2012年10月14日日曜日

RubyでAquesTalkを喋らせてみた。

昨年のPHPカンファレンスで東京に行った時仕入れいた、合成音声LSI AquesTalk
喋らせてみた。

これ、おもしろい!
こんな小さな8bitマイコンで、外付けのROMやRAMがいるわけもなく、電源とシリアルをつないで、
ローマ字を送るとしゃべる。
こんな小さな容量にどうやって詰め込んでいるのか。正に謎の技術。
しゃべるといえば、昔、PC6001というマシンがあって、これがBASICでTALK文という命令を使うと
喋らせることができた。当時画期的で大変未来を感じたものだ。こんな動画もある。
さらに、当時5インチフロッピーな時代に3.5インチフロッピーだったマッキントッシュは喋るのだよ。
衝撃だった。
ディスプレイがカラーになった時や、FM音源がなった時の感動は今でも・・・

っと昔話はおいておいてw
こいつを喋らせるには、音声記号と呼ばれるローマ字にアクセント記号がついたものを送る必要がある。音声記号の仕様についてはここを参照。

で、公式にも日本語を音声記号にするサービスがあるのだが、
サーバー資源に限りがあるため、本サイト以外からのアクセスおよびアプリやスクリプトからの利用を禁じます。
とのことなので、自作してみた。

ソースはここで公開中。お気軽にpull requestやらforkしてね。

仕組みとしては、

  1. TwitterAPIを利用して、特定ハッシュタグのついたつぶやきを取得。
  2. MeCabを利用して形態素解析を行う。
  3. 形態素解析の結果、数字なら数字のタグをつける。英語なら英語のタグをつける。
  4. 形態素解析の結果、記号で読み方がわかるものはそのまま。読めない記号は無視。
  5. 形態素解析の結果、記号で読み方が不明の場合は、人間が読み方の辞書を与える。
  6. 形態素解析の結果、固有名詞の場合は読み方がわからないので、人間が読み方の辞書を与えてやる。
  7. kakasiを使って、読みがなをローマ字に変換する。
  8. シリアルポートへローマ字を流して喋らせる

ざっとこんな感じ。
何気に公式に対抗してみるw
公式より優れているw点

  • 英語タグの解釈が可能
  • 記号の読みにある程度対応(辞書のメンテ次第)
  • intelのような英語固有名詞にある程度対応。(辞書のメンテ次第。公式も一部対応の様子。)
  • 公式ではデータシートにない裏コマンドを生成する?(MODE=DaAってなんだ?)


公式より劣っている点

  • アクセント未対応(アクセント辞書どこかにあるのかなぁ)
  • 公式でも一部対応しているようだが、膨大にある英語よみの辞書を手動メンテしないといけない。(どこかに辞書が落ちていないかなぁ)
  • 数字タグに完全に対応していない。<NUMK VAL=132 COUNTER=enn>のような形式には未対応。数字+円とか数字+時とかだったらみたいにすれば対応可能かな。(追記:第二品詞に”助数詞”とはいるようなので、これを見ればいける気がする)


実装してみての気になる注意点


  • シリアル通信の場合、内部クロックでの動作の影響か、タイミングを取るのが結構シビア。
  • 可能ならI2Cのような別の手段で通信する方がいいとおもう。試してないけど。
  • PCの処理が高速でかつ、シリアルもマイコンにとっては十二分に早いので、適切に待つ必要がある。
  • BUSYが解除されてすぐにデータを送信しても、当然構文解釈するためにある程度の時間がかかるが、そのためのBUSYを返すまでの間に大量データを送信するとバッファが受けきれなくなる。
  • 一回の送信は100Byte程度に抑え、送信後BUSYにかかわらず1秒以上待つほうがいい。
  • BUSY信号は、何かしらの入力をしないと帰ってこない。又BUSY送信時、改行を送らないので、使用するライブラリによっては、ずっと受信中になる。(地味にハマった。)
  • 送信した音声記号中に解釈不可能な文字(記号など)が混ざっていると、送ったデータ全体が無効になる。記号直前まで喋ってくれたりはしない。
  • したがって、喋らないのは、解釈不可能な文字が混入しているか、バッファがOFしたかの判断がつかない。(一応長い文字列を送るとエラーコードを送るようになっているが、そもそもBUSYを発信する前にOFすると、どうやら解釈不可能としてエラーを出さず無効になるようです)

実装してみて、改めて日本語を読み上げるのが大変だと思い知った。
日本語を読み上げるだけでも、漢字、かなだけでなく、ローマ字読みもあれば時として英語読みもある。
MACはなぜエムエーシーではなくマックなのか。
ーはマイナス?ダッシュ?長音記号?
瞬時に文脈を判断し、適切な単語の区切りを見つけて、単語のよみを発声する。
しかもこれにアクセントやイントネーションまであるときたもんだ。
なかなか高度なことを普段やっている。




0 件のコメント:

コメントを投稿