<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！ &#8211; HTML5Experts.jp</title>
	<atom:link href="/series/webmidi-2015/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>MIDIデバイスの準備不要！お手軽な『MIDIアプリ』実装法</title>
		<link>/ryoyakawai/17337/</link>
		<pubDate>Fri, 27 Nov 2015 00:00:53 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Web MIDI API]]></category>

		<guid isPermaLink="false">/?p=17337</guid>
		<description><![CDATA[連載： MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！ (2)この記事は、Web MIDI APIを題材にした連載の第二回目です。（第一回目はこちら） 第一回目はWeb MIDI APIでMIDI...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/webmidi-2015/" class="series-347" title="MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！" data-wpel-link="internal">MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！</a> (2)</div><p>この記事は、Web MIDI APIを題材にした連載の第二回目です。（第一回目は<a href="https://html5experts.jp/ryoyakawai/16787/" data-wpel-link="internal">こちら</a>）</p>

<p>第一回目はWeb MIDI APIでMIDI Inputデバイス、Outputデバイスを列挙し、利用する実装方法を説明してきましたが、詳細の実装の説明までできていませんでした。第二回ではx-webmidiというPolymer Elementを使い、第一回で実装した部分、また実装ができていなかったHotplugを含めて、お手軽に実装してしまう方法をご説明します。</p>

<p>前回に引き続き、今回もMIDIデバイスの準備は不要な内容になっていますので、最後までお試しいただけると嬉しいです。</p>

<h1>Polymerとは？</h1>

<p>「Web Componentsを簡単・便利にするライブラリ」です。Polymerを使うと簡単にWeb ComponentsのElementを作成することが可能です。本サイトHTML5Expert.jpでも連載記事がありますので、ぜひご覧ください。</p>

<ul>
<li><a href="https://html5experts.jp/series/web-components-2/" data-wpel-link="internal">基礎からわかる Web Components 徹底解説</a>  </li>
</ul>

<p>そして今回は、Web MIDI APIをPolymer Element化したx-webmidiを使って、以下の2つのアプリの実装をしていきます。</p>

<ol>
 <li>InputからOutputにMIDIメッセージを中継するアプリ</li>
 <li>SMF（Standard MIDI File）を再生するアプリ</li>
</ol>

<h1>x-webmidiとは？</h1>

<p>Web MIDI APIは、外部のMIDIデバイスとUSB-MIDIで接続するAPIです。API自体には<strong>「デバイスをリストする」</strong>、<strong>「デバイスへMIDIメッセージを送信する」</strong>、<strong>「デバイスからのMIDIメッセージを受信を行う」</strong>、また、接続に関しては<strong>「Hotplug」</strong>が、それぞれサポートされています。</p>

<p>しかし、これらを実装するのは少し手間がかかります。自分自身の体験としては、複数アプリケーションを書いていると「アイデアをアプリケーションに落としこむ時、MIDIデバイスの制御の部分に労力をかけるのは極力抑えたい」と思うようになりました。そこで考えついたのが、Polymerを使って基本的な操作はElementにしてしまう方法です。そして生まれたのが<strong>「x-webmidi 」</strong>です。</p>

<h1>さっそく実装してみよう</h1>

<h3>環境整備</h3>

<p><a href="https://html5experts.jp/ryoyakawai/16787/" data-wpel-link="internal">連載第一回目の環境整備</a>と同じです。ここでは手短に説明します。<br />
Polymer本体、今回利用するx-webmidiをそれぞれダウンロードします。</p>

<ul>
 <li><a href="http://zipper.bowerarchiver.appspot.com/archive?polymer=Polymer/polymer%231.0.0" target="blank" data-wpel-link="external" rel="follow external noopener noreferrer">Polymer</a></li>
 <li><a href="https://github.com/ryoyakawai/x-webmidi/archive/0.10.23.zip" target="blank" data-wpel-link="external" rel="follow external noopener noreferrer">x-webmidi</a></li>
</ul>

<p>開発するディレクトリを作成して、ダウンロードした2つのファイルを解凍し、以下の構成になるように配置してください。その後、同一ディレクトリにindex.htmlを作成します。</p>

<p><img src="/wp-content/uploads/2015/10/xwebmidi-directory-02.png" alt="Directory Structure" width="300" class="aligncenter size-full wp-image-17346" srcset="/wp-content/uploads/2015/10/xwebmidi-directory-02.png 535w, /wp-content/uploads/2015/10/xwebmidi-directory-02-300x183.png 300w, /wp-content/uploads/2015/10/xwebmidi-directory-02-207x126.png 207w" sizes="(max-width: 535px) 100vw, 535px" /></p>

<p>以上で環境整備は完了です。</p>

<p>では、実際に実際に開発を行っていきましょう。</p>

<h3>InputからOutputにMIDIメッセージを中継するアプリ</h3>

<p>作成する index.html のコード全体は<a href="https://github.com/ryoyakawai/x-webmidi/blob/gh-pages/src/hx_webmidi_02.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>になります。それでは順に説明していきます。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="bower_components/webcomponentsjs/webcomponents.js"&gt;&lt;/script&gt;
&lt;link rel="import" href="bower_components/x-webmidi/x-webmidirequestaccess.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-webmidilink/wm-webmidilink.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-pckeyboard/wm-pckeyboard.html"&gt;
&lt;x-webmidirequestaccess input output&gt;&lt;/x-webmidirequestaccess&gt;

&lt;wm-webmidilink id="wmlink"&gt;&lt;/wm-webmidilink&gt;
&lt;wm-pckeyboard id="pckeyboard"&gt;&lt;/wm-pckeyboard&gt;</pre><p></p>

<ul>
<li>1行目：Web ComponentsのPolyfillを読み込み</li>
<li>2〜4行目：Web MIDI API（x-webmidi）、仮想MIDI Outputデバイス(wm-webmidilink)、仮想のInputデバイス(wm-pckeyboard)のPolymer ElementをImport  </li>
<li>5行目：x-webmidiをアクティベート</li>
</ul>

<p>x-webmidiの属性は以下の通りです。</p>

<ul>
 <li><b>input</b>： MIDI Inputデバイスを利用する場合に追加</li>
 <li><b>output</b>： MIDI Outputデバイスを利用する場合に追加</li>
 <li><b>sysex</b>： System Exclusive メッセージを使う場合に追加</li>
</ul>

<p>今回、System Exclusive メッセージは使わないので、inputとoutputのみを記述します。</p>

<ul>
<li>7行目：wm-webmidilinkをアクティベート</li>
<li>8行目：wm-pckeyboardをアクティベート</li>
</ul>

<p>以上で準備は完了です。次にMIDIデバイスのリスト表示を行います。</p>

<p></p><pre class="crayon-plain-tag">input: &lt;x-webmidiinput id="midi-input" additionalid="pckeyboard" autoselect="PC-Keyboard" autoreselect&gt;&lt;/x-webmidiinput&gt;&lt;br&gt;
output: &lt;x-webmidioutput id="midi-output" additionalid="wmlink" autoselect="GMPlayer(WebMIDILink)" autoreselect&gt;&lt;/x-webmidioutput&gt;
&lt;br&gt;</pre><p> 
x-webmidiinputとx-webmidioutputの属性は以下の通りです。</p>

<ul>
 <li><b>additionalid</b>： 仮想のデバイスを追加する場合、そのタグのIDで指定します</li>
 <li><b>autoselect </b>： 自動選択して欲しMIDIデバイス名を指定します</li>
 <li><b>autoreselect </b>： 現在指定しているデバイスが切断され再接続した場合に自動選択します</li>
</ul>

<p>今回は仮想のデバイスを追加するため、属性 additionalid に、input側はpckeyboard(wm-pckeyboardタグのID名)、output側はwmlink(wm-webmidilinkタグのID名)をそれぞれ指定しています。最後に入力されたMIDIメッセージを表示する場所を作ります。
</p><pre class="crayon-plain-tag">&lt;div id="msg" style="margin:30px;"&gt;&lt;/div&gt;</pre><p></p>

<p>Inputから受け取ったMIDIメッセージを中継するためのJavaScriptを記述していきます。
</p><pre class="crayon-plain-tag">var output=document.getElementById("midi-output");
    window.addEventListener("midiin-event:midi-input", function(event){
        for(var i=0, out=[]; i&lt;event.detail.data.length; i++) out.push(("00"+event.detail.data[i].toString(16)).substr(-2));
        var div_msg=document.getElementById("msg");
        var ex_msg=div_msg.innerHTML.split("&lt;br&gt;");
        while(ex_msg.length&gt;19) ex_msg.pop();
        div_msg.innerHTML=out.join(" ")+"&lt;br&gt;" + ex_msg.join("&lt;br&gt;");
        if(output.checkOutputIdx()!="false") {
            output.sendRawMessage(event.detail.data);
        }
    });</pre><p></p>

<ul>
<li>1行目：MIDI OutputのObjectを取得</li>
<li>2行目：MIDI InputからのメッセージはEventとして飛んできますので、EventListenerをつける。Event名は&#8221;midiin-event:&#8221;に続き x-webmidiinput タグで指定したIDになる。MIDI Inputデバイスから入力したMIDIメッセージは event.detail.data。  </li>
<li>3行目：「MIDIメッセージを表示する場所」に表示して、分かりやすいように16進数の文字列にキャスト </li>
<li>4行目：「MIDIメッセージを表示する場所」のElementを取得</li>
<li>5, 6行目：「MIDIメッセージを表示する場所」の表示を新しいメッセージから順に並べるのと同時に表示する行数を絞る</li>
<li>7行目：MIDIメッセージを「MIDIメッセージを表示する場所」に表示</li>
<li>8〜10行目：Outputデバイスが選択されていたら、選択されているデバイスに対してInputから入力されたMIDIメッセージを送信。  </li>
</ul>

<p>これで、InputからOutputにMIDIメッセージを中継することができました。</p>

<h3>SMF（Standard MIDI File）を再生するアプリ</h3>

<p>次にMIDIというと必ず出てくるであろうSMF（Standard MIDI File）の再生です。</p>

<p>SMFはMIDIメッセージ1つ1つに時間情報を付加して、規定のフォーマットにまとめたバイナリファイルです。ここで付加された時間通りにMIDIメッセージを音源モジュールに送ることで、自動演奏ができる仕組みになっています。</p>

<p>SMFをWebブラウザ上で再生するには、SMFのバイナリを読み解いて（パース）、付加されている時間通りにMIDIメッセージを音源モジュールに送信する、という手順になります。しかし、このバイナリファイルをパースするためにはSMFのフォーマットを勉強しないといけません。この問題を解決するべく、SMFのバイナリをパースする部分を、<strong>「wm-smfplayer」</strong>というPolymerのElementにしてみました。このElemetでSMFを再生するアプリを作ってみます。</p>

<p>作成する index.html のコード全体は<a href="https://github.com/ryoyakawai/x-webmidi/blob/gh-pages/src/smfplayer.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>になります。それでは順に説明していきます。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="bower_components/webcomponentsjs/webcomponents.js"&gt;&lt;/script&gt;
&lt;link rel="import" href="bower_components/x-webmidi/x-webmidirequestaccess.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-webmidilink/wm-webmidilink.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-smfplayer/wm-smfplayer.html"&gt;
&lt;x-webmidirequestaccess input output sysex&gt;&lt;/x-webmidirequestaccess&gt;</pre><p></p>

<ul>
<li>1〜3行目：「InputからOutputにMIDIメッセージを中継するアプリ」と同じ</li>
<li>4行目：SMFをパースするElementを読み込む。SMFの中にはSystem Exclusiveが入っている場合があるので属性を書いています。  </li>
</ul>

<p></p><pre class="crayon-plain-tag">&lt;wm-webmidilink id="wmlink"&gt;&lt;/wm-webmidilink&gt;
&lt;wm-smfplayer id="smfplayer" midifile="contents/ys2_op_gm.mid" latency="1200"&gt;&lt;/wm-smfplayer&gt;</pre><p> 
続いて、wm-webmidilinkタグを記述して仮想のOutputデバイスをアクティベートし、SFMをパースする wm-smfplayer タグを記述しています。wm-smfplayerの属性は以下の通りです。</p>

<ul>
 <li><b>midifile</b>： SMFのURL（パス）</li>
 <li><b>latency </b>： MIDIメッセージをバッファする時間</li>
</ul>

<p>Latencyを指定してMIDIメッセージをバッファリングすることで、より時間に正確な再生が可能になります。<br>
次に、MIDI Outputデバイスのリスト表示、SMFの再生制御のためのボタンを追加します。
</p><pre class="crayon-plain-tag">output: &lt;x-webmidioutput id="midi-output" additionalid="wmlink" autoselect="GMPlayer(WebMIDILink)" autoreselect&gt;&lt;/x-webmidioutput&gt;
&lt;br&gt;

&lt;button id="startPlay" disabled&gt;Start&lt;/button&gt;
&lt;button id="stopPlay" disabled&gt;Stop&lt;/button&gt; &lt;br&gt;
&lt;button id="allSoundOff" disabled&gt;All Sound Off&lt;/button&gt;</pre><p></p>

<p>最後に、SMF再生中に取得したMIDIメッセージを、選択されたMIDI Outputデバイスに送信するためのJavaScriptを記述していきます。</p>

<p></p><pre class="crayon-plain-tag">var out_elem=document.getElementById("midi-output")
var output=null;
out_elem.addEventListener("midioutput-updated:midi-output", function(event){
    output=out_elem.getOutputDevice();
    document.getElementById("startPlay").removeAttribute("disabled");
    document.getElementById("stopPlay").removeAttribute("disabled");
    document.getElementById("allSoundOff").removeAttribute("disabled");
}, false);
var smfPlayer=document.getElementById("smfplayer");
document.getElementById("startPlay").addEventListener("mousedown", function(){
    if(output!=null) smfPlayer.startPlay(output);
});
document.getElementById("stopPlay").addEventListener("mousedown", function(){
    smfPlayer.stopPlay();
});
document.getElementById("allSoundOff").addEventListener("mousedown", function(){
    var output=document.getElementById("midi-output").getOutputDevice();
    smfPlayer.allSoundOff();
});</pre><p></p>

<p>各行での処理の内容は以下の通りです。</p>

<ul>
<li>1行目：MIDI OutputのElementのObjectを取得  </li>
<li>2行目：変数outputの初期化  </li>
<li>3〜8行目：MIDI Outputがユーザに選択したObjectの取得、再生制御のボタンの有効化  </li>
<li>9行目：wm-smfplaymerのElementのObjectを取得  </li>
<li>10-19行目：それぞれの再生制御ボタンが押された時の動作</li>
</ul>

<p>以上で、実装完了です。</p>

<h1>おわりに</h1>

<p>今回はWeb MIDI APIをPolymerのElementにしたx-webmidiを使用して、2つのアプリケーションを作りました。そして、第一回目と比べるとコードの量が減るとともに、その多くがJavaScriptによる手続き型の実装ではなく、HTMLによる宣言型の実装になりました。宣言型で書くことで見通しがよく、手軽に実装できるようになります。</p>

<p>ここで「手軽になった」ということは、「アイデアを具現化するまでの道のりが短くなった」ということを示していて、実際に開発を行う際は、考えついたアイデアの実現のみに集中してすることができるようになります。</p>

<p>次回は、MIDIはMusical Instrument Digital Interfaceの略称ではありますが、文字通りの音楽という枠を超えて別の分野でも利用可能、という実例をご紹介しようと思います。</p>

<p>お楽しみに！</p>
]]></content:encoded>
		
		<series:name><![CDATA[MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！]]></series:name>
	</item>
		<item>
		<title>MIDIデバイスの準備不要、Web MIDI APIの基礎</title>
		<link>/ryoyakawai/16787/</link>
		<pubDate>Tue, 13 Oct 2015 02:00:51 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Web MIDI API]]></category>

		<guid isPermaLink="false">/?p=16787</guid>
		<description><![CDATA[連載： MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！ (1)この記事は、Web MIDI APIを題材にした連載の第一回目です。 Web MIDI APIはWebブラウザのAPIですが、Webブ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/webmidi-2015/" class="series-347" title="MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！" data-wpel-link="internal">MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！</a> (1)</div><p>この記事は、Web MIDI APIを題材にした連載の第一回目です。</p>

<p>Web MIDI APIはWebブラウザのAPIですが、Webブラウザの中で完結はしません。Webブラウザと外部のMIDIデバイスとの間でMIDIによる通信を行うためのAPIなのです。Webブラウザと外部デバイスとのやりとりでというとGamepad APIを想像される方もいらっしゃると思いますが、Gamepad APIはGame PadからWebブラウザへの一方通行の通信を行うのに対し、Web MIDI APIはWebブラウザと外部MIDIデバイスとの間で、双方向の通信が可能です。</p>

<p><img src="/wp-content/uploads/2015/08/Screen-Shot-2015-08-27-at-2.55.56-PM.png" alt="Screen Shot 2015-08-27 at 2.55.56 PM" width="60%" class="aligncenter wp-image-16791" srcset="/wp-content/uploads/2015/08/Screen-Shot-2015-08-27-at-2.55.56-PM.png 640w, /wp-content/uploads/2015/08/Screen-Shot-2015-08-27-at-2.55.56-PM-300x130.png 300w, /wp-content/uploads/2015/08/Screen-Shot-2015-08-27-at-2.55.56-PM-207x90.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h1>昔ホームページで鳴っていたやつ</h1>

<p>ところで、<strong>MIDI</strong>ってご存じですか？ MIDIと聞くと、<strong>「昔ホームページで鳴っていたやつ」</strong> を思い出される方が多いと思います。そもそもMIDIとは、「電子楽器の演奏データを機器間でデジタル転送する」ための物理的な回路・インターフェイス、通信プロトコル、ファイルフォーマット等の複数の規格から成り立っている規格の総称です。そして、Web MIDIを語る上で重要になるのが、「MIDIプロトコル」と「物理的な回路・インターフェイス」というキーワードです。</p>

<p>冒頭の<strong>「昔ホームページで鳴っていたやつ」</strong> ですが、あれはMIDIの中のファイルフォーマット（Standard MIDI File）を、OSが持つ音源を使って再生したモノとなります。「つまりどういうこと？」という方もいらっしゃると思いますが、この後、解説する、MIDIプロトコルの説明をご覧いただければ理解できるはずです。</p>

<p>まず最初は「MIDIプロトコル」から解説していきます。</p>

<h1>MIDIプロトコル</h1>

<p>MIDIとは先述した通り、「電子楽器の演奏データを機器間でデジタル転送する」ための規格でした。まず、演奏データ、つまり「音楽」とはどういうモノで成り立っているか、誰もが小学生で触ったであろうリコーダー（縦笛）を例に考えてみまます。</p>

<p>リコーダーは口にくわえて息を吹き込むことで音が出ます。強く吹けば力強い音が出るし、弱く吹けば優しい音が出る、つまり息の強さで <strong>音の強弱が表現</strong> できます。それから、押さえる穴の数を変えれば高い音階の音が鳴ったり、低い音階の音が鳴ったりする、つまり穴の数を変えることで <strong>音程の変化</strong> をさせているのです。これら <strong>音の強弱が表現</strong> 、 <strong>音程の変化</strong> の2つの情報があれば、音を再現できそうですよね。実はMIDIプロトコルで音を鳴らす部分は、この2つの情報を1つのメッセージとして扱うことで「機器間での演奏データの転送」を実現しています。さらに、MIDIには <strong>チャンネル</strong> というものがあり、これを使い分けることで16個の独立したメッセージを扱うことが可能になります。</p>

<p>それでは、実際にMIDIメッセージを見てみましょう。「音を出す」、「音を停止」する場合は、このように16進数でに3バイトを1つのMIDIメッセージとして指定します。</p>

<h3>音を出す(noteOn)</h3>

<p><img src="/wp-content/uploads/2015/08/MIDI_noteOn.png" alt="MIDI_noteOn" width="640" height="77" class="aligncenter size-full wp-image-16903" srcset="/wp-content/uploads/2015/08/MIDI_noteOn.png 640w, /wp-content/uploads/2015/08/MIDI_noteOn-300x36.png 300w, /wp-content/uploads/2015/08/MIDI_noteOn-207x25.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>音を止める(noteOff)</h3>

<p><img src="/wp-content/uploads/2015/08/MIDI_noteOff.png" alt="MIDI_noteOff" width="640" height="77" class="aligncenter size-full wp-image-16904" /></p>

<ul>
 <li><b>チャンネル</b>: 0〜15を16進数で指定</li>
 <li><b>音階</b>： 21(最も低いラ：27.5Hz)〜108(最も高いド：4186Hz)を16進数で指定</li>
 <li><b>音の強さ</b>： 0〜127を16進数で指定（音を停止の場合、機器によって解釈が違う場合もある）</li>
</ul>

<p>MIDIメッセージの特徴の1つは、このように <strong>「何を」</strong> 、 <strong>「どのくらい」</strong>、 <strong>「どうする」</strong> の3つの内容が1組になっているところです。この2つのメッセージが分かれば音が出せるので、早速実装してみましょう。</p>

<h1>Web MIDI APIを使って実装する</h1>

<p><a href="http://webaudio.github.io/web-midi-api/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web MIDI APIの仕様</a>に中で、実装に必要な処理は以下の4つです。</p>

<ol>
 <li>コンピュータに接続されているMIDI Input/Outputの機器を列挙</li>
 <li>利用したい、MIDI機器を選択</li>
 <li>MIDI Input機器からの入力はEventで上がってくるので、EventListenerで処理を書く</li>
 <li>MIDI Output機器にMIDIメッセージを送信する</li>
</ol>

<p>今回は単純に、MIDI Input機器からの出力をブラウザで中継して、MIDI Output機器に送信するプログラムを書いてみたいと思います。まずは<a href="http://ryoyakawai.github.io/x-webmidi/src/hx_webmidi_01.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ライブデモ</a>を御覧ください。
<div id="attachment" style="width: 650px" class="wp-caption aligncenter"><a href="http://ryoyakawai.github.io/x-webmidi/src/hx_webmidi_01.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/09/deviceselect.png" alt="deviceselect" width="480" class="aligncenter size-full wp-image-17203" srcset="/wp-content/uploads/2015/09/deviceselect.png 640w, /wp-content/uploads/2015/09/deviceselect-300x114.png 300w, /wp-content/uploads/2015/09/deviceselect-207x79.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">inputのリストから「PC-Keyboard」をoutputのリストから「GMPlayer(WebMIDILink)」を選択してください。</p></div></p>

<p><div id="attachment_17033" style="width: 650px" class="wp-caption aligncenter"><a href="http://ryoyakawai.github.io/x-webmidi/src/hx_webmidi_01.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/09/livedemo01.png" alt="livedemo01" width="640" height="210" class="aligncenter size-full wp-image-17033" srcset="/wp-content/uploads/2015/09/livedemo01.png 640w, /wp-content/uploads/2015/09/livedemo01-300x98.png 300w, /wp-content/uploads/2015/09/livedemo01-207x68.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">左：inputのリストから「PC-Keyboard」を選択し、横に表示される鍵盤のアイコンをクリックした図、<br />右：outputのリストから「GMPlayer(WebMIDILink)」を選択し、横に表示されるMIDI端子のアイコンをクリックした図</p></div>
「PC-Keyboard」と「GMPlayer(WebMIDILink)」は、MIDI機器がなくても動かせるように、PCのキーボードで鍵盤、また、MIDIメッセージで発音するWeb Audioで作った音源モジュールをPolymerで仮想のデバイスにしています。（「GMPlayer(WebMIDILink)」は<a href="http://twitter.com/g200kg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">@g200kg</a>さんが開発した音源です）</p>

<h3>環境の整備</h3>

<p>今回は、PolymerとPolymerのElement(x-webmidiというElementのExtraのElement)を使いますので、ダウンロードしてきます。</p>

<ul>
 <li> <a href="http://zipper.bowerarchiver.appspot.com/archive?polymer=Polymer/polymer%231.0.0" target="blank" data-wpel-link="external" rel="follow external noopener noreferrer">Polymer</a></li>
 <li><a href="https://github.com/ryoyakawai/x-webmidi/archive/0.10.23.zip" target="blank" data-wpel-link="external" rel="follow external noopener noreferrer">x-webmidi</a></li>
</ul>

<p>例えば、 <strong>hx_webmidi_01</strong> ディレクトリを作成して、その下に <strong>bower_components</strong> ディレクトリを作成し、リンクからダウンロードしたファイルを保存してください。(x-webmidiは解凍するとファイル名にバージョン番号が付いてしまいますので削除してください)<br />
そして、これからコードを追加していく <strong>index.html</strong> を作成します。</p>

<p><img src="/wp-content/uploads/2015/10/xwebmidi-directory-01.png" alt="directory_structure" width="300" class="aligncenter size-medium wp-image-17012" /></p>

<p>以上で環境整備は完了です。</p>

<h3>Polymerのコードを実装</h3>

<p>では、次に実装するコードを見てみましょう。今回作成する index.html のコード全体は<a href="https://github.com/ryoyakawai/x-webmidi/blob/gh-pages/src/hx_webmidi_01.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>になります。早速、HTML部分を上から説明していきます。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="bower_components/webcomponentsjs/webcomponents.js"&gt;&lt;/script&gt;
&lt;link rel="import" href="bower_components/polymer/polymer.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-webmidilink/wm-webmidilink.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-pckeyboard/wm-pckeyboard.html"&gt;

&lt;wm-webmidilink id="wmlink"&gt;&lt;/wm-webmidilink&gt;
&lt;wm-pckeyboard id="pckeyboard"&gt;&lt;/wm-pckeyboard&gt;

input: &lt;select id="midi-input"&gt;&lt;option&gt;SelectOne&lt;/option&gt;&lt;/select&gt;&lt;span id="virtual-input"&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;
output: &lt;select id="midi-output"&gt;&lt;option&gt;SelectOne&lt;/option&gt;&lt;/select&gt;&lt;span id="virtual-output"&gt;&lt;/span&gt;&lt;br&gt;
&lt;br&gt;

&lt;div id="msg" style="margin:30px;"&gt;&lt;/div&gt;</pre><p></p>

<p>Web MIDI APIで列挙したMIDIデバイスを選択するためのSelectタグを書いておきます（9行目、10行目）。また、MIDI Inputデバイスから受けたMIDIメッセージを表示するエリアもつけています(12行目)。尚、今回は、MIDIデバイスがなくても楽しめるようにPolymerを使っています（1行目から7行目）が、ここでは深く触れません。Selectタグの直後の&lt;span&gt;&lt;/span&gt;も同様にPolymerに関連する記載のためここでは触れません。</p>

<h3>MIDIデバイスの列挙</h3>

<p>続いてWeb MIDI APIを使った実際の処理の説明です。
</p><pre class="crayon-plain-tag">navigator.requestMIDIAccess({sysex:false}).then(successCallback, errorCallback);
function successCallback(access) {
  (後ほど詳しく)
}
function errorCallback(msg) {
  console.log("[ERROR] ", msg);
}</pre><p> 
requestMIDIAccessはPromiseの形になっていますので、まずは「システムエクスクルーシブ(sysex)」を使用するか・使用しないかを設定し、実行します。成功すればsuccessCallbackへ、失敗すればerrorCallbackへと処理が遷移します。ここで「システムエクスクルーシブ」とはMIDIメッセージの1つで、電子楽器機器固有の機能を制御するために使われます。電子楽器内のデータのバックアップで使うことも多いため、Web MIDI APIではセキュリティの観点から、ユーザの許可（ダイアログを表示）を得ることが利用する条件となっています。</p>

<p>Promiseが成功し、successCallbackへ遷移した場合の説明です。</p>

<p></p><pre class="crayon-plain-tag">// MIDI Inputデバイスの配列を作成
var inputIterator = access.inputs.values();
for (var o = inputIterator.next(); !o.done; o = inputIterator.next()) {
    midi.inputs.push(o.value);
}
// 仮想のMIDI Inputデバイスを追加
midi.inputs.push((document.querySelector("#pckeyboard")).getInput());

// MIDI Outputデバイスの配列を作成
var outputIterator = access.outputs.values();
for (var o = outputIterator.next(); !o.done; o = outputIterator.next()) {
    midi.outputs.push(o.value);
}
// 仮想のMIDI Outputデバイスを追加
midi.outputs.push((document.querySelector("#wmlink")).getOutput());</pre><p> 
Prmiseが成功すると、コンピュータに接続されているMIDIデバイスの情報を引数で渡されます。MIDI Inputデバイスの場合access.outputs.values() 、MIDI Output デバイスの場合はaccess.outputs.values()を実行することで、それぞれのデバイスのリストをIteratorの形で取得できます。ここでは機器情報の配列 midi.inputs、midi.outputsを作成します。最後に仮想のデバイスを取得して追加しています。</p>

<h3>MIDI Outputデバイスのリスト表示と選択時の処理</h3>

<p></p><pre class="crayon-plain-tag">// MIDI Outputデバイスのリスト表示と選択時の処理
var osel=document.querySelector("#midi-output");                                                                                            
for(var i=0; i&lt;midi.outputs.length; i++) {                                                                                                  
    osel.appendChild((new Option(midi.outputs[i]["name"], i)));                                                                             
}
osel.addEventListener("change", function(event){
    outputSelIdx=event.target.value;                                                                                                        
    // 仮想のMIDI Outputデバイスが選択された時の処理
    if(parseInt(outputSelIdx)&gt;=0 &amp;&amp; midi.outputs[outputSelIdx].virtual==true) {
        document.querySelector("#virtual-output").appendChild(document.querySelector("#wmlink").getElement());                              
    } else {
        document.querySelector("#virtual-output").innerHTML=""
    }
});</pre><p> 
先ほど作成したMIDI Inputデバイスの配列の要素を、リストとして表示するためにselectタグにoptionとして追加します。（2行目〜5行目）
リストの選択の変化に対してEventListenerを設定します。（6行目～14行目）ここで行っているのは、選択された機器に割り振られたIDを記憶（7行目）、続いて、もし仮想デバイスの場合はリストの横にアイコンを追加（9行目～13行目）を行っています。</p>

<h3>MIDI Inputデバイスのリスト表示と選択時の処理</h3>

<p></p><pre class="crayon-plain-tag">// MIDI Inputデバイスのリスト表示と選択時の処理
var isel=document.querySelector("#midi-input");                                                                                             
for(var i=0; i&lt;midi.inputs.length; i++) {                                                                                                   
    isel.appendChild(new Option(midi.inputs[i]["name"], i));                                                                                
}
isel.addEventListener("change", function(event){
    if(inputSelIdx!=null) {
        midi.inputs[inputSelIdx].onmidimessage=null;                                                                                        
    }
    inputSelIdx=event.target.value;                                                                                                         
    midi.inputs[event.target.value].onmidimessage=eventOut;                                                                                 
    // 仮想のMIDI Inputデバイスが選択された時の処理
    if(parseInt(inputSelIdx)&gt;=0 &amp;&amp; midi.inputs[inputSelIdx].virtual==true) {
        document.querySelector("#virtual-input").appendChild(document.querySelector("#pckeyboard").getElement());                           
    } else {
        document.querySelector("#virtual-input").innerHTML=""
    }
});</pre><p> 
先ほど作成したMIDI Inputデバイスの配列の要素をリストとして表示するために、selectタグにoptionとして追加します。（2行目～5行目）リストの選択の変化に対してEventListenerを設定します。（6行目〜18行目）ここで行っているのは、選択された機器に割り振られたIDを記憶（10行目）、MIDI Inputデバイスからの入力を受ける為の関数をonmidimessageに指定(7行目〜11行目)、もし既MIDI Inputデバイスからの入力を受ける機器が指定されていたらonmidimessageも解除（7行目〜9行目）、続いて、もし仮想デバイスの場合はリストの横にアイコンを追加（8行目～12行目）を行っています。</p>

<h3>MIDI Inputデバイスからの入力を受けた時の処理</h3>

<p>ここでは、MIDI Inputデバイスから取得したMIDIメッセージを、もしMIDI Outputデバイスが指定されていたら加工はせずにそのまま送信しますので、以下のようになります（7行目～9行目）。MIDI InputからのMIDIメッセージはevent.dataで取得することが可能で、MIDIメッセージは画面表示します（4行目、5行目）。
</p><pre class="crayon-plain-tag">function eventOut(event) {
// MIDIメッセージを表示
for(var i=0, out=[]; i&lt;event.data.length; i++) out.push((&quot;00&quot;+event.data[i].toString(16)).substr(-2));
    var div_msg=document.getElementById(&quot;msg&quot;);
    var ex_msg=div_msg.innerHTML.split(&quot;<br>");
    while(ex_msg.length&gt;19) ex_msg.pop();
    div_msg.innerHTML=out.join(" ")+"<br>" + ex_msg.join("<br>");

    if(parseInt(outputSelIdx)&gt;=0) {
        midi.outputs[outputSelIdx].send(event.data);
    }
}</pre><p></p>

<p>以上で、接続されたMIDI Inputデバイスから、指定したMIDI Outputデバイスへメッセージを送信するWebアプリケーションが作成されました。PCのキーボードで演奏ができるようになったはずです。</p>

<p>もし電子ピアノ等の電子楽器をお手持ちの場合はUSB端子がついてないかご確認ください。そして、もしUSBで接続可能であれば接続し、作成したWebアプリをリロードしてみてください。inputもしくはoutputのどちらかに接続したデバイスがリストされるはずです。（ポケットミク、eVY1シールドも操作できます）</p>

<p>また、MIDIメッセージは単なるメッセージですので、音以外に割り当てたり、鍵盤に複数のMIDIメッセージを割り当ててフレーズを再生する等、アイデア次第で様々なモノのコントローラとして活用することができます。今回は、花火をモチーフに（季節外れですが…）こんな<a href="http://ryoyakawai.github.io/x-webmidi/src/fireworks.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">アプリケーション</a>を作ってみました。鍵盤を弾くと、音とともに花火の打ち上がります。この音はもちろんMIDIメッセージで音源モジュールを鳴らしています。</p>

<p><a href="http://ryoyakawai.github.io/x-webmidi/src/fireworks.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/09/fireworks-640x432.png" alt="fireworks" width="640" height="432" class="aligncenter size-large wp-image-17216" srcset="/wp-content/uploads/2015/09/fireworks.png 640w, /wp-content/uploads/2015/09/fireworks-300x203.png 300w, /wp-content/uploads/2015/09/fireworks-207x140.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h3>おわりに</h3>

<p>いかがでしたでしょうか？Web MIDIはそんなに難しくない、いやむしろ簡単であることをお分かりいただけたと思います。普段Webの開発をしていると「外部デバイスと接続して何かをする」という発想はなかったかもしれませんが、Web MIDIを使うとそういった実装もWebだけでできるようになります。「何かを作る」場合に選択の1つに是非Web MIDIを加えてみてください。</p>

<p>さて、今回は「MIDIとは何か？」というところから「Web MIDI APIの実装」、そして「MIDIを別の用途に応用してみる」というところを紹介してきました。しかし「難しくはないけど、少し準備が長い」と感じたりしていませんか？</p>

<p>実はWeb MIDIにはHotPlugの機能もありますが、今回の実装ではそこまで紹介しきれていないのです。そこで次回は、今回の記事にも少し登場した、Web MIDIと仮想デバイスの実装が一瞬でできてしまうx-webmidiというPolymerのElementについて、さらに具体的に紹介する予定です。</p>

<p>お楽しみに！</p>
]]></content:encoded>
		
		<series:name><![CDATA[MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！]]></series:name>
	</item>
	</channel>
</rss>
