Edited at
gloopsDay 5

Web MIDI APIを触ってみた

More than 1 year has passed since last update.


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さんです!