espeak
オープンソース、多言語対応の音声合成エンジン。 日本語には未対応。
ライセンスは GNU General Public License V3
http://espeak.sourceforge.net/
Ubuntu Linux には espeak パッケージが存在する。
NVDAにおけるespeak
ここではnvdajpのための技術調査について書く。
synthDrivers/_espeak.py が espeak DLL のラッパーである。
initialize() にて ctypes による DLL のロードが行われる。
espeakDLL.espeak_SetSynthCallback() でコールバックをセットする。
このコールバック関数は python で実装されている。
DLL側の仕様を確認すると
http://espeak.sourceforge.net/speak_lib.h
typedef int (t_espeak_callback)(short*, int, espeak_EVENT*);
void espeak_SetSynthCallback(t_espeak_callback* SynthCallback);
音声合成エンジン(espeak)は SynthCallback という関数ポインタを受け取り、 波形をある長さ生成したらこの関数を呼び出す。
コールバックを見てみる。
t_espeak_callback=CFUNCTYPE(c_int,POINTER(c_short),c_int,POINTER(espeak_EVENT)) @t_espeak_callback def callback(wav,numsamples,event): # 以下略
wav が空でなく、numsamples が0より大きければ、
player.feed(string_at(wav, numsamples * sizeof(c_short)))
でデータをオーディオ出力デバイスに送っている。
そして player オブジェクトは nvwave.py に実装されている nvwave.WavePlayer() のインスタンスである。
nvwave は ctypes を使って Win32 のオーディオ出力APIを叩いている。
nvwave (NVDA)
WinMM のラッパークラス
nvwave.WavePlayer の主なメソッド
- idle()
- feed()
- stop()
- pause()
言語 en で日本語の文字を読む
since 2013-04-12
最近の espeak は言語 en でカナ文字を Japanese Letter, 漢字を Chinese Letter と読むようになった。
ちょっといじったら英語の音素で日本語の文字を単漢字読みするのではないかと思い、試した。
espeak 1.47.05 で NVDA の scons を使う。
// tr_languages.cpp 100 行あたり // {"_ja", 0x3040, 0x3040,0x30ff, 0, AL_NOT_CODE}, // {"_zh", 0x3100, 0x3100,0x9fff, 0, AL_NOT_CODE}, {"_en", 0x3040, 0x3040,0x30ff, L('e','n'), AL_NOT_CODE}, {"_en", 0x3100, 0x3100,0x9fff, L('e','n'), AL_NOT_CODE},
// dictsource/en_extra というファイルを作る // Japanese U+3042 A: U+3044 I U+3046 u: U+3048 E U+304a o U+7d42 Su: U+4e86 rjo
これで「あいうえお」を「アイウエオ」と読み、それ以外のカナ文字を「レター」とだけ読むようになる。
U+7d42 と U+4e86 は「終了」で、なんとなく「シュウリョー」と聞こえるように読む。
ちなみに en_list には "_ja dZ'ap@ni:z" という Language Name の定義がある。tr_languages では _ja とカテゴライズされた文字を実際に「ジャパニーズレター」と読むのは en_list の定義による。