ブラウザとMIDIデバイスをHTMLタグで接続する

  • 5
    いいね
  • 0
    コメント

この記事は WebAudio Web MIDI API Advent Calendar 2016 の17日目です。

今回の目的はズバリこれ。

「ブラウザとMIDIデバイスを簡単につなげる」

Chrome 43からChromeををインストールしたら設定無しでWeb MIDI APIが利用できるようになりました。2015年6月くらいの出来事です。(DTM Stationの記事
個人的にはこの時点でたくさんのWeb MIDI APIを使ったアプリを書いていたのですが、毎回「あれっ?これ書かなかったっけ?」というデジャブがいつもありました😅 お陰で覚えてしまった訳ですが「もっと簡単になるようにどうにかしたい」という気持ちが抑えきれずにいろいろと試行錯誤をした結果最終的に落ち着いているx-webmidiの使い方を簡単に説明しようと思います。

(MIDIデバイス必須の記事です。お手元に無い皆様には大変申し訳ありません・・・)

WebMIDIAPIWrapper

最初に作ったのがWebMIDIAPIWrapperです。これはJavaScriptのPrototypeとして作成しました。
MIDIメッセージの送信はもちろんのこと、受信したメッセージがどのメッセージなのかも分かるようにし作りました。
が、実装にそこそこ手間がかかる感があり、なんとかできないか?と常に思っていました。

Polymer

私のPOSTでは毎回登場するPolymer。Web Componentsのラッパみたいなもので、カスタムのHTMLタグを作ることができます。
このPolymerを知ったことをキッカケに、
「タグだけ書いたらMIDIデバイス使えたら便利」
という夢から刷新することを考え始めました。

Polymerについて詳しくはこちら▶「基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜」

x-webmidi

刷新したのがx-webmidi。夢通りHTMLタグのみで実装ができるようになっています。
「Polymerのエレメント?それ難しいんでしょ?」
と聞こえて来そうですがとても簡単です。順を追って説明します。

実装

(Google Chromeでの動作を想定して書いています)

0. bowerをご存知な方

shell
$ bower install --save x-webmidi;

以上で、以下の1, 2, 3は省略することが可能です。

1. Polymerをダウンロード
ここから入手します。

2. x-webmidiをダウンロード
ここから入手します。

3. ダウンロードしたファイルを配置する
bower_componentsというディレクトリを作成します。

shell
$ mkdir bower_components;

1, 2でダウンロードしたファイルをunzip。
unzipするとpoymer-masterまたはx-webmidi-masterというディレクトリが出来上がりますので、名前から-masterを削除して、bower_components に移動します。

shell
$ unzip polymer.zip;
$ unzip x-webmidi.zip;
$ mv polymer-master bower_components/polymer;
$ mv webaudio-controls-master bower_components/webaudio-controls;

4. 入力デバイスからのメッセージを表示
index.htmlとか適当な名前でファイルを作成し以下のHTMLを記述します。

html
<html>
  <head></head>
  <body>
    <script src="bower_components/webcomponentsjs/webcomponents.js"></script>
    <link rel="import" href="bower_components/x-webmidi/x-webmidirequestaccess.html">
    <x-webmidirequestaccess sysex input output></x-webmidirequestaccess>

    MIDI INPUT: <x-webmidiinput id="midiinput"></x-webmidiinput><br>

    <div id="printout"></div>

    <script type="text/javascript">
     const midiinput=document.querySelector("#midiinput");
     midiinput.addEventListener("midiin-event:midiinput", (event) => {
         const out=[];
         for(const index in event.detail.property) {
             out.push(index + " : " + event.detail.property[index]);
         }
         document.querySelector("#printout").innerHTML=out.join("<br>");
     });
    </script>

  </body>
</html>

MIDI入力デバイスからのMIDIメッセージの取得は以上で完了です。

MIDI入力デバイスを接続して、操作すると以下のようなメッセージが表示されるはずです。
Screen Shot 2016-12-16 at 1.44.15 AM.png

画像に表示されている値の説明は以下です。
- raw : 生MIDIメッセージ
- type : メッセージのタイプ(channel / systemCommon / systemRealtime)
- statusNum : StatusByte
- channel : チャンネル番号(0 - 15)
- subType : メッセージの種類名 (noteOn / noteOff / controller 等、全17種類)
- noteNumber : 押下した鍵盤番号
- velocity : velocity
- frequency : noteNumberの周波数
- intl : ノートの名前(International形式)

subTypeによって出力は変わりますので是非試してみてください🎹
ちなみに、MIDIメッセージに関しての説明は
11日目のWebAudio Web MIDI API Advent Calendar 2016
に書かれていますので、そちらをご参照ください!

5. 入力デバイスからのメッセージを出力デバイスにバイパス
以下のようなコードにします。

html
<html>
  <head></head>
  <body>
    <script src="bower_components/webcomponentsjs/webcomponents.js"></script>
    <link rel="import" href="bower_components/x-webmidi/x-webmidirequestaccess.html">
    <x-webmidirequestaccess sysex input output></x-webmidirequestaccess>

    MIDI INPUT: <x-webmidiinput id="midiinput"></x-webmidiinput><br>
    MIDI OUTPUT: <x-webmidioutput id="midioutput"></x-webmidioutput>

    <div id="printout"></div>

    <script type="text/javascript">
     const midiinput=document.querySelector("#midiinput");
     midiinput.addEventListener("midiin-event:midiinput", (event) => {
         const out=[];
         for(const index in event.detail.property) {
             out.push(index + " : " + event.detail.property[index]);
         }
         document.querySelector("#printout").innerHTML=out.join("<br>");
         document.querySelector("#midioutput").sendRawMessage(event.detail.data);
     });
    </script>

  </body>
</html>

追加したのは以下の2行です。

9行目
MIDI OUTPUT: <x-webmidioutput id="midioutput"></x-webmidioutput>
21行目
document.querySelector("#midioutput").sendRawMessage(event.detail.data);

MIDI INPUTに加えて、MIDI OUTPUTが画面には表示されます。
それぞれを選択状態にをすると、MIDI INPUTのメッセージがMIDI OUTPUTへ流れるようになりました。

まとめ

非常に簡単な説明になっていますが、x-webmidiを使うと非常に簡単にMIDIデバイス(Inputデバイス、Outputデバイス)をブラウザに接続して、Webアプリケーション内で利用できることが分かりましたか?
ということで、MIDIデバイスをブラウザに接続してみたいけど難しそうでイマイチ手を出せていない方、とか、何度もWeb MIDI APIのコードを書きたくない方は是非ご利用ください😃

ということで、よいWeb MIDIライフをっ🎹

この投稿は WebAudio Web MIDI API Advent Calendar 201617日目の記事です。