現在書いているものが終わるまで他のことを書かないでおこうと思ってましたが、面白いアイデアが浮かんだのでここでプログラミングの話題を書くことにします。
集中力が切れたので、気分転換にUbuntu13.10を入れていろいろ試していました。久しぶりに起動したスクリーンリーダーgnome orcaのeSpeakの音声が、仮名文字や漢字のところで、ジャパニーズレターとかチャイニーズレターと言うようになっていました。以前は日本語文字列のところで意味不明な記号の羅列を延々と読み上げていたので、親切な修正と言えます。うるさいことには変わりないですが。
ちなみに、gnome orcaをオン/オフする標準のキーボードショートカットは、altキー+superキー(win)+sキーです。マウスでの操作だと、画面右上の[システム]ボタンを押して、出てきたメニューの中から[システム設定]を選び、開いた「システム設定」ウィンドウの中の[ユニバーサルアクセス]ボタンを押して、[視覚]タブにあるスクリーンリーダーのトグルボタンで切り替えます。
検索してみると、NVDA日本語版のてくてくラボのespeakのページにespeakのその指摘がありました。半年以上前の記事です。そこにはen_extraファイルを使って言語enで日本語を読ませる短いですが興味深い実験が書いてありました。
これはorcaに使えます。orcaの標準音声はespeakのenなので、これで日本の文字を発音できるようになれば素晴らしいです。さっそく勢いで作ってみました。
英語の発音記号を使ってカナ文字の発音をen_extraに定義していきます。このファイルを追加して、発音辞書であるen_dictにその内容を反映させると、eSpeakでカナ文字を発音してくれるようになります。Windowsでこの作業を行うには、eSpeakのホームページからespeak-1.47.11-win.zip や espeakedit-1.47.11-win.zipをとってきてインストールしておく必要があります。
発音辞書の設定は、espeakがインストールされた場所のdictsourceフォルダにあるrules、list、extraファイルで行います。その実行ファイルはcommand_lineフォルダにあるespeak.exeです。英語enの場合は次のコマンドになります。
espeak --compile=en
dictファイルはespeak-dataフォルダに生成されます。なお最近のWindowsでは管理者権限で実行しないと、VirtualStore内に作られてしまいます。
本当は言語jaを創設すべきところなんでしょうが、理解するのに時間がかかりそうだったので、このまま英語の追加の発音として作ってみました。今後、日本語独自のrules、list、extraファイルを作る場合は、eSpeakのサイトにあるPronunciation Dictionaryのページを参考にすればいいはずです。
せっかくなので、今後のことを考えて、仮名文字単体ではなく、長音、促音、拗音なども合わせて、ある程度の日本語の音節を表現するものを作ってみました。「ん」の発音の区別はしていません。これはカナ文字ではなくローマ字に変換するとやりやすくなるでしょう。他にも漏れてるものもあるかもしれません。発音も間違っているかもしれません。
このen_dictをNVDAにあるen_dictファイルと置き換えると、たどたどしくですが、かなを読み上げてくれるようになりました。同じファイルをubuntuに持っていってgnome orcaのen_dictと置き換えても、うまくいきました。漢字などまだ読めない文字がたくさんありますが、いかにも電子音電子音しているeSpeakの読み上げの中から日本語が聞こえてくると、それだけでも楽しいものです。
具体的なubuntuでのen_dictの置き換えですが、次の通りです。
まず、下記のアーカイブをダウンロードして、展開します。
ダウンロード:orca-3.10.1-espeak-jp_003.zip
(2013/12/13追記 後日作った数値読みの機能を追加したものにアーカイブを差し替えます。またubuntu13.10のorcaが3.10.1になったので対応バージョンも変えます。関連記事「gnome orcaでespeakに日本語をしゃべらせる方法2」 )
このアーカイブの内容は次の通りです。
・en_extra
・en_dict
・katakanize.py
・speechdispatcherfactory.patch
この中のen_dictを使います。新しいこのファイルがあるところで、端末から次のコマンドを実行します。
32ビット版ubuntuの場合、
sudo cp en_dict /usr/lib/i386-linux-gnu/espeak-data/en_dict
64ビット版ubuntuの場合、
sudo cp en_dict /usr/lib/x86_64-linux-gnu/espeak-data/en_dict
ただし別個にespeak関連パッケージをインストールした場合は別の場所のespeak-dataに変わるようです。
カナ文字だけならば発音できるようになりました。今度は、漢字の読み方を教えて漢字も読めるようにしてみます。要は漢字をカナ文字列に変換できればいいわけです。この問題の解決には、やはりMeCabを使います。gnome orcaなのでPython3で考えます。
ところが、ubuntuではpython3用のMeCabモジュールはapt-getでまだ入手できません。そのため自分でビルドしインストールする必要があります。修正も必要です。具体的な方法は、「Ubuntu - MeCabをPython3上から使えるようにする - Qiita [キータ]」に書かれています。注意点として、ビルド環境を整えるために、g++やpython3-devなどをapt-getでインストールしておかなければなりません。それから手順には書いてありませんでしたが、setup.pyも入手して実行しました。
ubuntuのpython3でmecabが使えるようになったので、次のような漢字の文字列をカタカナに変換する関数を作りました。(35行目にループ終了後に残ったwordを追加する処理を追加。2013/12/13)
# /usr/bin/env python3 # coding: utf-8 import MeCab import re def katakanize(text): regexp = re.compile(r'^[\x20-\x7E]+$') if regexp.match(text): return text tagger = MeCab.Tagger('--node-format=%pS%f[8] --unk-format=%M --eos-format=\n') text = tagger.parse(text) #text = unicode(tagger.parse(text.encode('utf-8')),'utf-8') list = [] word = "" prev = False for ch in text: if regexp.match(ch): if prev: word = word + ch elif word: list.append(word) word = ch else: word = ch prev = True else: if word: list.append(word) word = "" list.append(ch) prev = False else: if word: list.append(word) result = [] word = "" for ch in list: if regexp.match(ch): if word: result.append(word) word = "" result.append(ch) elif ch == u"ッ": if word: result.append(word) word = ch elif ch == u"ー": word = word + ch result.append(word) word = "" elif ch == u"ャ" or ch == u"ュ" or ch == u"ョ": word = word + ch elif ch == u"ァ" or ch == u"ィ" or ch == u"ゥ" or ch == u"ェ" or ch == u"ォ": word = word + ch elif len(word) >= 1 and ( word[-1] == u"ク" or word[-1] == u"グ" )\ and ( ch == u"ヮ" or ch == u"ヰ" or ch == u"ヱ" ): word = word + ch elif len(word) >= 1 and word[-1] == u"ッ": word = word + ch else: if word: result.append(word) word = ch if word: result.append(word) if result: return " ".join(result) else: return "" if __name__ == "__main__": text = "これは文章変換の実験です。" text = katakanize(text) #text = katakanize(unicode(text,'utf-8')).encode('utf-8') print(text)
最後の数行はテスト用のコードです。python2で試してみるときは、辞書のエンコードを考慮して二か所のコメントアウトした部分を直前の行と入れ替えます。
カタカナ化という名前にしていますが、やっているのはもう少し複雑です。まず、MeCab.Taggerの引数内のf[8]で示している通り、表記ではなく発音の文字列を出力しています。例えば助詞の「は」は「ワ」となります。それから日本語文字とそれ以外を区別して、さらに日本語の場合は今回のen_extraにあるような塊になるように分かち書きになります。 この関数の部分を適当な箇所に貼付けて、その呼び出しをeSpeakに文字列を渡す直前に配置します。例えば変数textに文字列が入っていれば、その直前にtext = katakanize(text)という行を入れます。なおpython2では文字列や辞書のエンコードを考える必要があるので、上記のコメントアウト部分のような記述になります。
それでは具体的な修正方法です。 ここに示す方法はあくまでも実験です。ここに書いてあることを試したいときは、実務機以外、仮想マシーン(VMware Player、VirtualBox)などにとどめてください。もちろん自己責任でお願いします。orcaのバージョンが変わったときは修正箇所もその影響も変わる可能性もあるので、そのときはあきらめてください。
やることはとてもシンプルです。先ほどやったen_dictをコピーする操作に加えて、一つのファイルにパッチをあてるだけです。その修正対象となるファイルは /usr/lib/python3/dist-packages/orca/speechdispatcherfactory.pyです。このファイルには、linuxで標準的な音声合成のインターフェイスであるSpeech DispatcherへOrcaからコマンドを送るコードが書かれています。この中の、特に文字列を送って音声を鳴らすspeakコマンドのあるところが修正すべき箇所となります。Speech DispatcherはeSpeak以外の音声合成システムも管理しているので、それぞれの音声合成でカナ文字日本語の処理を用意しておけば、使えるようになるかもしれません。
端末を開いてorcaのバージョンを確認します。次の行を実行します。
orca -v
返ってきた文字列が3.10.1が3.9.92であることを確認してください。このバージョン以外ならば、うまくいくかどうかわかりませんので、あきらめてください。このバージョンだったならば、アーカイブの中のpatchファイルのあるところで、次のコマンドを実行します。問題があったときは、ソフトウェアセンターでorcaをインストールしなおすか、バックアップファイルをもとの場所に戻してください。
cp /usr/lib/python3/dist-packages/orca/speechdispatcherfactory.py speechdispatcherfactory.py sudo patch /usr/lib/python3/dist-packages/orca/speechdispatcherfactory.py<speechdispatcherfactory.patch
これで、漢字交じりの日本語をカタカナ音節に変換する機構が組み込まれました。Alt+Win+sでOrcaを起動してみてください。
とりあえず、eSpeakの声で日本語をしゃべっています。問題はまだたくさんあります。数字の部分も英文と同じように本来のenで読んでもらうようにしています。そのため数値が英語読みになって、ちょっとおかしな表現になってしまいます。数字を日本語読みにする処理は以前ここでも書いたことがありますが、面倒そうだったので今回は入れていません。それくらいになると別ファイルにするか、モジュールとして独立させた方がよさそうです。他にも実用的にするにはもっと多くの処理が必要になってくるでしょう。
言語jaを作って、日本語用の音素を作って、別のfactory.pyを作って、さらにアクセント情報のあるunidicかOpen JTalkの辞書を使ったり、いろいろできるはずです。日本語の音声が必要な人たちに標準で用意できるようになると素晴らしいでしょう。
また新たな中途半端なものを作ってしまったわけですが、これを足掛かりに先に進めればいいと思います。