にゃみかんてっくろぐ

猫か百合を見守る壁になりたい

Raspberry PiでNHKラジオ第一の緊急地震速報を検出する

P2P地震情報では,NHKラジオ第一の放送から緊急地震速報の発表を検出しています. 今回,その検出をPCではなくRaspberry Piで行うように変更しました.そのときの記録です.

前提: 自動音声による放送

NHKラジオ第一では,緊急地震速報(警報)が発表されると,通常の放送を中断して緊急地震速報の放送が入ります.

放送の内容は下記の通り.事前に収録した音声で自動的に放送されているようです.

(チャイム音)
緊急地震速報です.(震源名)で地震.次の地域は,強い揺れに警戒してください.(地域名)

緊急地震速報です(以下繰り返しの後,該当地域の方々への注意喚起など)

「発表されたこと」だけを検出する場合,冒頭の音声をパターンマッチするだけで実現が出来ます.これをやります.

材料

Raspberry Piによる録音

アダプタを接続するだけです.

$ lsusb
Bus 001 Device 002: ID 0d8c:013c C-Media Electronics, Inc. CM108 Audio Controller
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ arecord -l
**** ハードウェアデバイス CAPTURE のリスト ****
カード 1: Device [USB PnP Sound Device], デバイス 0: USB Audio [USB Audio]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0

$ arecord -L
(省略)
plughw:CARD=Device,DEV=0
    USB PnP Sound Device, USB Audio
    Hardware device with all software conversions

$ arecord -D plughw:1,0 test.wav
録音中 WAVE 'test.wav' : Unsigned 8 bit, レート 8000 Hz, モノラル

Python3による音声のパターンマッチ

GitHubにソース公開しています.見せるように作っていないのでかなり汚いです.

github.com

技術的なポイントはこのへん.

  • 音声波形そのままではなく,FFT変換した周波数スペクトルでパターンマッチング
  • FFT変換はNumPyライブラリで実施(お手軽)
  • 精度(しきい値)は人力で調整.といっても大した手間ではない

緊急地震速報の検出のためのポイントはこのへん.

  • 検出負荷を下げるために正解データは短く
    • チャイム音は2回繰り返すうち1回分
    • 自動音声は冒頭の「緊急地」のみ
  • 必ずチャイム音と音声をセットで検出(過去,チャイム音を用いた啓蒙放送等があったため)

※正解データは著作権の関係で公開できません.

実行

arecordの標準出力をPythonスクリプトの標準入力に食わせます.

$ arecord -D plughw:1,0 -t raw | python3 fft_analyze.py

f:id:no_clock:20190203233109p:plain

過去の放送音声を流してみたところ,正しく認識されました.CPU使用率は約20%,良い感じです.

(失敗)pyaudioで録音&パターンマッチ

そもそもpyaudioライブラリを使えば,Pythonで完結させることが出来ます.しかし,失敗しました.

f:id:no_clock:20190203235500p:plain

Input overflowedの表示の通り,録音データをリアルタイムに処理出来ていません.

arecordでは8000Hz, 1ch, 8bitという低いデータレートで録音していましたが,これはarecord内部でリサンプリングされたものでした.一方,pyaudioにはそうした機能はありません.デバイスが対応する44100Hz, 1ch, 16bitという高いデータレートで録音するしかなく,リアルタイムに扱うには厳しい量でした.

その結果,arecordの標準出力から食わせる,という方法に落ち着きました.

参考