音声の処理周りのタイミングなどがいまいち理解できていないので、検証をしていきます。
自分で動作を確認していくことも大事だね〜
今回は、以前の記事で曖昧にしていた音声処理関連の関数(prepareToPlay、getNextAudioBlock、releaseResources)の動作順序やタイミングを見ていきたいと思います。
こんな人の役に立つかも
・JUCEフレームワークに入門したい人
・JUCEで音声プログラミングを学びたい人
・JUCEのAudioチュートリアルを進めている人
VisualStudioでの文字列出力
VisualStudioのデバッグ出力で文字列を出力させて確認できるようにしてみました。
※今回はWindowsの場合のデバッグ出力です。
次のように、Windows.hを読み込みます。
#include <Windows.h>
プログラム中に次の「OutputDebugString」を記載することで、デバッグモードで動作させた際、「出力」ウィンドウに任意のタイミングで文字列を表示させることができます。
OutputDebugString("prepareToPlay");
出力の方法は、次のサイトを参考にさせていただきました。
音声処理の動作検証
次の3つの関数の中で、文字列を出力します。
void MainComponent::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
{
//[1]prepareToPlayが実行されたタイミング
OutputDebugString("\nprepareToPlay\n");
transportSource.prepareToPlay(samplesPerBlockExpected, sampleRate);
}
void MainComponent::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill)
{
if (readerSource.get() == nullptr)
{
//[2]getNextAudioBlockのreaderSourceがnullptrのタイミング
OutputDebugString("\nbufferClear\n");
bufferToFill.clearActiveBufferRegion();
return;
}
transportSource.getNextAudioBlock(bufferToFill);
//[3]transportSourceのgetNextAudioBlock関数が呼び出された後のタイミング
OutputDebugString("\ngetNextAudioBlock\n");
}
void MainComponent::releaseResources()
{
//[4]releaseResourcesが実行されたタイミング
OutputDebugString("\nrelease\n");
transportSource.releaseResources();
}
プログラムのように、[1]~[4]のタイミングに文字列を埋め込みました。
検証
検証した結果、次のような動作が確認できました。
アプリ起動時に「prepareToPlay」が呼び出されます。[1]
prepareToPlayでは、transportSpurceのprepareToPlayが呼び出されますが、この時点でまだ音声がよみこまれていない(readerSourceがnullptr)ので、音声自体を指し示すポインタはnullptrとなります。
その後、アプリ起動中は、getNextAudioBlock関数は繰り返し一定間隔で実行され続けます。この時に、readerSourceにはまだnullptrのため、先ほどのgetNextAudioBlock関数の条件に入ります。nullptrのときは、オーディオバッファに0を書き込んで出力します。そして、returnでgetNextAudioBlockは終了します。この流れが一定間隔でひたすら繰り返されます。[2]
openボタンで音声を読み込むと、readerSourceがnullptrではなくなるので、getNextAudioBlockの処理の流れも変わります。単純にtransportSourceのgetNextAudioBlock関数を呼び出すような流れに切り替わります。[3]
そして、アプリを終了(×でウィンドウを閉じる)すると、「releaseResource」が実行されていました。
やっぱり、実際に自分で検証してみないと具体的な動作イメージがつかめないですね