音声処理クラスでの音声処理準備
前回はVST3ホストでVST3プラグインから音声処理クラスを取得する方法について記載いたしました。
今回は取得した音声処理クラスで音声処理の準備を行うプログラムの説明を実施します。
今回作成するプラグインは下記のとおりです。
- VST3プラグインを読み込む
- VST3プラグインから音声処理クラスを作成する
- 音声処理クラスの情報(入出力数など)を取得する(new)
- 音声処理クラスで音声処理の準備を行う(new)
実際に音声処理を行う一歩手前までとなります。
このVST3プラグインのサンプルソースファイルはこちらからダウンロードできます→vst3host_20210410
ZIPファイルの中の「vst3host03_音声処理クラスでの音声処理準備」フォルダが今回のサンプルソースファイルになります。
なお、Visual Studioのプロジェクトは「コンソールアプリケーション」で作成しております。
プロジェクト設定などは「Visual Studioのプロジェクト設定」もご参照ください。
今回の説明内容
本ページでは、前回説明したVST3プラグインの利用の流れ(下記)のうち、4.についての内容を説明します。
なお、前回までで説明した内容については、説明を省略させていただきます。
- VST3プラグインのファイル(.vst3ファイル)をホストアプリケーションに組み込む(読み込む)
- VST3プラグインのファイル内にある音声処理クラスとパラメーター操作クラスの一覧を取得
- 音声処理クラスとパラメーター操作クラスの一覧から必要なクラスのインスタンスを作成
- 作成した音声処理クラスとパラメーター操作クラスのインスタンスを初期化
VST3ホストのソースコード
まず、ソースコードは下記となります。今回説明する点については、ハイライトしております。説明は後述します。
【main.cpp】
音声処理の準備について
VSTホストアプリケーションでは、PlugProviderクラスからIComponentクラスとIAudioProcessorクラスの取得が終わった後、下記の4つの内容を実施して音声処理の準備をします。
IComponentクラスとIAudioProcessorクラスの取得については前回の内容を確認してください。
- 音声入出力の確認
- イベント入出力の確認
- レイテンシ・ビット数などを確認
- 音声処理するためにセットアップ
上記の順番については特については特に決まりはありませんが、「4.」については音声処理の直前がいいと思われます。(明確な根拠はありません。)
音声入出力の確認
まず、音声入力の確認をしています。
音声入力の数、つまりオーディオ入力バスの数はIComponentクラスのgetBusCount()関数で取得します。
「オーディオバス」で「入力方向」のバスの情報を取得するので、getBusCount()関数にはkAudioとkInputを指定しています。
- getBusCount()関数
概要 | VST3プラグインのバスの数を取得する関数。 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
int32 | VST3プラグインのバスの数。 | ||
引数 | 型 | 変数名 | 概要 |
MediaType | type | 取得するバスの種類。kAudioとkEventが指定でき、kAudioはオーディオバス、kEventはイベントバスが取得できる。 (MediaTypeはlongの再定義) |
|
BusDirection | dir | 取得するバスの方向。kInputとkOutputが指定でき、kInputは入力バス、kOutputは出力バスが取得できる。 (BusDirectionはlongの再定義) |
続いて、オーディオ入力バスの数だけforループでバスの詳細な情報を取得しています。
オーディオ入力バスの詳細な情報はIComponentクラスのgetBusInfo()関数とIAudioProcessorクラスのgetBusArrangement()関数で取得しています。
VST3のバスについてなどもご確認ください。
- getBusInfo()関数
概要 | 指定したバスの情報を取得する関数。 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | バス情報の取得に成功したかどうかの結果。 取得に成功した場合…kResultTrue、取得に失敗した場合…kResultFalse |
||
引数 | 型 | 変数名 | 概要 |
MediaType | type | 取得するバスの種類。情報取得したいバスがオーディオバスのときはkAudio、イベントバスのときはkEventを指定する。 | |
BusDirection | dir | 取得するバスの方向。情報取得したいバスが入力のときはkInput、出力のときはkOutputを指定する。 | |
int32 | index | 取得するバスの番号。0~getBusCount()関数で取得した値の範囲で指定する。 | |
BusInfo& | bus | バス情報が格納されるBusInfo構造体への参照。 |
- getBusArrangement()関数
概要 | 指定したオーディオバスのスピーカー構成を取得する関数。 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | スピーカー構成の取得に成功したかどうかの結果 取得に成功した場合…kResultTrue、取得に失敗した場合…kResultFalse |
||
引数 | 型 | 変数名 | 概要 |
BusDirection | dir | 取得するバスの方向。情報取得したいバスが入力のときはkInput、出力のときはkOutputを指定する。 | |
int32 | index | 取得するバスの番号。0~getBusCount()関数で取得した値の範囲で指定する。 | |
SpeakerArrangement& | arr | スピーカー構成が格納されるSpeakerArrangement型変数への参照。(SpeakerArrangementはunsigned __int64の再定義) |
【main.cpp】
つぎに音声出力の確認をします。内容は音声入力とほぼ同様なので詳細は割愛いたします。
【main.cpp】
イベント入出力の確認
次にイベント入出力の確認をしています。
ここも基本的には音声入出力の確認と変わりません。
イベントバス数をIComponentクラスのgetBusCount()関数で取得し、イベントバスの数だけforループでイベントバスの詳細な情報を取得しています。
イベントバスの詳細な情報はIComponentクラスのgetBusInfo()関数で取得しています。(スピーカー構成はないのでgetBusArrangement()関数は使いません)
【main.cpp】
レイテンシ・ビット数などの確認
次にVST3プラグインが処理できる音声入出力のビット数とVST3プラグインのレイテンシとテイルサンプルを確認をしています。
処理できる音声入出力のビット数はIAudioProcessorクラスのcanProcessSampleSize()関数を使うことで確認できます。
- canProcessSampleSize()関数
概要 | VST3プラグインが処理できる音声入出力のビット数を確認するための関数。 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | 指定したビット数に対応しているかどうかの結果 対応している場合…kResultTrue、対応していない場合…kResultFalse |
||
引数 | 型 | 変数名 | 概要 |
int32 | symbolicSampleSize | ビット数の指定。32bit浮動小数点(float型)に対応しているか確認する場合はkSample32、64bit浮動小数点(double型)に対応しているか確認する場合はkSample64を指定する |
プラグインのレイテンシはIAudioProcessorクラスのgetLatencySamples()関数を使うことで確認できます。
また、テイルサンプルはIAudioProcessorクラスのgetTailSamples()関数で確認できます。ここでは詳細は割愛いたします。
【main.cpp】
音声処理のためのセットアップ
セットアップの前にVST3プラグインを非アクティブにします。必ず後述するIAudioProcessorクラスのsetupProcessing()関数の前には非アクティブにしてください。
非アクティブにするには、IAudioProcessorクラスのsetProcessing()関数とIComponentクラスのsetActive()関数の引数にfalseを指定してを呼び出します。
setProcessing()関数とsetActive()関数の詳細は割愛いたします。
【main.cpp】
次にIAudioProcessorクラスのsetupProcessing()関数を使用してVST3プラグインをセットアップします。
VST3プラグインにこれから処理で使用するサンプリングレートやブロックサイズ、ビット数などを指定して通知します
なお、VST3プラグインが対応しているサンプリングレート・ブロックサイズは事前に取得できないので、VSTホスト側でサンプリングレート・ブロックサイズを適当に設定して、setupProcessing()関数が成功するパターンを探す必要があります。
(「まずサンプリングレート96,000Hz、ブロックサイズは32で試して、無理なら次はサンプリングレート48,000Hzブロックサイズは32で試して…」というように成功するパターンを探す必要があります。)
筆者の感覚ですが、サンプリングレートは44,100Hz・48,000Hz・96,000Hzのいずれかでブロックサイズは32~2048ぐらいであれば多くのVST3プラグインが対応しているようです。
- setupProcessing()関数
概要 | VST3プラグインにこれから処理で使用するサンプリングレートやブロックサイズ、ビット数などを指定してセットアップするための関数。 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | VST3プラグインがセットアップに成功したかどうかの結果 セットアップに成功した場合…kResultOk、セットアップに失敗した場合…kResultFalse |
||
引数 | 型 | 変数名 | 概要 |
ProcessSetup& | setup | VST3プラグインのセットアップのための情報を格納したProcessSetup構造体への参照。 |
- ProcessSetup構造体
型 | 変数名 | 概要 |
---|---|---|
int32 | processMode | これから行われる音声処理のモード。kRealtime、kPrefetch、kOfflineが指定できる。基本的にkRealtimeでいいはず。(詳細不明) |
int32 | symbolicSampleSize | これから行われる音声処理のビット数。kSample32(32bit浮動小数点…float型)とkSample64(64bit浮動小数点…double型)が指定できる |
int32 | maxSamplesPerBlock | これから行われる音声処理の最大ブロックサイズ。(音声バッファの最大サイズ) |
SampleRate | sampleRate | これから行われる音声処理のサンプリングレート。 |
【main.cpp】
セットアップが終われば、VST3プラグインをアクティブにします。
非アクティブのときとは逆にIComponentクラスのsetActive()関数とIAudioProcessorクラスのsetProcessing()関数の引数にtrueを指定してを呼び出します。
なお、アクティブにするときはsetActive()関数→setProcessing()関数の順に呼び出し、非アクティブにするときはsetProcessing()関数→setActive()関数の順に呼び出す必要があります。
【main.cpp】
この後、VST3プラグインに音声データやMIDIデータ、パラメーターの変更情報を与えて音声処理を実施します。
今回 説明が多くなり過ぎるため、次回 説明いたします。
終了処理
最後に終了処理を行います。
終了処理では、アクティブにしたVST3プラグインを非アクティブにします。
その後は前回説明した通り、IAudioProcessorクラスのrelease()関数とplugProviderクラスのreleasePlugIn()関数の呼び出しを行います。
【main.cpp】
実行結果サンプル
上記のコードを実行すると下記のような表示となります。読み込んだVST3プラグインは私の作成した「Tempo Sync Filter」となります。
最後に
ここまででようやく音声処理クラスのセットアップが完了となり、実際に音声処理を行うことができるようになります。
次回は、作成した音声処理クラスで実際に音声処理を行うところを説明いたします。
次回→(作成中)
VST3プラグイン作りの情報はこちらにもございます → はじめてのVST3プラグイン作り
ご指摘やご質問などがございましたら、コメント欄か掲示板、Twitterでご連絡いただければと思います。
■掲示板
■Twitterアカウント:@vstcpp URL:https://twitter.com/vstcpp
更新お疲れ様です、うつぼかずらさんの記事を全部拝見しました、それを見ながらプラグインとホストを作っています。
今回の内容について一つ質問があります、ホストがプラグインをセットアップ&アクティブ処理をしないと何かまずいことがありますか、つまりセットアップとアクティブは必須動作ですか?(僕は一番簡単なプラグインとホストを作りましたがセットアップとアクティブ処理はしていないけどプラグインとのやり取りは特に問題なく普通に処理できるから疑問が出てきました)。
他の資料に”プラグインをリアルタイム処理可能な状態にするためには、setprocessingとsetupProcessを呼ぶ”を書いた、僕今回作ったホストはWAVファイルのデータを一気に読み込んでプラグインに渡して、プラグインが処理した後に、一気にホストに返す、再生するの仕様ですから、リアルタイム処理ではないからセットアップ処理がしなくても大丈夫、ということですか?
VST3の規格を見た限り、setActive()・setProcessing()・setupProcessing()は必須だと思われます。
この記事はVST3 SDKの「Workflow Diagrams」をもとに書いていますが、上記の関数の処理によりVST3プラグインは初期状態から処理可能な状態に変わっていく形となります。
上記の関数を呼び出さない場合、リアルタイム処理かどうかにかかわらず、VST3プラグインが正常に動作しない可能性があります。
今回はたまたまVST3プラグインが動いただけと考えるほうがよいと思います。
返信ありがとうございます、そうですね、とりあえず規格通り設定するのは正しい操作ですから、追加するべきです。
SDK3.7.1についたサンプルプラグイン「hostchecker.vst3」のソースから見ると、setActive(true)はsetProcessing(true)の次にやると、Errorと判断されます。そうみると、先にsetActive(true)を実行したほうがいいです。(この順番より何かが違うが全然わかりませんですけど)
ご指摘ありがとうございます。
確かに順番的にsetActive(true)→setProcessing(true)ですね。(falseを指定するときは逆順。)
ドキュメントを見る限りでは下記のような違いがあるようです。
・setActive()…プラグインのメモリの確保・初期化などを行う。音声スレッドでは呼び出さない。
・setProcesssing()…プラグインの初期化を行う。音声スレッドでも呼び出してよい。
回答ありがとうございます。
なるほどね、こうみると、setActive(true)は先にやったほうがいいですね。
ちなみに、hostchecker.vst3はホストをチェックするプラグインと思いますが、どう使いますか?エラーとワーニングがあれば直すか?評点に何か意味がありますか?ご存じでしょうか
hostcheckerはほとんど使ったことがないのでよくわからないです。