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

トップページ


MIDIメッセージを処理するVSTについて2

MIDIメッセージ処理 No1No5で作成したVSTのMIDI処理については、どんなVSTでもほぼ共通の処理となる。
コードを再利用しやすいように、ここではシステムエクスクルーシブを除くMIDIメッセージに関する処理をクラスとしてひとまとめにする。

MIDIメッセージを処理するクラスは自作VSTクラスで下記のように継承できるように作成する。
  1. class MyMidiSampleVST2 : public AudioEffectX , public CMidiMsg // CMidiMsgが今回作成するクラス
  2. {
  3. // 以下省略
  4. };

ここで作成するVSTサンプルのソースコード全体はここにある。

MIDIメッセージ処理用クラス定義

MIDIメッセージ処理用クラスは以下のように定義する。(全体は長いので一部省略している。全体はここにある。)

  1. class CMidiMsg
  2. {
  3. protected:
  4. int cur; //読み込み中のMIDIの位置
  5. int num; //受け取ったMIDIメッセージの数
  6. MidiMessage buf[MIDIMSG_MAXNUM]; //受け取ったMIDIメッセージを保管するバッファ
  7. public:
  8. CMidiMsg(void);
  9. ~CMidiMsg(void);
  10.  
  11. // バッファのクリア等を行う。
  12. virtual void clearMidiMsg();
  13.  
  14. // MIDIメッセージをバッファに追加する
  15. // バッファへの追加が成功すると1、失敗すると0を返す
  16. virtual int addMidiMsg(VstMidiEvent *midievent);
  17. virtual int addMidiMsg(MidiMessage msg);
  18.  
  19. // バッファからMIDIメッセージを取り出す
  20. virtual MidiMessage getMidiMsg();
  21.  
  22. // バッファ中にあるMIDIメッセージの数を返す
  23. virtual VstInt32 getMidiMessageNum();
  24.  
  25. // バッファから最初に取り出せるMIDIメッセージのDeltaFramesを返す
  26. virtual VstInt32 getNextDeltaFrames();
  27.  
  28. // MIDIメッセージが何かを判断し、そのメッセージに対応した
  29. // onMidiKeyOn()関数、onMidiControlChange()関数等を呼び出す。
  30. // 引数なしの場合、内部でgetMidiMsg()が使用されるので注意。
  31. virtual void midiProc(MidiMessage mididata);
  32. virtual void midiProc() { MidiMessage mididata = getMidiMsg(); midiProc(mididata); };
  33.  
  34. // midiProc()関数から呼び出される。
  35. // それぞれのMIDIメッセージに応じて処理を行う
  36. // 以下6つはオーバーライドして使う
  37. virtual void onMidiKeyOn (unsigned char channel, unsigned char noteNo, unsigned char velo) {}; // 関数の中身は空
  38. virtual void onMidiKeyOff (unsigned char channel, unsigned char noteNo, unsigned char velo) {}; // 関数の中身は空
  39. // 長いので省略
  40. };

解説

まず、MIDIメッセージのや書き込みのためのバッファと読み出し位置や書き込み位置の変数を定義している。
これらは他のクラスから読み込まれることはないのでprotectedで宣言している。
protected:
	int          cur;                 //読み込み中のMIDIの位置
	int          num;                 //受け取ったMIDIメッセージの数
	MidiMessage  buf[MIDIMSG_MAXNUM]; //受け取ったMIDIメッセージを保管するバッファ
 

次に以下2つの操作を行うための関数を定義している
  • ホストアプリケーションからのMIDIメッセージの受け取る際に使用する関数(processEvents()関数内で呼び出される関数)
メンバ関数 戻り値 引数 内容
clearMidiMsg() なし なし MIDIメッセージを受け取るMIDIバッファを初期化する関数。
addMidiMsg() int VstMidiEvent *midievent MIDIメッセージをMIDIバッファへの保存する関数。
引数は受け取るMIDIメッセージ(VstMidiEvent型のポインタ)
MIDIバッファへの追加に成功すると1、失敗すると0が返る。

メンバ関数 戻り値 引数 内容
getMidiMessageNum() VstInt32 なし MIDIメッセージ有無のチェックに利用する関数。
戻り値はMIDIバッファにあるMIDIメッセージの数。
getNextDeltaFrames() VstInt32 なし processReplacing()関数内で次のMIDIメッセージを処理するタイミングを返す関数。
戻り値は処理すべきフレーム(0~sampleFramesの範囲の値)
getMidiMsg() MidiMessage MIDIバッファからのMIDIメッセージの取り出す関数。
戻り値はMIDIメッセージ構造体
midiProc()関数 なし MidiMessage mididata 引数のMIDIメッセージに応じて処理を実施する。
引数は処理するMIDIメッセージ

midiProc()関数では各MIDIメッセージ(KeyOn、KeyOff、ControlChange等)を処理するメンバ関数を呼び出す。
これらの関数(onMidiKeyOn()関数、onMidiKeyOff()関数 等)についても、定義している。
  • midiProc()関数から呼び出されるメンバ関数
メンバ関数 戻り値 引数 内容
onMidiKeyOn() なし MIDIメッセージがKeyOnの際に呼び出される。
onMidiKeyOff() なし MIDIメッセージがKeyOffの際に呼び出される。
onMidiProgramChange() なし MIDIメッセージがプログラムチェンジの際に呼び出される。
onMidiPoliKeyPress() なし MIDIメッセージがポリフォニックキープレッシャーの際に呼び出される。
onMidiChannelPress() なし MIDIメッセージがチャンネルプレッシャーの際に呼び出される。
onMidiPitchBend() なし MIDIメッセージがピッチベンドチェンジの際に呼び出される。
onMidiSystemMessage() なし MIDIメッセージがシステムコモンメッセージ、システムリアルタイムメッセージの際に呼び出される。
システムメッセージに応じてさらにonMidiQuarterFrame()関数、onMidiSongPointer()関数などが呼び出される
onMidiControlChange() なし MIDIメッセージがコントロールチェンジの際に呼び出される。コントロールチェンジメッセージに応じてさらにonMidiCC000()~onMidiCC127()の関数が呼び出される。






同一カテゴリのTips


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