##はじめに
この記事は SLP_KBITその2 Advent Calendar 2016 の24日目の記事です。
最近Web MIDI APIなるものを知りました。
これを使うとMIDIに対応しているデバイスをPCに接続するだけで、JavascriptでMIDIの入出力が行えるそうです。なにそれすごい。
そんなわけで早速シンセサイザーを使ってMIDIの入力を受け取ってみます。
##MIDIについて
MIDIは電子楽器の演奏データを通信するための規格です。
演奏情報の音を、音の高さ(ノート)、音の強さ(ベロシティ)、音の長さ(デュレーション)表現するそうです。
詳しいことはWebAudio Web MIDI API Advent Calendar 2016の18日目の記事が参考になりました。
##MIDIプロトコル
MIDIのプロトコルで扱うデータとして、音のON/OFF、使用するチャンネル、音の強弱、音程の変化があります。
WikipediaでMIDIを調べたところ他にもいろいろなデータを送信しているようですが、これらのデータがあれば最低限演奏に必要なものは揃っています。
##MIDIデバイスを繋げる(物理)
今回はJUNO-Giというシンセサイザーを使用します。
このシンセサイザーをUSBケーブルでPCに接続します。
##使用できるMIDIデバイスを表示する
htmlはこんな感じです。
<html>
<head>
<meta charset="UTF-8" />
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="sample.js"></script>
<title>Web MIDI API</title>
</head>
<body>
<label>入力デバイス</label>
<ul id="input">
</ul>
<label>出力デバイス</label>
<ul id="output">
</ul>
<label id="data">00 00 00</label>
</body>
</html>
###MIDIの有効化
ブラウザでMIDIを有効にするには、requestMIDIAccess()
を使用します。
また、引数にMIDIの有効が成功したときと失敗したときのコールバックを指定します。
navigator.requestMIDIAccess().then(successCallback,faildCallback);
###MIDIデバイスの表示
成功時のコールバックで、入力のMIDIデバイスと出力のMIDIデバイスを配列で記録します。
また、記録時にリストで表示も行います。
navigator.requestMIDIAccess().then(successCallback,faildCallback);
var midi = null;
var inputs = [];
var outputs = [];
// MIDI接続成功時
function successCallback(m){
midi = m;
// 入力MIDIデバイスの記録
var it = midi.inputs.values();
for(var o = it.next(); !o.done; o = it.next()){
inputs.push(o.value);
$("#input").append("<li>"+ o.value.name +"</li>");
}
// 出力MIDIデバイスの記録
var ot = midi.outputs.values();
for(var o = ot.next(); !o.done; o = ot.next()){
outputs.push(o.value);
$("#output").append("<li>"+ o.value.name +"</li>");
}
}
// MIDI接続失敗時
function faildCallback(msg){
console.log("[Error]:"+msg);
}
うまくいけば、ページ読み込み時に現在接続されているMIDIデバイスが表示されいるはずです。
今回はJUNO-Giというシンセサイザーを使用しているため、その名前が表示されます。
##MIDI入力の値を表示する
配列に記録している入力のMIDIデバイスに、入力が来たときの処理を登録します。
// 入力MIDIデバイスから入力が来たときの処理の登録
for(var cnt=0;cnt < inputs.length;cnt++){
inputs[cnt].onmidimessage = onMIDIEvent;
}
今回は送られてきた信号をブラウザ上で表示させます。
//入力MIDIデバイスから入力が来たときの処理
function onMIDIEvent(e){
var str = "";
for(var i=0, out=[]; i<e.data.length; i++) {
str = str + e.data[i].toString(16).substr(-2) + " ";
}
str = str;
$("#data").text(str);
}
全体のコードは以下のようになります。
navigator.requestMIDIAccess().then(successCallback,faildCallback);
var midi = null;
var inputs = [];
var outputs = [];
// MIDI接続成功時
function successCallback(m){
console.log("asd");
midi = m;
// 入力MIDIデバイスの記録
var it = midi.inputs.values();
for(var o = it.next(); !o.done; o = it.next()){
inputs.push(o.value);
$("#input").append("<li>"+ o.value.name +"</li>");
}
// 出力MIDIデバイスの記録
var ot = midi.outputs.values();
for(var o = ot.next(); !o.done; o = ot.next()){
outputs.push(o.value);
$("#output").append("<li>"+ o.value.name +"</li>");
}
// 入力MIDIデバイスから入力が来たときの処理の登録
for(var cnt=0;cnt < inputs.length;cnt++){
inputs[cnt].onmidimessage = onMIDIEvent;
}
}
// MIDI接続失敗時
function faildCallback(msg){
console.log("[Error]:"+msg);
}
//入力MIDIデバイスから入力が来たときの処理
function onMIDIEvent(e){
var str = "";
for(var i=0, out=[]; i<e.data.length; i++) {
str = str + e.data[i].toString(16).substr(-2) + " ";
}
str = str;
$("#data").text(str);
}
##実行する
それでは実行してみます。
鍵盤を叩くたびに値が変わっているのがわかります。
##おわりに
今回はMIDIの入力を受け取るところまで行いました。
この調子で今度は音の出力や可視化を行っていこうと思います。
##参考
###Web MIDI API
MIDIデバイスの準備不要 !Web MIDI APIを使いこなそう!
JavaScriptだけでMIDIで遊べる!最高に乱暴なWeb MIDI API利用方法
###MIDIの知識
Web MIDI APIを扱うためのMIDI基礎知識
MIDIが良く分かる。バンドマンのためのDTMの基礎知識