「本当に世の中の電子音はご年配の方には聞きづらい！」に対処してみる

# はじめに

糸井重里さんが書かれていました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">年寄りは「体温計」のお知らせ音が聞こえないのですじゃ。わしのような老人たちにも音の聞こえる体温計を発売してくれんかのう。</p>&mdash; 糸井 重里 (@itoi_shigesato) <a href="https://twitter.com/itoi_shigesato/status/638546851671609344?ref_src=twsrc%5Etfw">September 1, 2015</a></blockquote>

調べてみると、年齢とともに高い周波数は聞こえなくなってくるそうで、電話の呼出音や体温計の通知音などは聞こえにくくなるとのこと。

ドアホンのチャイム、電子レンジのチン、冷蔵庫の閉め忘れ音、火災警報器...、日常生活における様々な電子音で「聞こえにくい」って起きているのかも。これからの社会に「電子音の聞こえの補助」って必要なんじゃないかな。

プログラムで人の言葉が認識できる時代なのだから、電子音の認識だってきっとできるはず。やってみよう。

# やりたいこと

- マイクで拾っている周囲の音から、ドアホンのチャイム、電話の呼出音を認識する。
- 認識内容に応じて...、とりあえず旗を振ってお知らせする。

# どうなったか

※ドアホンのチャイムと電話の呼出音が鳴りますのでご注意ください
[![movie.png](https://qiita-image-store.s3.amazonaws.com/0/60193/8e689d49-f438-add6-4004-acee84928c07.png
)](https://drive.google.com/open?id=1NXpMF8BCLvT-Je519xQXuCoYNyomxipv)
※動画が始まらない場合は[こちら](https://drive.google.com/open?id=1NXpMF8BCLvT-Je519xQXuCoYNyomxipv)から... :confounded:

周囲の音は右側のPCのマイクで拾ってます。

# どうやったか

流行の機械学習の出番かと思いましたが、電子音は再現性があるので、そこまでしなくてもいけそうな気がします。もしかして既に...、と探してみたら、なんとありました。[Picognizer: 電子音の検出および認識のためのJavaScriptライブラリ](http://www.unryu.org/home/picognizer) [^1]。もう、そのものすぎて、逆に驚きました。ありがたく利用させていただきます。

[^1]: ご提供者は[SpeechJammer](http://www.unryu.org/home/speechjammer)でイグノーベル賞を受賞されたあの方でした。なんと。

## 電子音の認識

[beefy](https://github.com/chrisdickinson/beefy)で動かすNode.jsサンプル[node_beefy_example.js](https://github.com/qurihara/picognizer/blob/gh-pages/node_beefy_example.js)を公開いただいていたので、こちらをベースに実装していきました。

```js:node_beefy_example.js
var audiofile = ['./sounds/chime.mp3', './sounds/phone.mp3']; // 音源
var threshold = [30, 55]; // しきい値
var triggered = (new Array(audiofile.length)).fill(false);

var option = {
  mode: 'direct',
  framesec: 0.05,
  duration: 0.5
};

var picognizer = new Pico();
picognizer.init(option);
picognizer.oncost(audiofile, function(cost) {
  for (var index = 0; index < cost.length; ++index) {
    if (cost[index] < threshold[index]) {
      if (!triggered[index]) {
        fire(index); // イベント発火
        triggered[index] = true;
      }
    }
    else {
      triggered[index] = false;
    }
  }
});
```

認識対象のドアホンのチャイム、電話の呼出音を録音してchime.mp3、phone.mp3として入力しました。しきい値は実際に動作させて決定しました。しきい値を下回る（対象を検出する）と、後述するfire関数が呼び出されます。

## 旗を振ってお知らせ

fire関数内の旗振りは[obniz](https://obniz.io/)で。[公式制作例](https://obniz.io/explore)より、[ハッシュタグ#obnizのツイートで動く旗](https://obniz.io/explore/1)を参考にしました。

```js:node_beefy_example.js
var obniz = new Obniz('OBNIZ_ID_HERE'); // obniz id
var servos;
obniz.onconnect = async function() {
  servos= [obniz.wired('ServoMotor', {signal: 0,vcc: 1, gnd: 2}),
           obniz.wired('ServoMotor', {signal: 3,vcc: 4, gnd: 5})];
  servos[0].angle(75);
  servos[1].angle(75);
};

fire = function(index) {
  var count = 0;
  var angles = [125, 75, 125, 75, 125, 75];
  var timer = setInterval(function() {
    var angle = angles[count++];
    servos[index].angle(angle);
    if (count >= angles.length) {
      clearInterval(timer);
    }
  }, 450);

  // ブラウザの背景色を変更
  document.bgColor = ['red', 'blue'][index];
  setTimeout(function() {
    document.bgColor = 'white';
  }, 1000);

  console.log('recognized: ' + ['chime', 'phone'][index]);
}
```

デバッグ目的でブラウザの背景色も変更しました。

## Firefoxで実行

以上のスクリプトに対して

```
$ beefy node_beefy_example.js --live
```

として、Firefoxで実行しました。

# おわりに

「聞こえの補助」に関する既存の製品は有線が多いのかな、検出対象が多いと取り付けるの大変かな、というのも、やってみようと思ったモチベーションのひとつでした。

認識結果をSlackなどへ通知すれば、留守宅の様子の一元管理、なんてこともできそうです。「聞こえの補助」以外にも活用方法が色々ありそうな気がしています。

そうか、帰宅時に留守電がペカペカしていることに気付かず数日放置しちゃう問題が解決できるのか...。