オーディオプラグインの作成、パート2

シリーズのすべての投稿:

パート1.紹介とセットアップ

パート2.コードの学習

パート3. VSTおよびAU

パート4.デジタル歪み

パート5.プリセットとGUI

パート6.信号合成

パート7. MIDIメッセージの受信

パート8.仮想キーボード

パート9.封筒

パート10. GUIの改善

パート11.フィルター

パート12.低周波発振器

パート13.再設計

パート14.ポリフォニー1

パート15.ポリフォニー2

パート16.アンチエイリアス






テストプロジェクトを詳しく見てみましょう。 最も重要なファイルはresource.hMyFirstPlugin.hおよびMyFirstPlugin.cppです。 現時点では、プラグインはシンプルなボリュームコントロールです。





学習コード





定数、フラグ、画像ソース





ナビゲーターでresource.hを開きます。 このファイルには、プラグインの名前、バージョン、一意のID、GUIの画像ソースへのリンクなどの定数が含まれています。 行23〜26では、一意のIDを指定できます。



// 4 chars, single quotes. At least one capital letter #define PLUG_UNIQUE_ID 'Ipef' // make sure this is not the same as BUNDLE_MFR #define PLUG_MFR_ID 'Acme'
      
      







IDは、プラグインの一般的なカタログ化にとって重要です。 ここで登録できます 。 56行目以降は、プラグインの起動時に表示されるボリュームノブのIDとイメージへのパスをさらに決定します。



 // Unique IDs for each image resource. #define KNOB_ID 101 // Image resource locations for this plug. #define KNOB_FN "resources/img/knob.png"
      
      







ナビゲータで検索し、 リソース→img→knob.pngを開きます。 これは、サイズが48 x 48ピクセルの60の異なるペン位置を持つスプライトです。 プラグインを起動してノブを回しても、ハンドルの画像は回転しません。 プログラムは、このスプライトの対応する部分のみを表示します。

なぜ回転しないのですか? ペンにいくつかのノッチがあり、影を落としていると想像してください。 次に、回転中に影も回転します。 あなたが知っているように、これは実際には起こりません。



以下のresource.hで、プラグインウィンドウのサイズを設定できます。



 #define GUI_WIDTH 300 #define GUI_HEIGHT 300
      
      







値をいじってプラグインを実行します。



プラグインクラスインターフェイス





MyFirstPlugin.hを開きます 。 プラグインクラスのインターフェイスが含まれています。 public



部分には、コンストラクタ、デストラクタ、およびクラスの3つのメンバー関数が含まれます。







private



部分には、現在のボリューム値を格納するdouble



変数のみがあります。



実装





興味深い部分に進みます! MyFirstPlugin.cppを開きます 。 すぐに、 enum



タイプの興味深いレシーバーが表示されます。



 enum EParams { kGain = 0, kNumParams };
      
      







kGain = 0



設定し、その後にkNumParams



を置くと、 kNumParams



はプラグインパラメーターの数になります(この場合は1)。

次のenum



は、 resource.hで説明されている定数を使用し、プラグインウィンドウでハンドル座標を設定します。



 enum ELayout { kWidth = GUI_WIDTH, kHeight = GUI_HEIGHT, kGainX = 100, kGainY = 100, kKnobFrames = 60 };
      
      







また、 knob.pngのフレーム数を60に設定します。

次に、コンストラクターの実装が開始されます。 プラグインの属性が設定されます:



 //arguments are: name, defaultVal, minVal, maxVal, step, label GetParam(kGain)->InitDouble("Gain", 50., 0., 100.0, 0.01, "%");
      
      







これまでのGUIでは、値もパーセント記号も表示されませんが、値は0



から100



まで変化できます。 デフォルト値は50



です。 値のグラデーションが円上で均一ではないことに気付くかもしれません。 これはSetShape(2.)



です。 これをSetShape(1.)



に置き換えると、値の分布は線形になります。 非線形動作を定義するのはSetShape



です。

次に、デザイナーは目的のサイズのグラフィックコンテキストを作成し、背景の赤色を設定します。



 IGraphics* pGraphics = MakeGraphics(this, kWidth, kHeight); pGraphics->AttachPanelBackground(&COLOR_RED);
      
      







その後、 knob.pngがロードされ、画像を含む新しいIKnobMultiControlが作成され、GUIにアタッチされます。 IKnobMultiControl



は、インターフェイスハンドルのクラスです。

スプライト内のフレーム数を示すためにkKnobFramesパラメーターがどのように渡されるかに注意してください。



 IBitmap knob = pGraphics->LoadIBitmap(KNOB_ID, KNOB_FN, kKnobFrames); pGraphics->AttachControl(new IKnobMultiControl(this, kGainX, kGainY, kGain, &knob));
      
      







最後に、デザイナーはグラフィックスコンテキストをバインドし、プラグインのデフォルトプリセットを作成します。



 MakeDefaultPreset((char *) "-", kNumPrograms);
      
      







OnParamChange



見てOnParamChange



(ファイルの最後)。 IMutexLock



は、後で説明する概念であるストリーミングセキュリティを提供します。 それ以外は、変更するパラメーターに応じたオプションのセットです。



 case kGain: mGain = GetParam(kGain)->Value() / 100.; break;
      
      







覚えているように、 kGain



は0から100に変化します。したがって、値を100で除算した後、0から1の値をmGain



クラスのメンバーにmGain



ます。



そこで、GUIを作成し、 mGain



などのパラメーターmGain



バインドするプロセスを少し見てみました。 プラグインが着信オーディオを処理する方法を見てみましょう。 この場合、オーディオストリームはdouble



データ型で表されるサンプルのシーケンスであり、各サンプルには特定の時点での信号振幅が含まれています。

ProcessDoubleReplacing



関数に渡される最初のパラメーターはdouble** inputs



です。 double*



を使用して、 double*



シーケンスを渡すことができます。 ただし、プラグインは2つのチャネル(ステレオ)またはそれ以上を処理するため、サンプルのシーケンスをいくつか必要とし、これをdouble**



と通信します。 関数の最初の2行はこれを示しています。



 double* in1 = inputs[0]; double* in2 = inputs[1];
      
      







in1



はサンプルの最初のシーケンス(左チャネル)を示し、 in2



は右チャネルのサンプルを示します。 出力バッファーに対して同様のアクションを実行した後、入力バッファーと出力バッファーの要素を反復処理できます。



 for (int s = 0; s < nFrames; ++s, ++in1, ++in2, ++out1, ++out2) { *out1 = *in1 * mGain; *out2 = *in2 * mGain; }
      
      







サンプルごとに、入力値を取得し、 mGain



を乗算して出力バッファーに書き込みます。 nFrames



は、チャネルごとに使用可能なサンプル数を示しているため、バッファの長さがわかります。

プラグインをスタンドアロンアプリケーションとして実行すると、コンピューターにマイクが内蔵されている場合、スピーカーから自分の声が聞こえることに気づいたかもしれません。 これは、アプリケーションがデフォルトでこのマイクを入力ソースとして使用するためです。 これ(および他の何か)を変更するには、 設定に移動します











Reset



機能でブレークポイントを設定します。 右側のサンプリングレートを変更し、変更を適用します。 デバッガーは、 Reset



機能でコードの実行を中断します。 lldb



機能する右下で、 print GetSampleRate()



と入力しprint GetSampleRate()











デバッガから任意の関数を呼び出して、正しい値を確認することもできます。 表示されたら左上の[ 停止]をクリックして続行することにします。

次に、コードからプラグインを作成し、ホストにアップロードします。 これは次の投稿のトピックになります。

それまでの間、



追加の読書





いくつかのギャップを埋めるために、本発明のオリ・ラーキン氏によるこれらのスライドを読むことを強くお勧めします。 WDL-OLに関する重要な説明の一部が含まれています。



元の記事:

martin-finke.de/blog/articles/audio-plugins-003-examining-the-code



All Articles