JavaScriptだけでMIDIで遊べる!最高に乱暴なWeb MIDI API利用方法

  • 118
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

JavaScriptだけでMIDIで遊べる!最高に乱暴なWeb MIDI API利用方法

Web MIDI API / Web Audio APIを使ったハッカソンイベント「Web Music ハッカソン #3」が近づいていますので、ここでWeb MIDI APIの使い方を振り返ってみましょう。

はじめに断っておきますが、これは 乱暴者による乱暴者向けの記事です。
最低限の手間で、Web MIDI APIに対応してる気分を味わう までを目指します。

[2015/02/08 追記]
さらに手間をかけたくないという超絶手抜きな人(ワシです)向けに、アホみたいなラッパー(poormidi.js)作りました。

良かったら使ってみてください。

ちゃんと勉強したい方は、下記リンクを見てください。

ちゃんと勉強したい方向けリンク集

Web MIDI API (W3C)

Web MIDI APIの仕様はW3Cで策定中です。(2014年8月25日現在、Working Draft版です)

Web MIDI API (日本語訳)

shinyagaitoさんによるWeb MIDI API仕様の日本語訳です。

Code Labs

@ryoyakawaiさんによるWeb Audio APIとWeb MIDI APIのチュートリアルです。

Chromeで動かそう

それでははじめましょう。

Web MIDI APIが動くブラウザは、2014年8月25日現在Chromeだけですが、今回は、Polyfillを使わず、Chromeしか動かなくていーやー。な乱暴な感じで行きます。

ブラウザ差分考えなくていいからいいよね!?w

Chromeの Web MIDI API機能を有効にするための設定

対応してる風なChromeですが、まだ試験運用のようで、Web MIDI API機能はデフォルトでは無効になっているようです。
ブラウザのアドレスバーから、chrome://flagsと入力して設定画面を呼び出して、midi で検索を行い、「Web MIDI API を有効にする」欄をチェックして有効にしてください。(Chromeの再起動が必要)

また、MIDI機器を繋いだ後も、ブラウザの再起動が必要です。

MIDIを有効にする。requestMIDIAccess()

はじめに。

Web MIDI APIを使うには、最初にnavigator.requestMIDIAccess()を呼び出して、Web MIDIを有効にします。

navigator.requestMIDIAccess().then(onMIDISuccess,onMIDIFailure);

.then()の第1パラメータに、MIDI使える時に呼び出されるCallback関数を、第2パラメータにエラー時のCallback関数を指定しましょう。

成功を祈りつつ。onMIDISuccess() (Chrome v39以降用に書き換え)

続けて、MIDI有効に出来た時に呼び出されるonMIDISuccess()を書いてみます。

var midi = null;
var inputs = [];
var outputs = [];

function onMIDISuccess(m){
  midi = m;
  var it = midi.inputs.values();
  for(var o = it.next(); !o.done; o = it.next()){
    inputs.push(o.value);
  }
  var ot = midi.outputs.values();
  for(var o = ot.next(); !o.done; o = ot.next()){
    outputs.push(o.value);
  }

  for(var cnt=0;cnt < inputs.length;cnt++){
    inputs[cnt].onmidimessage = onMIDIEvent;
  }
}

乱暴者らしく、どのポートに来ても全部同じ処理ですw
さらに、onMIDIFailure()の方は空っぽですw

function onMIDIFailure(msg){
  console.log("onMIDIFailure()呼ばれただと?:"+msg);
}

こんな感じで良いはずです。(適当w)

onmidimessageに登録する関数を書く。

もう少しです。続けてMIDI信号を受け取った時の処理を書きましょう。
先ほどinputs[cnt].onmidimessageに指定したonMIDIEvent()です。

function onMIDIEvent(e){
  if(e.data[2] != 0){ 
    // なにかをうけとったときの処理
  }
}

これは、乱暴者らしさを強調する 恐ろしく手抜きな処理です!w

たぶんNote ONと Note OFFしか来ないからVelocityが0以外だったらNoteONと見なして処理しよう。
という作戦です。

こんなんじゃヤダ!という正常な人は、g200kgさんのDTM技術情報>1.MIDIメッセージ一覧でも見て、ちゃんと書きましょう。

送信にも対応する

最後に、MIDI送信にも対応しましょう。
もちろん 乱暴さ を最後まで徹底したいので、1コ目の機器決め打ちで適当なノートONを送りつける という処理にします。

function sendMIDINoteOn(note){
  if(outputs.length > 0){
    outputs[0].send([0x90,note,0x7f]);
  }
}

出来ました!

これを、<button>タグとかのonClickとかで呼び出せば、MIDI機器が鳴ってくれます!

しかし、ここでも 超乱暴な仕掛 けが。
ノートOFFが無いので、多くの機器では 鳴りっぱなし になるはずです。
もちろん、乱暴者は、機器側の電源を切る などの乱暴な対応で乗り切ってください。

完成。(Chrome v39対応)

※以下のコードは、Chrome v39.0以降用に書き換えています。(2014/11/09)

navigator.requestMIDIAccess().then(onMIDISuccess,onMIDIFailure);

var midi = null;
var inputs = [];
var outputs = [];

function onMIDISuccess(m){
  midi = m;
  var it = midi.inputs.values();
  for(var o = it.next(); !o.done; o = it.next()){
    inputs.push(o.value);
  }
  var ot = midi.outputs.values();
  for(var o = ot.next(); !o.done; o = ot.next()){
    outputs.push(o.value);
  }

  for(var cnt=0;cnt < inputs.length;cnt++){
    inputs[cnt].onmidimessage = onMIDIEvent;
  }
}

function onMIDIFailure(msg){
  console.log("onMIDIFailure()呼ばれただと?:"+msg);
}

function onMIDIEvent(e){
  if(e.data[2] != 0){
    // なにかをうけとったときの処理
  }
}

function sendMIDINoteOn(note){
  if(outputs.length > 0){
    outputs[0].send([0x90,note,0x7f]);
  }
}

簡単!w

まとめ

乱暴者にもWeb MIDI APIなら使えるよ!

こんな感じで。
ち〜ん