PocketSphinxとは
PocketSphinxは連続音声認識を行う音声認識エンジンです。
英語しか対応していないので、日本語には向かないようです。
(強引に対応させる手があるようですが、話が脱線するので割愛します。。。)
実行環境
今回は以下の環境で動作確認を行いました。
- Windows10
- Anaconda(Python 3.7.9)
パッケージインストール
pip install pocketsphinx
で終わり、とはならないです。。。
PocketSphinxをインストールするには、swigとBuild Tool(C++)が必要になります。
swigはこちらを参考にインストールできました。
Build Toolはこちらからダウンロードできます。
準備ができたら、pipでPocketSphinxをインストールします。
pip install pocketsphinx
サンプルコード実行
PocketSphinxのサンプルコードは以下のようになっています。
この通り実行すると、英単語を検知してくれます。
import os
from pocketsphinx import LiveSpeech, get_model_path
model_path = get_model_path()
speech = LiveSpeech(
verbose=False,
sampling_rate=16000,
buffer_size=2048,
no_search=False,
full_utt=False,
hmm=os.path.join(model_path, 'en-us'),
lm=os.path.join(model_path, 'en-us.lm.bin'),
dic=os.path.join(model_path, 'cmudict-en-us.dict')
)
for phrase in speech:
print(phrase)
LiveSpeechのデフォルト値は以下のようになっているそうです。
verbose = False
logfn = /dev/null or nul
audio_file = site-packages/pocketsphinx/data/goforward.raw
audio_device = None
sampling_rate = 16000
buffer_size = 2048
no_search = False
full_utt = False
hmm = site-packages/pocketsphinx/model/en-us
lm = site-packages/pocketsphinx/model/en-us.lm.bin
dict = site-packages/pocketsphinx/model/cmudict-en-us.dict
参照先ディレクトリの理解
PocketSphinxでは、このようなエラーが出る事象が発生しました。
この事象の原因を整理していきます。
RuntimeError: new_Decoder returned -1
hmm / lm / dictで使用しているmodel_path
は以下のように設定しています。
model_path = get_model_path()
このパスをprintしてみるとこのようになります。
C:\Users\<UserName>\.conda\envs\pocketsphinx\lib\site-packages\pocketsphinx\model
(pocketsphinx) C:\Users\<UserName>\.conda\envs\pocketsphinx\Lib\site-packages\pocketsphinx\model>tree /f
C:.
│ cmudict-en-us.dict
│ en-us.lm.bin
│
└─en-us
feat.params
mdef
means
noisedict
README
sendump
transition_matrices
variances
どうやら、pipでインストールしたパッケージの中にデフォルトの辞書データ諸々が含まれているようです。
このパスが間違っているとRuntimeError
が発生するようです。
余談
このエラーの話は検索すると情報があるのですが、わざわざen-usをダウンロードするように書かれていたり、
そもそも、エラーが回避できていないコードがあったりしました。
(極めつけは、そもそもPythonとして、パスの置換に失敗しているコードも出てきました。。。)
当初、自分もパスの確認を怠ったのもあり、ますます謎が深くなった事象でした。
自作辞書データの適用
今回はこのようなディレクトリ構成になっています。
model\sample.dict
が自作辞書データです。
(pocketsphinx) C:\Users\<UserName>\Documents\pocketsphinx_sample>tree /f
C:.
│ exmaple.py
└─model
sample.dict
次に、LiveSpeechの引数を見ると、以下の引数を設定すればよさそうです。
lmについては、False
を設定する方法もドキュメントに記載されていますが、何故かRuntimeErrorになるので、対象としています。
hmm=os.path.join(model_path, 'en-us'),
lm=os.path.join(model_path, 'en-us.lm.bin'),
dic=os.path.join(model_path, 'cmudict-en-us.dict')
import os
from pocketsphinx import LiveSpeech, get_model_path
model_path = get_model_path()
my_model_path = 'C:\\Users\\<UserName>\\Documents\\pocketsphinx_sample\\model'
speech = LiveSpeech(
hmm=os.path.join(model_path, 'en-us'),
lm=os.path.join(model_path, 'en-us.lm.bin'),
dic=os.path.join(my_model_path, 'sample.dict'),
)
for phrase in speech:
print(phrase)
残った疑問点
自分の目的としては辞書データを読み込んでくれればよいので、これで目的は達成できました。
しかし、lm=False
でエラーになる原因が不明な状態なままです。
また、gram(文法ファイル)を読み込ませるjsgf
という引数を書いているサンプルコードも見られましたが、
PocketSphinxのGithubでコードを確認しても、そのような引数はなさそうでした。
文法ファイルの読み込み方も今後必要になれば確認が必要です。
参考
http://rinatz.github.io/swigdoc/install.html
https://pypi.org/project/pocketsphinx/
https://visualstudio.microsoft.com/ja/thank-you-downloading-visual-studio/?sku=BuildTools
https://stackoverflow.com/questions/44339312/new-decoder-returned-1-when-trying-to-run-pocketsphinx-on-raspberry-pi/51346264#51346264