LoginSignup
133
126

More than 1 year has passed since last update.

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

Last updated at Posted at 2014-08-25

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)」アプリです。

133
126
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
133
126