[mbedbot] 取り込んだ音声をGoogle Speech APIで認識させてみた

February 19, 2017

前回までの記事で述べた通り、PCにBLEで送った音声は1,600Hzでサンプリングし、ADPCMで16bitのサンプルデータを3bitに圧縮しています。送られてきた音声データの保存の実装はHubotのアダプタ内で行いました。

  audioRead: (data, isNotification) ->
    self = @
    if isNotification
      s = data.toString 'UTF-8'
      if s == 'TOP_OF_VOICE________'
        console.log 'Start to get voice'
        @abuf = new Buffer(0)
      else if s == 'END_OF_VOICE________'
        console.log 'Finished to get voice'   
        fs.open '/mydisk/share/test.pcm', 'w', '0644', (err, fd) ->
          if err
            console.log err
          else
            fs.write fd, self.abuf, 0, self.abuf.length, null, (err, written, buffer) ->
              if err
                console.log err
      else
        @abuf = Buffer.concat [@abuf, data]

 

このファイルを更にADPCMのデコード(Sun Microsystemsのソースを使用)、soxというフリーウェアでPCMからWAVに変換(周波数は16KHz、音量も正規化)して聞いたところ、思った通りかなり品質は悪く、とても聞き取りにくいものでした。何となく口を塞いだまま喋ってる感じです。高調波成分がほとんどカットされており、子音が聞き取れないです。

試しに、上記の音声をGoogleのGoogle Speech APIで認識させてみましたが、全くダメでした(補足:2017/2/19現在、このAPIは60分まで無料、それ以降は15秒ごとに$0.006かかるそうです)。ノイズに強くて認識率の高い、と言ってもやっぱりここまで品質が悪いと無理みたいですね・・。

ちなみに、このAPIはwavファイルをそのまま送ってもダメで、base64形式(改行は取り除く)で送らないといけないみたいです。ADPCMデコードからBase64形式への変換までの一連の処理は下記のようなScriptで行いました(decodeはSunのADPCMコーデックのソースに含まれています)。

#!/bin/sh

./decode < /mydisk/share/test.pcm > out.pcm
sox -r 1600 -c 1 -b 16 -e signed-integer -t raw out.pcm /mydisk/share/out.wav rate 16k norm
base64 /mydisk/share/out.wav | tr -d '\n' > /mydisk/share/out.b64

また、GoogleのAPIは「https://speech.googleapis.com/v1beta1/speech:syncrecognize?&key=APIキー」に下記のようなJSONをPOSTするだけでいけました。5秒の音声を送ってから認識結果が返ってくるまで、大体5.5秒程度かかりました。

{
  "config":{
    "encoding":"LINEAR16",
    "sampleRate":16000,
    "languageCode":"ja-JP"
  },
  "audio":{
    "content":"BASE64に変換したWAVデータ(16kHz,16bitPCM)"
  }
}