Pauseの機能を追加するだけで、プログラムの流れが複雑になりました・・・
流れをおって理解してみよう〜
Pauseボタンの機能を追加することで、playButtonを押した時の処理の流れが少し複雑に変化します。
今回のアプリは、ボタンを押す、という行為がトリガーとなって、音声のコントロールを行うので、それぞれ、ボタンを押した時に、アプリ自体のstate変数と、ボタンを押した後にどのような処理が走るのかをまとめてみました。言葉も記載しているのですが、主に、図をソースコードを追うためのご参考としていただければ幸いです。
公式のチュートリアルページはこちらです。
こんな人の役に立つかも
・JUCEフレームワークに入門したい人
・JUCEプログラミングでオーディオアプリを作成したい人
・JUCEで音声再生を行いたい人
5つの処理
処理の流れとしてボタンクリックのイベントを起点とすると、次の5つの処理の流れが存在しています。
結構凝った内容のプログラム構成となっていますので、プログラムの勉強にはちょうど良いと感じています。一方で、もう少し原始的な方法で、Pauseボタンを別で作成して、単純にボタンを有効化無効化するような方法のほうが初学者へのチュートリアルとしてはわかりやすいのかな、と思ったりもしました^^;
①Playボタンを押した時の処理の流れ
音声を読み込んだ後の「Play」というテキスト状態のplayButtonオブジェクトを押し下げた時の挙動です。
playButtonオブジェクトが「play」の時は、まずplayButtonClickedでchangeStateが呼ばれ、Startingという状態に変更になります。changeState内でtransportSourceがstartされてこれが音声ファイルを再生します。
これで、音声ファイルの再生状態が変化しますので、changeListenerCallbackが呼び出されます。
changeListenerCallback関数は、一つだけstateが条件になっておらず、今回は、その場合の条件に該当します。
if (transportSource.isPlaying())//←transportSourceの状態を条件にしています。
changeState (Playing);
else if ((state == Stopping) || (state == Playing))
changeState (Stopped);
else if (Pausing == state)
changeState (Paused);
このコールバック関数の中でchangeStateをPlayingに変更します。changeStateにPlayingを与えることでGUIの状態を変更します。
②Pauseボタンを押した時の処理の流れ
Pauseという名前はplayButtonオブジェクトのテキストがPauseなだけで、実際はplayButtonClicked関数が実行されます。
Pauseが押される時には、stateは必ずPlayingという状態のため、始まりはPlayingの状態になります。Playと同じ流れで、changeStateでtransportSourceがstopとなり、この時にコールバック関数changeListnerCallback関数が実行されます。この中でさらにchangeStateが実行されてplayButtonとstopButtonのGUIを変更します。
③Resume(再開)ボタンを押した時の処理の流れ
Resumeは再開という意味ですね〜、ちょっと普段使わないので、戸惑いました^^;
この機能の時は、Playの時と全く同じ流れで処理が流れるようになっています。
④Return to Zeroボタンを押した時の処理の流れ
一時停止を行った時のstopButtonオブジェクトの処理の流れになります。一時停止中のstopボタンは、音声の再生状態を停止して再生開始位置を0に戻すような処理を行います。
単純にchangeState関数で停止の処理を行うだけです。
⑤Stopボタンを押した時の処理
音声のPlay中に直接Stopボタンを押した場合も④と同様に、音声を停止して再生位置を0に戻すような処理を行います。
処理の流れの所感
今回のPause機能を追加するときの処理としては、changeStateが全てを司るようにプログラミングされているという点がポイントのような気がします。
実際、音声の再生状態が変更されるのはtransportSourceのstart()とstop()で、この時に実行されるのがchangeListenerCallback関数という仕組みがあります。ここに、transportSourceの再生位置を変更したり、GUIの変更を紐づけるためにstateという状態を持ち込んで、changeState関数でコントロールしている、というイメージです。