カテゴリー別アーカイブ: Web MIDI API

Web MIDI API MIDIメッセージの受信

MIDIデバイスからのMIDIメッセージを受信するには, MIDIInputインスタンスのonmidimessageイベントハンドラを定義します.

onmidimessageイベントハンドラには,MIDIMessageEventイベントオブジェクトが引数に渡されます.

MIDIMessageEventイベントオブジェクトには,Number型のreceivedTimeプロパティとサイズが3のUint8Arrayのdataプロパティが定義されています.

そして, MIDIメッセージはこのUint8Arrayのdataプロパティに格納されています. MIDIメッセージの詳細はこちらを参照してください.

インデックス0のデータは,  音を鳴らす (9nH ノートオン) or 止める (8nH ノートオフ) メッセージが格納されています.

サンプルコードでは, この値 (のマスク値) で分岐して, noteOn関数かnoteOff関数のどちらを呼び出すかを決定しています.

インデックス1のデータは,ピッチ (音の高さ) を表すメッセージとなります (ノートナンバーと呼ばれます). 最も低い音が0, 最も高い音が127となります. また, ピアノ88鍵に対応するノートナンバーは, 22 〜 109となります.

サンプルコードでは, この値をWeb Audio APIのOscillatorNodeに反映させています.

インデックス2のデータは, 音の強弱を表すメッセージとなります (ベロシティと呼ばれます). 1 〜 127までの値をとり, 127が最も強い音となります.

サンプルコードでは, この値をWeb Audio APIのGainNodeに反映させています.

Web MIDI API MIDIPort (MIDIInput / MIDIOutput) インスタンスを取得する

MIDIPort (MIDIInput / MIDIOutput) インスタンスとは, 簡単に表現すれば, 入出力となるMIDIデバイスを抽象化したオブジェクトのことです.

厳密には, MIDIPortクラスのサブクラスとして, MIDIInputクラス / MIDIOutputクラスが定義されています.

MIDIPort (のサブクラスのインスタンス) がMIDIデバイスとMIDI信号の送受信処理をするので, MIDIAccessインスタンスからMIDIPort (のサブクラスの) インスタンスを取得します.

navigator.requestMIDIAccess({sysex : true}).then(function(midiAccess) {
    var inputs  = [];
    var outputs = [];

    console.dir(midiAccess);

    if (typeof midiAccess === 'function') {
        // Legacy Chrome
        inputs  = midiAccess.inputs();
        outputs = midiAccess.outputs();
    } else {
        // Chrome 39 and later
        console.dir(midiAccess.inputs);
        console.dir(midiAccess.outputs);

        var inputIterator  = midiAccess.inputs.values();   // MIDIInputMap  -> Iterator
        var outputIterator = midiAccess.outputs.values();  // MIDIOutputMap -> Iterator

        console.dir(inputIterator);
        console.dir(outputIterator);

        // Iteration
        for (var i = inputIterator.next(); !i.done; i = inputIterator.next()) {
            inputs.push(i.value);
        }

        for (var o = outputIterator.next(); !o.done; o = outputIterator.next()) {
            outputs.push(o.value);
            }
        }

        console.dir(inputs);
        console.dir(outputs);
}, function(error) {
       console.dir(error);
});

レガシーなChromeでは, MIDIPortインスタンスの取得が異なり, MIDIAccessインスタンスのinputsメソッド / outputsメソッドを呼び出すだけです.

Chrome 39以上のバージョンでは,  MIDIInputMapインスタンス / MIDIOutputMapインスタンスにアクセスする必要があります.

そのために, MIDIAccessインスタンスのinputsプロパティ / outputsプロパティにアクセスします.

そして, valuesメソッドを呼び出すことで, 入出力のMIDIデバイスを抽象化したオブジェクトの集合, つまり, MIDIPortインスタンスの集合であるIteratorオブジェクトを取得できます.

あとは, イテレーションして各要素を抽出し, 配列に格納しておくだけです.

Web MIDI API MIDIAccessインスタンスを取得する

まず前提として, Web MIDI APIを利用するためにはMac版ChromeのWeb MIDI APIを有効にする必要があります.

  1. アドレスバーに chrome://flags を入力する
  2. Web MIDI APIを有効にして, Chromeを再起動します.
Chrome Web MIDI API設定
Chrome Web MIDI API設定

Web MIDI APIを利用するための最初のステップは, Web MIDI APIのほとんどの処理の起点となる, MIDIAccessインスタンスを取得することです.

そのために, navigatorオブジェクトのrequestMIDIAccessメソッドを呼び出します.

requestMIDIAccessメソッドはPromiseオブジェクトを返すので, 後続関数となるthenの第1引数にリクエストが成功した場合の処理を, 第2引数にリクエストが失敗した場合の処理を記述します.

navigator.requestMIDIAccess({sysex : true}).then(function(midiAccess) {
    // 第1引数は, MIDIAccessインスタンス
    console.dir(midiAccess);
}, function(error) {
    // 第1引数は, DOMErrorインスタンス (リクエストがユーザーによりブロックされた場合など)
    console.dir(error);
});

以上の設定 & コードでWeb MIDI APIを利用するための最初のステップが完了です.