※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

トップページ


MIDIメッセージをprocessReplacing()関数中で処理する方法

前項でprocessEvents()関数によってホストアプリケーションから受け取ったMIDIメッセージをprocessReplacing()関数で処理する方法を記載する。

サンプルコード


サンプルコードではロードするとノイズを生成、出力するVSTとなっている。
MIDIのコントロールチェンジメッセージ 7番(ボリュームコントロール)によって出力されるノイズのボリュームを調整している。
  1. void MyMidiSampleVST::processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames)
  2. {
  3. //入力、出力は2次元配列で渡される。
  4. //入力は-1.0f~1.0fの間で渡される。
  5. //出力は-1.0f~1.0fの間で書き込む必要がある。
  6. //sampleFramesが処理するバッファのサイズ
  7. float* outL = outputs[0]; //出力 左用
  8. float* outR = outputs[1]; //出力 右用
  9.  
  10. // midieventlistの読み込み位置
  11. int midimsg_cursol = 0;
  12.  
  13. for (int i = 0; i < sampleFrames; i++)
  14. {
  15. //ここで音声処理を行う。
  16.  
  17. // MIDIメッセージがあるか確認
  18. if ( midimsgnum > 0)
  19. {
  20. // MIDIメッセージを処理するタイミングかどうかを確認する。
  21. if( midimsgbuf[midimsg_cursol].deltaFrames <= i)
  22. {
  23. // MIDIメッセージがコントロールチェンジのボリューム変更(CC7)であった場合
  24. if( midimsgbuf[midimsg_cursol].message == 0xB0
  25. && midimsgbuf[midimsg_cursol].data1 == 7)
  26. {
  27. volume = (float)( midimsgbuf[midimsg_cursol].data2) / 127.0f;
  28. }
  29.  
  30. // midimsgbufからMIDIメッセージを読み出したので
  31. // 読み込み位置を進め、MIDIメッセージの数を減らす
  32. midimsgnum--;
  33. midimsg_cursol++;
  34. }
  35. }
  36.  
  37. //出力バッファへ書き込む。
  38. outL[i] = volume * (float)((rand() % 256) -128) / 255.0f;
  39. outR[i] = volume * (float)((rand() % 256) -128) / 255.0f;
  40. }
  41. }

サンプルコードの解説

まず、MIDIメッセージを保存したバッファ(midimsgbuf)の読み込み位置を初期化とノイズのボリュームの初期化を行っている。(6~10行目)
// midieventlistの読み込み位置
int midimsg_cursol = 0;
 
// ノイズのボリューム
static float volume = 1.0f;

次に音声処理を行うfor文の中でMIDIメッセージがあるか確認し、ある場合はMIDIメッセージを処理するタイミングかどうかを確認している。(17~34行目)
// MIDIメッセージがあるか確認
if ( midimsgnum > 0)
{
	// MIDIメッセージを処理するタイミングかどうかを確認する。
	if( midimsgbuf[midimsg_cursol].deltaFrames <= i)
	{
		:
		:
	}
} 

MIDIメッセージを処理するタイミングであった場合、通常はMIDIメッセージにあわせて以下のような処理を行う
  • キーのオン、オフ処理
  • ピッチベンドの処理
  • コントロールチェンジ処理

今回はMIDIメッセージがコントロールチェンジのボリューム変更(7番)のみを処理し、ノイズのボリュームを変更する処理となっている。(22~27行目)
// MIDIメッセージがコントロールチェンジのボリューム変更(CC7)であった場合
if( midimsgbuf[midimsg_cursol].message == 0xB0
	&& midimsgbuf[midimsg_cursol].data1 == 7)
{
	volume = (float)( midimsgbuf[midimsg_cursol].data2) / 127.0f;
} 

MIDIメッセージを処理した場合、MIDIメッセージの数をしめすmidimsgnumを1減らし、同時にmidimsgbufの読み込み位置を1進める(31~32行目)
// midimsgbufからMIDIメッセージを読み出したので
// 読み込み位置を進め、MIDIメッセージの数を減らす
midimsgnum--;
midimsg_cursol++; 

最後にノイズの生成と音声信号出力バッファへの書き込みを行っている。(37~38行目)
outL[i] = volume * (float)((rand() % 256) -128) / 255.0f;
outR[i] = volume * (float)((rand() % 256) -128) / 255.0f;





同一カテゴリのTips


項目 No. 概要
MIDIメッセージ処理 No.1 MIDIメッセージ処理で最小構成の自作VSTに追加する変数・関数
No.2 VSTの初期化とMIDIメッセージ処理関連の変数の初期化
No.3 ホストアプリケーションからMIDIメッセージを受け取る方法
No.4 MIDIメッセージをprocessReplacing()関数中で処理する方法
No.5 MIDIメッセージ処理で作成したVSTのサンプルソースコード全体(暫定版)


javascript plugin Error : このプラグインで利用できない命令または文字列が入っています。