LoginSignup
56
18

More than 5 years have passed since last update.

Web MIDI APIを触ってみた

Last updated at Posted at 2016-12-04

gloops AdventCalender 5日目

gloops advent calender 5日目です:hand_splayed_tone2::sunglasses:
4日目@t_furuyaさんのはVisualStudioCodeでGo言語開発環境を作ってみたでした!

VSCodeいいですよね!何も入れなくてもmdとかも書けてお気に入りです
今日書いた記事のWeb MIDI APIもVSCodeでコーディングしました!

さて、今回のタイトルのWeb MIDI APIなんですが、名前は知ってはいたけど触ったことがなくちょうどいい機会だったので触ってみました
初歩的な部分ではありますがご覧あれ〜

MIDIとは

ちょっと調べてみると、MIDIはMusical Instrument Digital Interfaceの略のです。略を見てわかるように電子楽器をつなげる共通企画のようですね。

なるほど、じゃあWeb MIDI APIはWebで電子楽器をつなげて使うためのAPIか。

早速やろうと思ったが・・・

大変なことに気づきました。

MIDIデバイスなんて持ってないじゃん。。。

と焦ってぐぐったら出てきました

仮想MIDIキーボードです
https://github.com/mohayonao/virtual-midi-keyboard

Electronで作っているようですね!
詳しくは読んでないですが、使わせていただきますm(_ _)m

npm installしてstartしたらすぐにキーボードが起動してくれました

スクリーンショット 2016-12-04 21.17.24.png

使ってみよう

つなげる

まず、ブラウザとMIDIデバイスを接続してみましょう

app.js
(function () {
    // MIDIデバイス
    var midiDevices = {
        inputs: {},
        outputs: {}
    };
    // 成功したときの処理
    function requestSuccess(data) {
        console.log('success!!!', data);
    }
    // 失敗したときの処理
    function requestError(error) {
        console.error('error!!!', error);
    }
    // MIDIデバイスにアクセスする
    function requestMIDI() {
        if (navigator.requestMIDIAccess) {
            navigator.requestMIDIAccess().then(requestSuccess, requestError);
        } else {
            requestError();
        }
    }
    requestMIDI();
})();

requestMIDIでMIDIデバイスにアクセスしてます
navigator.requestMIDIAccessを呼ぶとPromise型で返ってくるので成功時と失敗時の処理を登録しておきましょ

一応非対応だった場合はrequestErrorを呼んでエラーにしちゃってます
ちなみに今のブラウザの対応状況はコチラ
この記事を書いてるときはChromeとOperaだけって感じですね
スクリーンショット 2016-12-04 14.34.01.png

デバイスからの入力を受け取る

受け取ったときのメソッドを用意しましょう

app.js
// Inputを受け取ったときのイベント
function inputEvent(e) {
    console.log('Input!!!', e);
}

成功したときの処理を変更します

app.js
// 成功したときの処理
function requestSuccess(data) {
    // Inputデバイスの配列を作成
    var inputIterator = data.inputs.values();
    for (var input = inputIterator.next(); !input.done; input = inputIterator.next()) {
        var value = input.value;
        // デバイス情報を保存
        midiDevices.inputs[value.name] = value;
        // イベント登録
        value.addEventListener('midimessage', inputEvent, false);
    }

    // Outputデバイスの配列を作成
    var outputIterator = data.outputs.values();
    for (var output = outputIterator.next(); !output.done; output = outputIterator.next()) {
        var value = output.value;
        // デバイス情報を保存
        midiDevices.outputs[value.name] = value;
    }
}

最初に用意しておいたmidiDevicesの中にデバイス情報を保存しておきましょう
そして、MIDIデバイスからinputがあったときのイベント登録をします

これで実行するして鍵盤を叩くとInputとログが出てきますね

データを処理しよう

最後に、inputEventを更新しましょう

app.js
// Inputを受け取ったときのイベント
function inputEvent(e) {
    var target = e.target;
    var device = midiDevices.outputs[target.name];
    var message = '';
    var numArray = [];
    // 2桁の16進数にして表示する
    event.data.forEach(function(val) {
        numArray.push(('00' + val.toString(16)).substr(-2));
    });
    message = numArray.join(' ');
    // InputしたDeviceに結果を送信する
    device.send(e.data);

    // 2桁の16進数を表示
    console.log(message);
}

dataの中に入ってるものは以下です

  • 1つ目 : ノートオン信号・チャンネル(n = チャンネル)
    • ノートオン時は9n
    • ノートオフ時は8n
  • 2つ目 : ノートナンバー(音の高さ)
  • 3つ目 : ベロシティ(鍵盤を離す速さ)

実際に出力されたログはこんな感じになります
スクリーンショット 2016-12-04 21.26.12 2.png

この共通化されたデータで電子楽器がどんな音をだすのかを判別してるんですね

これでサンプルは完成です!

終わりに

導入はかなり簡単でした
最近ではBlutoothを使ってのデータのやり取りもできるようです
これはかなり夢が広がりますね!
音楽だけでなく、いろいろなものにも使えそうなので今後はもっと深いところまで触りたいです

明日は@Ak_Suzukiさんです!

56
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
56
18