エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

Web Bluetooth API と Bluetooth MIDI を使って子供向けの音符学習アプリを作る

エムスリー エンジニアリングGの岩本です。

会社ではiOS開発からサーバサイドの開発を担当していますが、家でDIY・IoT・スマホアプリなどを作るパパエンジニアやっています。 最近小学生になった娘がピアノに興味を持ち始めました。といっても習い事にするまでの興味はないようですが、楽しそうに猫ふんじゃったを弾いています。ところがドレミの音符もわかっていません。今回は子供に音符を教えるためといって買ったワイヤレスMIDIアダプター MD-BT01を使って、Chromeと通信してかんたんな音符を学習する子供向けのアプリを作ってみました。

なお、エムスリーテックブログのものづくり系の記事が増えてきたのでこちらもよろしければ参照ください。

作ったもの

まずは作ったものを御覧ください。

www.youtube.com

仕組み

f:id:cpw:20210929222041p:plain

まず家に眠っていた電子ピアノにはMIDIインタフェースだけがあったので、購入したワイヤレスMIDIアダプター MD-BT01を利用してBluetoothでつながるようにしました。あとはブラウザに備わっているWeb Bluetooth APIを使って電子ピアノと接続します。

押された鍵盤の判定

鍵盤を押したり離したりすると、下記のようなイベントを取得できます。

[136, 156, 144, 60, 72] // 鍵盤を押したときのイベント
[137, 162, 128, 60, 64] // 鍵盤を離したときのイベント

今回作ったアプリでは上記のイベントから下記の3つの情報を抽出する必要があります。

  1. 押されたこと
  2. どの音が押されたか
  3. 押された音が何オクターブ目か

押されたことについては5バイト目を見れば良さそうです。 10進数で64のときは鍵盤を離したときのイベントで、逆に押されたときは押したときの強弱を数値で表しているようです。

また、4バイト目はどの鍵盤が押されたかを示しています。0のときが一番低いドの音でそこから1上がるごとに半音ずつ上がっていきます。 つまり、黒鍵も合わせると1オクターブで12個の音があるので、どの音が押されたかはvalue % 12で、 どの高さの音が押されたかは Math.floor(value / 12)で求められます。

これで必要な情報が揃いました。

注意:なお、実際に鍵盤を押してみて実際のデータから推測しているので、本気で使うときはBluetooth MIDIの仕様を調べてください。

スコアの表示

ABC譜記法をsvgにして表示してくれるabcjsというものがあったのでこれを利用しました。使い方は簡単で下記のようにすれば

ABCJS.renderAbc(scoreEl, `
X: 1
M: 4/4
L: 1/4 
K: C
CEGC^|`);

下記のsvgを生成して表示してくれます。

f:id:cpw:20210929225953p:plain

次に押す音符は赤くしたいのですが、良いAPIを見つけることができなったため泥臭い実装になっています。 pathオブジェクトを探してcssで色を付けています。

    // this.visualObjectはABCJS.renderABC()の戻り値
    const voices = this.visualObject.lines[0].staff[0].voices[0];
    // reset color
    for (let i = 0; i < voices.length; i++) {
      const elemset = voices[i].abselem.elemset;
      for (let i = 0; i < elemset.length; i++) {
        elemset[i][0].classList.remove("current");
      }
    }
    // coloring
    const elemset = voices[coloredIndex].abselem.elemset;
    for (let i = 0; i < elemset.length; i++) {
      elemset[i][0].classList.add("current");
    }

f:id:cpw:20210929231156p:plain

あとは、正解の鍵盤が押されたら次の音に進めばゲームとして成立します。

まとめ

  • MIDIインタフェースはBluetooth化可能
  • ChromeでWeb Bluetoothを使えば電子ピアノにも接続可能
  • 楽譜をレンダリングするライブラリabcjsは便利

これで娘が楽譜が読めるようになって、習い事にまで発展してくれればいいのですがここから先はエンジニアリングとは全く違うのでもどかしいですね。

なお、今回作ったものはGithubに登録していますので興味があれば参照してください。

github.com

We are hiring!

エムスリーでは好奇心旺盛で技術が好きなエンジニアを絶賛募集中です。少しでも興味を持っていだたけら以下のリンクよりカジュアル面談にぜひご応募ください。

jobs.m3.com