Web Music Developers JPのアドベントカレンダーの12月20日の記事です!

追記:Web MIDI APIの仕様は日に日に更新されています。2013年1月8日の段階で既にこの説明の説明からは変更されていますのでご注意ください。

前回は「Second Web MIDI API Working Draftのレビュー」を行いました。今回はWeb MIDI APIのWorkingDraft 第二版の末尾にあるサンプルコードのレビューを行います。とてもシンプルで分かりやすいサンプルコードになっていてとても参考になると思います。

ではさっそくレビューにはいります。

MIDI機器を取得

MIDI機器を扱う為の準備。

var midi = null;  // global MIDIAccess object

function onMIDISuccess( midiAccess ) {
 console.log( "MIDI ready!" );
 midi = midiAccess;  // store in the global 
}

function onMIDIFailure(msg) {
  console.log( "Failed to get MIDI access - " + msg );
}

navigator.getMIDIAccess( onMIDISuccess, onMIDIFailure );

getMIDIAccessメソッド成功時のcallback関数をonMIDISuccess[3-6行目]とする。onMIDISuccessでGlobal変数midi[1行目]にインターフェイスMIDIAccessを代入[5行目]。getMIDIAccessメソッドがエラーとなった場合のcallback関数としてonMIDIFailure[8-9行目]をと指定。

MIDI機器のリストアップ

MIDI入力元、出力先を指定する為にリストアップ。

function enumerateInputsAndOutputs( midiAccess ) {
 var inputs = midiAccess.enumerateInputs();
 var outputs = midiAccess.enumerateOutputs();
 var i;

 for (i=0; i<inputs.length; i++) {
  console.log(inputs[i]);
 }

 for (i=0; i<outputs.length; i++) {
  console.log(outputs[i]);
 }
}

インターフェイスMIDIAccessのメソッドenumerateInputs[2行目]/enumerateOutputs[3行目]を実行してMIDI機器のリストを取得して入力機器、出力機器を別々にconsole.logでデバッガのWebコンソールに出力[入力機器:6-8行目、出力機器:10-12行目]。

MIDIの入力信号を処理

受け取ったMIDI信号を処理。

function onMIDIMessage( event ) {
  var str = "MIDI message received at timestamp " + event.timestamp + "[" +
               event.data.length + " bytes]: ";
  for (var i=0; i<event.data.length; i++)
    str += "0x" + event.data[i].toString(16) + " ";
  console.log( str );
}

function startLoggingMIDIInput( midiAccess, indexOfPort ) {
  var input = midiAccess.getInput( indexOfPort );
  input.onmessage = onMIDIMessage;
}

インターフェイスMIDIAccessのメソッドgetInputで入力機器を指定して取得[9行目]し、MIDIメッセージを受信した場合のcallback関数(onmessage)をonMIDIMessageに指定[10行目]。 関数onMIDIessageは、MIDI入力を16進数変換してconsole.logでデバッガのWebコンソールに出力。

MIDIの出力ポートからMIDI信号を出力

MIDI信号を送信。

function sendMiddleC( midiAccess, indexOfPort ) {
  var output = midiAccess.getOutput( indexOfPort );
  output.send( [0x90, 60, 0x7f] );
   // note on, middle C, full velocity - omitting the timestamp means send immediately.
  output.send( [0x80, 60, 0x40], window.performance.now() + 1000.0 );
   // note off, middle C, release velocity = 64, 
   // timestamp = now + 1000ms.
}

インターフェイスMIDIAccessのメソッドgetOutputで出力機器を指定して取得[2行目]し、即座(timestampなし)に[90 60 7f]を実行するようMIDIメッセージを送信[3行目]、次に1000ms後に[80 60 40]が実行されるようMIDIメッセージを送信[4行目]。

  • [90 60 7f]:「MIDIポート1のC4を127の音量で発音する」というMIDIメッセージ
  • [80 60 40]:「MIDIポート1のC4を64の速度(機器によって異なる)で発音を停止する」というMIDIメッセージ

(RunningStatusの送信は許可されていません。)

MIDIの入力機器から受信したMIDIメッセージを出力機器へ送信するLoopback

var midi = null;  // global MIDIAccess object
var output = null;

function echoMIDIMessage( event ) {
  if (output)
    output.send( event.data, event.timestamp );
}

function onMIDISuccess( midiAccess ) {
  console.log( "MIDI ready!" );
  try { 
    var input = midiAccess.getInput( 0 );
    output = midiAccess.getOutput( 0 );
    input.onmessage = echoMIDIMessage;
  }
  catch (e) {
    console.log("Exception! Couldn't get i/o ports." + e );
  }
}

function onMIDIFailure(msg) {
  console.log( "Failed to get MIDI access - " + msg );
}

navigator.getMIDIAccess( onMIDISuccess, onMIDIFailure );
  • インターフェイスMIDIAccessを代入するGlobal変数midiを初期化[1行目]。
  • インターフェイスMIDIAccessのメソッドgetOutputで取得するインターフェイスMIDIOutputを代入するGlobal変数outputを初期化[2行目]。
  • getMIDIAccessメソッド成功時のcallback関数をonMIDISuccess[9-19行目]とする[25行目]。
  • MIDISuccessでは、getInputで先頭ににリストアップされた入力機器を取得[12行目]、getOutputで先頭ににリストアップされた出力機器を取得[13行目]、MIDIメッセージを受信した場合のcallback関数としてechoMIDIMessageを指定[14行目]。
  • echoMIDIMessageでは、選択した入力機器から受信したMIDIメッセージをそのまま選択した出力機器へ送信[6行目]。

というのがサンプルコードになります。 これでかなりイメージが湧くかな、と思います。

そして、Web MIDI APIの編集者の1人であるChris Wilsonさんが公開くださっているプラグインを使ったエミュレーションライブラリ(Polyfill)を実際に使って簡単なMIDI INのみのデモを作ってみましのた!!動作にはUSB-MIDIキーボードとJazz SoftのJazz-Pluginのインストールが必須となります。こんなに簡単にUSB-MIDI機器がブラウザにつながってしまう世の中になるのか〜、って思うとワクワクしちゃいます!

デモはこちらです!

それでは次回Web Music Developers JPのAdventCalenderの最終日は、MIDI OUTなデモが作成できたらな〜、と考えています!(作成できなかった場合、すみません。。。)

Web Music Developers JPのアドベントカレンダーの12月15日の記事です!

追記:Web MIDI APIの仕様は日に日に更新されています。2013年1月8日の段階で既にこの説明の説明からは変更されていますのでご注意ください。

2012年12月11日にWeb MIDI APIのWorkingDraft 第二版になりました。サンプルコードも追加され、また編集者の一人であるChris Wilsonさんがプラグインを使ったエミュレーションライブラリ(Polyfill)を公開してくださいました。仕様とサンプルを同時にレビューすると長くなりそうなので「仕様のレビュー」、「サンプルコードのレビュー」の2部構成で進めさせていただこうと思います。初回の今回は「仕様のレビュー」を行います。

さて、まずは「MIDI」と「Web MIDI API」についての簡単な説明です。 MIDIは「Musical Instrument Digital Interface」の略で、日本語にすると「電子楽器デジタルインターフェイス」、電子楽器の演奏データを機器間でデジタル転送するための世界共通規格です。そしてWeb MIDI APIです。HTML5のデバイスアクセスの仕様の1つとしてW3Cで策定が進められているウェブブラウザから”プラグインを使わずに”電子楽器へ直接接続を可能にする為のAPIです。とはいえ、最近のコンピュータでMIDIポートを搭載しているものはありませんので、基本的にはUSB-MIDIでの接続になります。Web MIDI APIの最終的な仕様は2013年の第3四半期に策定される予定になっています。

それではWeb MIDI APIの仕様のレビューをしていきます。 最初に全体的な構成です。(i)がinterface、(m)がmethodを示しています。また「->」の意味ですが、例えば「A -> return B」だとすると「Aを実行するとBがくる」という意味で使っています。

  • (i)NavigatorMIDIAccess
    - (m)getMIDIAccess -> return void
  • (i)MIDIAccess
    - (m)enumerateInputs -> return (i)MIDIPort
    - (m)enumerateOutputs -> return (i)MIDIPort
    - (m)getInput -> return (i)MIDIInput
    - (m)getOutput -> return (i)MIDIOutput
  • (i)MIDIPort
  • (i)MIDIInput
  • (i)MIDIOutput
    - (m)send -> return void
  • (i)MIDIEvent

次に(i)のついているinterfaceを説明します。

UserAgentのwindow.navigatorに属するObjectでMIDI機器へのアクセスを可能にします。

interface NavigatorMIDIAccess {
      void getMIDIAccess(successCallback, optional errorCallback)
    }

MIDIAccess

UserAgentに接続されているMIDI機器のリストアップ、またアクセスを可能にします。

interface MIDIAccess {
      sequence<MIDIPort> enumerateInputs();
      sequence<MIDIPort> enumerateOutputs();
      MIDIInput          getInput(MIDIPort or DOMString or short target);
      MIDIOutput         getOutput(MIDIPort or DOMString or short target);
}

MIDIPort

MIDIのInput/Outputポートで、名前、製造会社、MIDIポートのタイプ(input/output)、ユニークIDを提供します。

interface MIDIPort: EventTarget {
      DOMString    fingerprint;
      DOMString    manufacturer;
      DOMString    name;
      MIDIPortType type; // input or output
      DOMString    version;
}

MIDIInput

MIDIPortに組み込まれていて、さらにMIDIメッセージハンドラをデバイスへ割当てることが可能です。onmessageにMIDIメッセージを取得した時の処理を関数として書きます。

interface MIDIInput {
  attribute callback? onmessage;
}

MIDIOutput

MIDIPortに組み込まれていて、またMIDIメッセージをOutputポートへ送信するメソッドを提供します。

interface MIDIOutput {
  void send(sequence<short> data, optional DOMHighResTimeStamp? timestamp);
}

MIDIEvent

MIDIInputのonmessage handlerに渡されたEventオブジェクトで、MIDI data byteに加えてtimestampも含まれています。

interface MIDIEvent: Event {
  attribute DOMHighResTimeStamp timestamp;
  attribute Uint8Array          data;
}

最後に(m)のついているmethodの説明です。

getMIDIAccess(successCallback, optional errorCallback)

  • successCallback: MIDI機器が取得できた場合のCallback
  • -> (i)MIDIAccess を渡す
  • errorCallback: なんらかの理由でMIDI機器を取得できなった場合のCallback
  • enumerateInputs()
  • 引数なし
  • 利用可能なMIDI input port[(i)MIDIInput]のリストを配列で返す

enumerateOutputs()

  • 引数なし
  • 利用可能なMIDI output port[(i)MIDIInput]のリストを配列で返す

getInput(target)

  • target: (i)MIDIPort、または、(i)MIDIPortのfingerprint[DOMString]、
    または、 enumerateInputs()で取得したindex[short]

getOutput(target)

  • target: (i)MIDIPort、または、(i)MIDIPortのfingerprint[DOMString]、
    または、enumerateOutputs()で取得したindex[short]

send(data, optional timestamp)

  • data: 配列にしたshort
  • timestamp: DOMHighResTimeStamp(暫定?)

といった仕様になっています。 これだけではイメージするのは難しいと思いますが、「サンプルコードのレビュー」も続けて書きますので、そちらも合わせてご覧になるともっとイメージが湧くと思います。

ということで今回はここまでということで!

Web Music Developers JPのアドベントカレンダーの12月13日の記事です!

ネタは「緊急車両通りますよ〜っと!「Web Audioでドップラー効果」」です。 物理の授業で出てくる定番かな、って思います。 ドップラー効果は19世紀半ばにオーストリアの物理学者ドップラーさんが発見しました。簡単に説明すると、音は音源を中心に球状に音波の速度で伝わります。聞き手が音源に向けて一定の速度で近づくとき、音波の速度は (音波の速度)+(聞き手の速度) となりますが、音源から遠ざかる時は (音波の速度)-(聞き手の速度) となり、この音波の速度が異なることで音程が変わる、というのが原理です。

さて、ここからWeb Audioへの実装の下準備です。 今回は音は固定、聞き手(針金人間)が動くという想定で実装していきます。 変数と式はそれぞれ以下のようになります。

  • 音波の速度:340(m/s) で固定します。(14.17℃の時の音波の速度です)
  • 波周波数: F0 = V340 / Lambda
  • 初期状態において聞き手から音までの距離:d(m)
  • 聞き手の速度: v0 (m/s)
  • 聞き手の周波数:F1

(a) 音よりも右の場合:F1 = (V340 + v0) / Lambda = F0 ( V0 + U1 ) / V0

var tune = (V340+v0)/V340; // L32: js/dopplerEffect.js

(b) 音よりも左の場合:F1 = (V340 - v0) / Lambda = F0 ( V0 - U1 ) / V0

var tune = (V340+v0)/V340; // L32: js/dopplerEffect.js

(a)と(b)の分岐は、

d-v0*(i*interval)/1000 // L31: js/dopplerEffect.js

が、0より大きい場合は(a)、0より小さい場合は(b)となります。

このとき interval は JavaScriptのSetIntervalが呼ばれる間隔(ミリ秒)です。iはSetIntervalを何回通ったか、という変数にしていますので

(i*interval)/1000

は今までに聞き手が初期状態から動いた距離になります。

あとせっかくなので、PanとVolume(Gain)を変えてより臨場感を出します。 WebAudioでのPanは3次元で設定できますが、今回はその1次元だけを使います。最大値は1.0、最小値は-1.0、中央は0.0となっていますのでそのように動くように式を作ります。Volumeは最大値は1.0、最小値は0.0ですが、今回は音が大きくなり過ぎるのを避けるために最大値は0.5と設定しました。 音源は定番の救急車の「ピーポーピーポー」にしました。ヘッドホンで聞くとより臨場感のあるドップラー効果を聞けると思います。

実装したモノはこちらです。

1つもヒネリがなかった訳ですが、Web AudioってHTML5なのでテキストエディタとブラウザがあれば実装できるので、教育現場で使えたりするんじゃないかな〜、なんて密かに思っています。科学って実際に肌で触れるとより理解できると個人的には思っているので、特にWeb Audioに関してはそっちでも使われるといいな〜、なんて抱いています。

つい先日Google+に「コミュニティ」機能が追加されました。 まず「Google+って何?」というところだと思います。ざっとこんな感じです。

  • 情報を発信できる
  • 人をフォローして投稿を読む事ができる
  • フォローを分類してサークルというグループを作る事ができる
    (他人には非公開)
  • サークル、人を限定した投稿ができる
  • イベント機能を使ってイベント開催を周知できる
    (Google Calenderにも反映される)
  • イベント中の写真を立てたイベントに紐づけてアップロードでき共有できる
  • ハングアウト機能を使ってビデオチャット的なことができる

「Twitter、Facebookと同じじゃん。」とお気づきかもしれません。そうですその通りです。ただし 投稿先を細かく設定できる 点が他のTwitter、Facebookとは大きく違うところだと思います。またイベント機能を使うと例えばパーティー、勉強会等の告知が簡単にできて、さらにハングアウトではストリーミングで映像の配信、音楽セッションができたりします。どのSNSよりも詳細な設定が可能なところが僕は気に入っています。

そして本題のGoogle+のコミュニティ機能。これは特定の人達とのコミュニケーションができる場です。サークルとの違いは、サークルは各個人の嗜好で人を追加して個人が個人の為にだけ作り上げるのに対して、コミュニティは個人の嗜好で参加することで人が集まるという違いがあります。そうGoogle+のコミュニティは学校の活動に例えるとサークルですね。(ちょっとややこしい。。。)

コミュニティの作成に関しては任意で「公開」、「非公開」の設定が可能、参加制限についてもオーナーの許可の有無の選択ができます。さらにコミュニティの中にもイベントも作れます。議論もしすいようにタグが用意されていて任意に設定できます。グループで集まって何かするには最適だと思います。例えば結婚式の二次会とかを想定すると、運営が1、2人なら連絡、意思疎通に問題ないのですが複数人になると集まるだけでも大変だと思います。それを、この機能を使って役割毎にタグを作成して問題が起こったらタグ付けをして議論・告知、アイデア出しもタグをつけて発言、また集まる日程はイベントで、といった感じで本来煩わしいやりとりをスマートに進められるんじゃないかな〜、と思います。

まとまりのないダラダラとした説明になっていますが「Google+コミュニティいいね!」とも言いたいですが、実は「Google+いいよ〜」ともいいたいのですf(^-^;)ということで、まだ使った事ない方は使ってみると心地の良いSocialな日々が送れる思いますよ〜

ちなみに、蛇足ですが僕はここにいます。

CoCo壱番屋 カツカレーチップス」(限定商品)です。

名前の通り、CoCo壱番屋のカツカレーの味がするチップスです。味の再現性が結構高いです。個人的にCoCo壱番屋のカレーって独特の味で、カレーというより「ココイチ」というジャンルを作ってもいいんじゃないか、って思ってる(もちろん悪い意味ではないですよ!)のですが、その味が再現されてておいしいチップスでした。もちろん単なるカレーの味ではなくて「カツカレー」の味の再現です。ちょっと感動しました。

ビールのお供に最適かな〜って思いました!限定商品らしいので、これを見かけたビール好きの方は一度お試しあれ〜!!