2021年07月29日 更新

BLEデータに応じて音声出力!

どうも、クラゲです。
今回は、BLEデバイスからNotifyで読み込んだデータに応じて音声出力を出す方法を紹介します。例えば、センサー値が、ある閾値を超えたら警告音を鳴らすなどの応用に使えます。

動画の音声はONにして見てください。今回はmicro:bitを回転することで変化する角度の値を代用しています。閾値は90付近、つまり90°です。

【 必要なもの 】

Scan と同様

【 micro:bitの準備 】

Scan と同様

micro:bitが手元にない人は、HTML側のUUIDと受信データフォーマットを変更すれば、他のBLEデバイスでも対応可能です

【 デモページとソースコード 】

WEB上で試せるデモページはこちら
BlueJelly Sample : Sound

ローカル環境で試したい方はこちらのGitHubからダウンロードし、advance_sound.htmlを開いて実行してください。

【 プログラム解説(HTML) 】

プログラムのベースは Notify です。
では、音声出力追加部分について見てゆきましょう。

事前準備として音声ファイルを用意しています。「効果音」「素材」で検索するとたくさんサイトが見つかりますし、もちろん自分で録音して作ってもOKです。
今回はこちらの「ロボット合体3 衝撃弱め」を使用しました。
http://soundeffect-lab.info/sound/machine/

音声ファイル再生にはaudioタグを利用します。
まずHTMLにて以下のようにAUIDOタグを記述します。
preloadをautoにすることで音声ファイルを事前読み込みできます。

<!-- 音声ファイルの読み込み -->
<audio id="sound-file" preload="auto">
<source src="./union3.mp3" type="audio/mp3">
</audio>

【 プログラム解説(JavaScript) 】

超シンプルに「データが90以上になったら、PCで音声ファイルを繰り返し再生する」という場合は、Read後の処理部に以下の記述のみでOKです。

if(value >= 90)
  document.getElementById("sound-file").play();

しかしクラゲは、もう少し実用的な使い方を行うために、以下の4つの工夫を追加しています。

  • 変化時のみ再生対応
    このままだと、90以上でずっと繰り返し再生されてしまうので、90以上になった変化時のみ再生ささせるようにしました。 具体的には音声再生許可フラグを設けて制御しています。

  • バラツキ変動対応
    閾値が90だけだと、その付近でバラツキやノイズ変動が起きた場合に、意図しない変化の繰り返しが起きてしまう可能性があるため、ちょっぴりヒステリシス幅を設けています。

  • 割り込み再生対応
    割り込み再生したい場合、再生中に頭に戻って再生させる必要があります。 例えば「おはよう」という音声ファイルがあったとき、「おはよう おはよう」と再生させるのではなく、「お、おはよう」と再生させる工夫です。

  • スマホ再生対応
    このままだとスマホやタブレットでは再生されません。スマホやタブレットで音声出力させるための工夫を盛り込んでいます。

それでは見てゆきましょう。

Global変数宣言の部分に、音声再生許可フラグを追加しました。初期値はtrueとしました。

//(変化時のみ再生対応)音声再生許可フラグ
var flag_playOK = true;

Read後の処理の部分に、音声再生を加えています
閾値は90とし、それを超えたら音声ファイルを再生します。ただし再生できる条件として音声再生許可フラグがtrueのときのみです。再生したらfalseにします。また、再生前には必ず音声を巻き戻します。 もう一つの閾値を設け60としています。60以下になったら音声再生許可フラグをtrueにします。

  //BLEデータ値に応じて音声出力
  if(value >= 90)
  {
    //(変化時のみ再生対応)音声再生許可が有効のときのみ再生
    if(flag_playOK == true)
    {
      //(割り込み再生対応)音声ファイルを巻き戻し
      document.getElementById("sound-file").currentTime = 0;

      //音声ファイル再生
      document.getElementById("sound-file").play();

      //(変化時のみ再生対応)音声再生許可を無効にする
      flag_playOK = false;
    }
  }
  //(バラツキ変動対応)音声再生許可の有効と無効の閾値に差を設ける
  else if(value <= 60)
  {
    //(変化時のみ再生対応)音声再生許可を有効にする
    flag_playOK = true;
  }

PCの場合は、ここまでの変更でOKですが、スマホの場合はaudioタグでpreloadautoにしても、実はロードされません。
そこで、javascriptで強制的にロードする必要があります。その時の注意点として、ユーザー操作を伴う動作に連動させる必要があります。つまり、window.onloadに記述してもダメです。今回はStart Notifyボタンを押したときにロードさせるようにしました。
ちなみにこの順番も重要で、ble.startNotifyの後に書いた場合はボタンを2度押さないと上手くいきませんでした。

document.getElementById('startNotifications').addEventListener('click', function() {

  //(スマホ再生対応) ユーザー操作時に音声ファイルをロード
  document.getElementById("sound-file").load();

  ble.startNotify('UUID1');
});

いかがでしょうか?
今回は傾き角度でしたが、センサー値などに変更すれば、ぐっと実用度が上がると思います!

以上、BLEデータに応じて音声出力でした。