EternalWindows
MIDI / MIDIイベント

今回は、MIDIイベントの取得について説明します。 MIDIイベントのステータスバイトは、0x8n〜0xEnまでのいずれかであり、 それぞれ次のような特徴があります。

イベント名 ステータスバイト データバイトの数 効果
ノートオフ 0x8n 2 消音
ノートオン 0x9n 2 発音
ポリフォニック・キー・プレッシャ 0xAn 2 アフタータッチ
コントロールチェンジ 0xBn 2 第一データバイトによって様々
プログラムチェンジ 0xCn 1 音色の切り替え
チャンネルプレッシャ 0xDn 1 アフタータッチ
ピッチベンド・チェンジ 0xEn 2 音程(ピッチ)のシフト

上記表のノートオフやピッチベンドなどの言葉や効果は、無理に覚える必要はありません。 重要なのは、これらのイベントをメッセージとしてMIDIデバイスに送信するという点です。 デバイスに送信すれば、デバイスがメッセージに応じた処理を行ってくれますから、 アプリケーションがイベント(メッセージ)の詳細を知っておく必要はありません。 ただし、イベントによってデータバイトの数が違うという点は重要です。 データバイトはステータスバイトの後に格納され、イベント固有の値が格納されます。 メッセージとして送信する際は、ステータスバイトとデータバイトを組み合わせることになります。

0x8nなどのnの部分には、チャンネルが格納されます。 チャンネルは全部で16種類あり、nには0からfまでの値を格納することができます。 チャンネルとはいわば演奏パートであり、1つのイベントは1つのチャンネルに対して有効です。 たとえば、0x90はチャンネル0に対する発音のイベントであり、 これによりチャンネル0から音が鳴ることになります。 また、0x91ならばチャンネル1から音が鳴ることになります。 その後、0x80を送信した場合、チャンネル0から鳴っている音が消音されますが、 チャンネル1の音は依然として鳴っています。 基本的にMIDIでは、1つのチャンネルから1つの楽器を使った音を鳴らすため、 特定のチャンネルの音が消音された場合は、 特定の楽器の音が聴こえなくたったように感じることになります。

MIDIイベントのデータバイトを取得するのは、ReadTrackの次の部分です。

switch (lpEvent->state & 0xF0) { // ステータスバイトを基にどのイベントか判別

case 0x80:
case 0x90:
case 0xA0:
case 0xB0:
case 0xE0:
	mmioRead(hmmio, (HPSTR)&lpEvent->data1, sizeof(BYTE));
	mmioRead(hmmio, (HPSTR)&lpEvent->data2, sizeof(BYTE));
	break;
case 0xC0:
case 0xD0:
	mmioRead(hmmio, (HPSTR)&lpEvent->data1, sizeof(BYTE));
	lpEvent->data2 = 0;
	break;

lpEvent->state & 0xF0とすることにより、チャンネルの部分が0になります。 これにより、lpEvent->stateが0x97や0x9Fなどであっても、0x90に収束されるため、 case 0x97などの記述は不要になります。 0xC0と0xD0以外のステータスバイトの場合は、データバイトが2つ格納されているのでそれを読み取り、 0xC0か0xD0の場合はデータバイトを1つ読み取ります。 この場合、2つ目のデータバイトは使用されないので0を指定しています。


戻る