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なら使えるよ!
こんな感じで。
ち〜んタイマー
2022/11/02更新
もともとの記事に記載していた「フィジカルWebアプリち〜ん」の運用が停止したため、「ち〜んタイマー」にリンクを置き換えました。
「ち〜んタイマー」は、ベルを鳴らすMIDIデバイス「ち〜ん」がつながってれば、タイムアップ時にMIDIデバイスのベルが鳴り、つながっていなくても、Web Audioでベルの音が鳴る「ある意味拡張現実(AAR)」アプリです。