2013/04/01

Android TextToSpeech#setLanguage() の使い方

前回は TextToSpeech の初期化について書いたが、N2 TTS を使用時に女性/男性の切り替えができないと書いた。可能な方法が見つかったので、書いておく。


まず、ロケール周りのテキスト表現が2種類(大文字小文字も含めると更に多い)ある。言語と国を"-"で区切る場合と、"_"で区切る場合があり、TTSでの取り扱いでは、これが混在している。例えば、ACTION_CHECK_TTS_DATA で取得できるサポート言語のリストでは "-"区切りとなるのに対して、使用中のTTSエンジンの現在の言語設定を取得するgetLanguage()では、"_"区切りとなっている。
結局 Lacale のインスタンスを作って操作することになるので、なんでもいいんだが、無駄な混乱の元になるといけないので、どちらか一方に正規化して整理したほうがコードのメンテナンスは楽になるだろうと思う。区切り文字が何になるかは、運(?!)次第な面があるので、OSのアップデートなんかを考えると、ぜひともそうしておいたほうが、精神衛生上よろしいと思う。


さて、問題の N2 TTS エンジンなのだが、ACTION_CHECK_TTS_DATA で取得できる言語は

jpn-JPN-F01
jpn-JPN-M01
の二つだ。Android 組み込みの Google TTS エンジンの場合は、
fra-fra
eng-gbr
eng-usa
ita-ita
deu-deu
spa-esp
のように、ロケールの Variant にあたる部分がないし、全て小文字になっている。
(という具合に表現と要素まで違ってくるので、この違いに注意して、実装することが必要)。
現象として、Google TTS エンジンから取得した言語情報を使えば、言語の切り替えできるが、N2 TTS からの場合、切り替えできないということになるが、エンジン側としては、指定どおり切り替えている( setLanguage() の戻り値で調べられる)。N2 TTS で問題になるのは、実は3項目目の Variant にあたる部分で、これが

new Locale("jpn-JPN-M01");


の際、なくなってしまうのが、原因だと判明した。原因が分かれば簡単で、あらかじめ言語文字列を3要素に分解して
new Locale("jpn", "JPN", "M01");
のようにして、3要素指定でインスタンスを作ればいい。
これを setLanguage() してあげれば、めでたく男性に切り替わってくれる。


ところで、Variant 要素を具体的にどういう表現にすればいいのかといったことに関して、Android OSのリファレンスにも特に規定はないようだ。唯一http://developer.android.com/reference/android/speech/tts/TextToSpeech.Engine.html 
にvariantの例として、
"eng-USA-FEMALE"
というのがあげらている。試しに
"eng-USA-MALE"
をしてみたが、女性のままだった。しかし
"eng-gbr-MALE"
を試すと、あら不思議、大英帝国のジェントルマンの声が聞こえてきた。


という訳で、variantの値が、具体的にどうなるのかは、手探りの状態だ。


どうにかならないのかな???

0 件のコメント:

コメントを投稿