2010年08月14日

GNOME Orca で日本語をしゃべらせてみる。

ご無沙汰しています。ずっと文章書いていませんでした。文章だけでなく、プログラミングもやる気が全然起きなくて。でも久しぶりにやってみると意外に進展したので報告します。
Orcaに日本語をしゃべらせたい」で書いたことの続きです。

Orca は GNOME デスクトップで動作するスクリーンリーダーです。残念なことに、日本語ではしゃべってくれません。
日本語音声を使えるようにするにはどういう方法があるのか、Orca の設定をいじってみて調べてみたのが、「Orcaに日本語をしゃべらせたい」の記事です。
いろいろな可能性は見えましたが、結局、その時点ではうまくはいきませんでした。

久しぶりに、Orcaについて調べてみました。英文の資料を読んだり、Orcaの Python ソースをじっくり眺めてみたり。
読んでみると、なんとか新しく読み上げシステム(speech system)を登録できそうに思えたのでやってみました。そしたら、意外に簡単に動いてくれました。

やったことはとても単純です。orca のソースにある ***factory.py というファイルが、音声システムを仲介するスクリプトのようなので、これを参考に作りました。実際に英語の発音ができている speechdispatcherfactory.py の音声出力部分を、mbtts による記述で置き換えていきました。とてもあっさりとできました。このブログで何度か体験してきたブレイクスルーは、どれもこんな感じでした。今回もやはりそうでした。

まだ完全ではありませんが、とりあえず動くようになりました。
詳しいことは次回。とりあえず報告まで。

ところで、日本には Orca という同名の Ubuntu で動くレセプトソフトがあるため、検索エンジンでこのスクリーンリーダーの Orca の情報を探すのがちょっと面倒です。そのためスクリーンリーダーのそれを扱うときは、書くときも探すときも GNOME orca という表記を使わないと仕方ないですね。


posted by takayan at 03:38 | Comment(0) | TrackBack(0) | GNOME Orca | このブログの読者になる | 更新情報をチェックする

2010年08月17日

GNOME Orca で MBROLA と mecab を使って日本語をしゃべらせる方法

注意:
このプログラムは実験的なものです。自己責任でお使いください。
動作が確認できたのは Ubuntu10.04 です。
それ以後では動作しません。インストールしないでください。
2011.10.18

そういうわけで、Ubuntu上で日本語スクリーンリーダーを動作させる方法です。
以下に必要なファイルと、手順を示します。興味がある人は自己責任で試してみてください。

現在確認しているOS は Ubuntu 10.4 だけです。
orca ですので、GNOME デスクトップが動いているディストリビューションでも、動くかもしれません。問題があるとすれば、今回利用している mbtts がそのディストリビューションで使えるかどうかです。

TTS として、以前僕が作った mbtts というものを使います。これは、日本語のテキストを、mecabにより日本語形態素解析を行い音素文字列に変換し、それをMBROLA の日本語音素を使って音声に変換するものです。ruby で書かれた吉田 智章氏の muDaTTS を参考にして、Pythonで書いたものです。今回、orca への対応のためローマ字の逆変換など機能追加や修正を行いました。

以下インストール手順です。
[2010/08/19 orca-2.31.90へ対応のため修正]
[2010/08/30 mbtts 97.6への対応]

1. 下記のリンクより mbtts 0.97.6 をダウンロードし、展開後 mbtts.txt で示してある手順で、必要なパッケージと、mbtts 本体をインストールします。このとき MBROLA の日本語音素データベースを所定の場所に必ず一つ入れてください。
https://neu101.up.seesaa.net/etc/mbtts-0.97.6.zip

2. orca のソースを 下記の GNOME の ftp からダウンロードします。今回は バージョン2.31.90 を使っていますので、それをダウンロードしてください。
orca-2.31.90.tar.bz2

3. orca で日本語を再生できるようにするためのファイル群をダウンロードします。今回作ったものそのものです。
https://neu101.up.seesaa.net/etc/orca-2.31.90-mbtts-files-0.3.tar.gz
(0.3 ... 初回起動時に選択できない問題を修正 2010/10/13)

4. 2でダウンロードした orca-2.31.90.tar.bz2 ファイルと、3でダウンロードした orca-2.31.90-mbtts-files-0.3.tar.gz ファイルを同じフォルダに入れ、次のコマンドを実行してください。問題がなければ、これで日本語に対応したOrca がインストールされます。今回 intltool を最新版にする必要があるようなので、下記のように configure の前に sudo apt-get install intltool も実行する必要があります。
sudo apt-get install intltool
tar xvfj orca-2.31.90.tar.bz2
tar xvfz orca-2.31.90-mbtts-files-0.3.tar.gz
cd orca-2.31.90
./configure
make
sudo make install

5. Orcaの起動は、「アプリケーション」メニュー>「ユニバーサル・アクセス」>「Orca スクリーン・リーダと拡大鏡」です。初回起動のときは、質問をいろいろされると思います。これはあとから設定画面で変更できます。日本語の音声にならないときは、設定画面を開き、読み上げシステムを mbtts に切り替えて、右下のOKボタンを押せば、日本語をしゃべるようになるはずです。

できないこと
・句読点などの読み上げレベルが変更できません。
・漢字変換を読み上げません。
・そのほかいろいろ

まだ完全な機能ではありませんが、これで Ubuntu で日本語スクリーンリーダーを使えるようになりました。


posted by takayan at 03:44 | Comment(0) | TrackBack(0) | GNOME Orca | このブログの読者になる | 更新情報をチェックする

2010年08月19日

pythonで文章中のアラビア数字を漢数字に変換するスクリプト

日本語読み上げのための mbtts を久しぶりに書き直したのですが、そこでアラビア数字を漢数字に変換する部分も修正しました。
このスクリプトをもっと簡潔に書くとどうなるだろうと、単純な条件にしてみて、考えてみたのが次のスクリプトです。

#!/usr/bin/env python
# -*- coding: utf8 -*-
import re

char2int = {
u'0' :0, u'1' :1, u'2' :2, u'3' :3, u'4' :4,
u'5' :5, u'6' :6, u'7' :7, u'8' :8, u'9' :9,
u'0':0, u'1':1, u'2':2, u'3':3, u'4':4,
u'5':5, u'6':6, u'7':7, u'8':8, u'9':9,
}

numKanji0 = [ u'', u'一', u'二', u'三', u'四', u'五', u'六', u'七', u'八', u'九' ]
numKanji1 = [ u'', u'', u'二', u'三', u'四', u'五', u'六', u'七', u'八', u'九' ]
numKanji = [ numKanji0, numKanji1, numKanji1, numKanji1 ]

numPlace1 = [ u'', u'十', u'百', u'千' ]
numPlace4 = [ u'', u'万', u'億', u'兆', u'京', u'垓' ]

# 千の桁が1のときの処理:
#
# (a) 全て千
#  例  千万,  千五百万,  一万千,  千
#
# (b) 全て一千
#  例 一千万, 一千五百万, 一万一千, 一千
#
# (c) 四桁のときだけ千。残りは一千
#  例 一千万, 一千五百万, 一万一千,  千
#
# (d) 四桁のときは常に千。百十一の桁が無ければ一千、あれば千。
#  例 一千万,  千五百万, 一万一千,  千
#
# (e) 一万以下の千の桁は常に千。一万以上の千の桁は常に一千。
#  例 一千万, 一千五百万,  一万千,  千
#
# (f) 一万以下の千の桁は常に千。一万以上の千の桁は、百十一の桁が無ければ一千、あれば千。
#  例 一千万,  千五百万,  一万千,  千

def convert_pure_integerstring(match):
source = match.group()
numstr = re.sub( u'[,,]', u'', source )
# numKanji[3] = numKanji0 # (b)
# numKanji[3] = numKanji1 if len(numstr) == 4 else numKanji0 # (c),(e)
s = []
for ch in ((u'0'*((4-len(numstr)%4)&3))+numstr): s.insert(0,char2int[ch])

list = []
while len(s):
temp = u''
for i in range(4):
if s[i]: temp = numKanji[i][s[i]] + numPlace1[i] + temp
list.append(temp)
s = s[4:]

if len(list) > len(numPlace4): return source

result = u'' # (a),(b),(c),(d)
# result = list[0][1:] if list[0].startswith(u'一千') else list[0] # (e)
# result = list[0] # (f)
for i in range(len(list)): # (a),(b),(c),(d)
# for i in range(1,len(list)): # (e),(f)
if list[i]:
if len(list) > 1 and list[i] == u'千': list[i] = u'一' + list[i] # (d)
# if list[i] == u'千': list[i] = u'一' + list[i] # (f)
result = list[i] + numPlace4[i] + result

return result if result else u'零'

def convert_integerstring(string):
if string == None or string == u'': return u''
p = re.compile(u'[0-90-9][0-90-9,,]*[0-90-9]|[0-90-9]')
return p.sub( convert_pure_integerstring, string )

print convert_integerstring( u'10,000,000, 15,000,000, 11000, 1000')

このスクリプトは日本語の文章の中のアラビア数字を漢数字に変換します。小数点数には対応していません。
桁区切りのコンマは、無視します。つまり、でたらめでも構いません。
数字は半角でも全角でも混ざっていても処理します。

(追記 2010/08/20)
「一千」の扱いについていろいろ修正してみました。ありがちな読み方を6通り考えてみました。対応する行を有効にしたり、コメントアウトしたりすれば、読み方を変えられます。他にも読み方の規則はあるかもしれませんが、そのときは応用して修正すればできると思います。

(a)と(b)は、はっきりと違和感がありますので、わざわざ選ぶことはないと思います。(c)はここで最初に書いていた処理で、一番シンプルで、違和感は多少ありますが許容範囲内だと思います。(d)と(e)と(f)は(c)の違和感を補正する方向で考えたものです。条件分岐を入れて補正しているので、ちょっと処理が美しくありません。(d)と(e)と(f)のどれを選ぶかは作り手のちょっとした好みによるでしょう。
(追記終わり)

最速とはいえませんが、すっきり分かりやすいアルゴリズムだと思います。
一カ所、for ch in ((u'0'*((4-len(numstr)%4)&3))+numstr): s.insert(0,char2int[ch]) が分かりにくいかもしれませんが、全角か半角の数字だけからなる文字列を先頭に0で詰め物をして4の倍数の桁にした後、変換テーブルを使って逆順の数値リストに変換しています。


posted by takayan at 22:51 | Comment(0) | TrackBack(0) | プログラミング | このブログの読者になる | 更新情報をチェックする

2010年08月24日

AquesTalk2 も GNOME Orca で 使えるようにしてみた

注意:
このプログラムは実験的なものです。自己責任でお使いください。
動作が確認できたのは Ubuntu10.04 です。
それ以後では動作しません。インストールしないでください。
2011.10.18


GNOME Orca に日本語をしゃべらせる方法がわかったので、mbtts を少し改造して、AquesTalk2 にも対応してみました。いわゆる、ゆっくりボイスで、Linux のデスクトップを読み上げてくれるようになります。

興味のある方は、上記のファイルをダウンロードして、次の記事を参考にしてインストールしてみてください。
GNOME Orca で MBROLA と mecab を使って日本語をしゃべらせる方法

今回利用できるようにした AquesTalk2 というのは、アクエスト社の音声合成ライブラリです。非営利の個人利用に限って使用することができます。
製品ページは、AquesTalk2 - テキスト音声合成ミドルウェアです。

今回、AquesTalk2 を同梱していませんので、ライセンスを確認したうえで、上記サイトよりダウンロードして試してみてください。設定フォルダの中のaquestalk2フォルダにDLLを配置すれば、この ライブラリの機能が利用できます。また、追加の声種ファイルは、設定フォルダの phont フォルダの中に入れるだけで、利用可能になります。
設定フォルダの中の aquestalk2 フォルダの中に、声種データのアーカイブを置くだけで、実行時に展開してくれます。
(2010.8.30 修正。aquestalk2関連ファイルの配置場所についての仕様を変更。)


Orca で日本語をしゃべらせるために GNOME Orca にファイルを追加して対応しているのですが、今回はそのファイルのバージョンアップは行わず、mbtts のバージョンアップ(0.97.3)だけで対応してみました。本来は、シンセサイザの分類を追加して作るべきなのでしょうが、今回はディフォルトのシンセサイザ1つのまま、音声の人物を増やすことで対応しました。人物の記法は、シンセサイザ名ドット音声名です。例えば、'MBROLA.jp1'や'AquesTalk2.aq_yukkuri'と表記しています。ただ省略記法として音声名だけでも認識できるようにもしています。

mbtts は、MBROLA のデータベース向けに作ったスクリプトなので、内部はちょっと美しくない方法での対応になっています。とにかく動作させたいという気持ちを最優先で作っているので、細かな部分は今後コツコツ修正していきます。

今現在 Orca に日本語をしゃべらせるためには、どうしたらいいかという実験の途中です。まだまだ機能が足りない部分がいろいろありますが、今回使える声数がいっきに増えて、とても面白くなってきました。AquesTalk 2は前々から知っていたのですが、実際プログラムを組んでみて、これほど使いやすく聴ける合成音声が出ることに驚いています。無償は非営利個人利用限定ですが、このように素晴らしいものが公開されていることに、とても感謝します。

Python からの AquesTalk の利用に関しては、特に次のページを参考にさせてもらいました。
AquesTalk2 Linuxを使ってみる - Linux の音声合成コンソールアプリ SayAqTk2 - | N.Yamazaki's blog
Pythonで音声合成(AquesTalk) - tomoemonの日記
AquesTalk Win版 でゆっくり Python していってね - 銀月の符号



今回バージョンアップした mbtts 本体はこれです。Ubuntu10.4 と Windows7 と Mac OS X v10.6 で動作確認をしています。
https://neu101.up.seesaa.net/etc/mbtts-0.97.3.zip


posted by takayan at 02:39 | Comment(0) | TrackBack(0) | GNOME Orca | このブログの読者になる | 更新情報をチェックする

2010年08月28日

GNOME Orca で Open JTalk も 使えるようにしました。

注意:
このプログラムは実験的なものです。自己責任でお使いください。
動作が確認できたのは Ubuntu10.04 です。
それ以後では動作しません。インストールしないでください。
2011.10.18


先日、mbtts を修正して AquesTalk2 を使えるようにしたのですが、せっかくなので Open JTalk も使えるようにしました。これで GNOME Orca で Open JTalkの落ち着いた音声でガイドしてくれるようになります。まだ音量調整など Orcaの設定画面からできないので、ぜんぜん実用的ではないですが、いい感じにしゃべってくれます。今回いろいろやって長文が不得意だということも気が付きましたが、メニューなどの項目を読み上げてくれる分には一番ききやすいように思います。今のところ、Open JTalk の標準の音量が小さく Open JTalk のときだけ、ちょっとパソコンのボリュームを上げないといけませんが。

それから、MBROLAだけのときには気づかなかったのですが、音声の再生速度が今までおかしかったです。pygame.mixer は初期化するときに周波数もちゃんと指定しないといけなかったんですね。でも発音するたびに、初期化をやるようになったので、今まで以上に遅れて発音しているように思います。発音するたびに初期化をしてしまうと、やはりとても遅れてしまいます。声の速さの不正確さは犠牲にしても、遅れを短くしようと思います。初期化は音声を切り替えるときだけにします。(2010.8.30修正)


まだまだ問題はありますが、とりあえず目標としていたフリーの3種類の日本語音声が使えるようになりました。あとはこつこつ細かな修正を加えていく作業が続きます。早いうちに音声出力を PyGame から自前のものに切り替えたいとも思います。

それでは、Open JTalkを使えるようにする方法を以下に書いておきます。ここでは GNOME Orca の対象となる Linux 向けだけでなく、OS Xや、Windows向けの設定方法もまとめて書いておきます。Linux の GNOME Orca で日本語をしゃべらせるには、この Open JTalk と mbtts のインストールの他に、GNOME Orca の修正ビルド、およびインストールが必要です。これは、以前の記事「takayanの雑記帳: GNOME Orca で MBROLA と mecab を使って日本語をしゃべらせる方法」を見てください。

さて、何はともあれ Open JTalk の実行ファイルが必要なので、これを用意します。やはりソースからビルドします。(Windows版はビルド環境作りが面倒なのでビルド済みを用意しています。)
Open JTalkのビルド、実行には hts-engine のライブラリが必要なので前もってこれもビルドします。

それぞれのソースを下記の場所からダウンロードします。

hts-engine:
http://sourceforge.net/projects/hts-engine/
現時点の最新ファイルは、hts_engine_API-1.03.tar.gz です。

open_jtalk:
http://sourceforge.net/projects/open-jtalk/
現時点の最新ファイルは、open_jtalk-1.01.tar.gz です。

mbtts 側の処理の単純化のため Ubuntu でも OSX でも文字セットにしています。Windows 版が UTF-8 でビルドできないので SJIS にしないといけないので、Ubuntu でも OSX でも文字セットは SHIFT_JIS で作っています。なお、nishimotz さんのページ にUbuntu用のパッケージが置かれています。今回の目的以外ならばこれを使うと便利なのですが、このdebパッケージは UTF8 でビルドされているので今回の mbtts で利用することはできません。
Visual C++でコンパイルするときフィルターを通すことで、エラーが出ないように文字コードをエスケープし回避しました。そういうわけで、どのプラットフォームでも UTF-8をOpenJtalkの標準文字セットにしました。これで、nishimotz さんのページ に置いてある Ubuntu 用のパッケージをインストールした場合でもうまく発音してくれるはずです。

ビルド環境さえ整っていれば、Ubuntu、OSXともに次のコマンドでインストールできます。ファイルが更新され名前が変わった場合は適宜書き換えてください。
このときダウンロードしてきた二つのファイルが同じフォルダにおいてあるとします。

tar xvfz hts_engine_API-1.03.tar.gz
cd hts_engine_API-1.03
./configure
make
sudo make install
cd ..
tar xvfz open_jtalk-1.01.tar.gz
cd open_jtalk-1.01
./configure --with-charset=UTF-8
make
sudo make install

(修正2010/10/13)

Windows版は、ビルド環境を作るのも大変でしょうから、文字セットUTF-8で、音声出力を無効化し、VC++2008でビルドした open_jtalker.exe を、mbtts.zip内に同梱しています。

これは以前書いた次の手順でビルドしています。
takayanの雑記帳: Open JTalkをVS2008で

ただし、Windows 版では音声出力をしてしまうので、上記の nishimotz さんの記事を参考に、open_jtalk.c を修正して音声出力を殺しています。
具体的には、現在のソースで144行目に下記のように1行を挿入します。
HTS_Engine_create_pstream(&open_jtalk->engine);
open_jtalk->engine.global.audio_buff_size = 0; // nishimotz
HTS_Engine_create_gstream(&open_jtalk->engine);
なお Windows版では、hts-engine のライブラリは静的に取り込んでいるので open_jtalk.exe 単体で実行できます。

文字セットのことですが、最初、Windows版を UTF-8 でビルドしようとしたのですが、失敗してしまいました。どうやらソースファイルをUTF8で保存することで文字列定数をUTF-8文字列として用意してある部分が引っかかってしまうようです。これを回避するにはパソコンのロケールを英語に切り替えて再起動すればいいのですが、それだとビルドは成功しますが、文字によって異常終了するようになってしまいます。解決策はあるのでしょうが探すのも面倒なので、Windowsでは無理せずSJIS版にしています。そして mbtts の処理を単純化するために、どのプラットフォームでも SJIS版を使うようにしています。ただ SJIS 固定だと他にOpen JTalk利用のソフトが出てきたとき困るかもしれませんので、ここは今後切り替えられるようにしようと思っています。
(2010.08.30 以上の文字セット関連の記述の更新。該当する文字セットでビルドして実行ファイルさえ用意できれば、三つのどの文字セットでも処理できるはずです。)

これで、実行ファイルができました。Ubuntu と OSX では make install でちゃんとPATHの通ったところに配置されているはずです。Windows版も同じように配置する必要があります。PATHの通ったところならばどこでもいいのですが、分かり易いように、ユーザーのホームフォルダの「.mbtts」フォルダの中に「open_jtalk」フォルダを作ってそこに置くと認識するようにしています。

次は辞書と話者データです。Open JTalk には 辞書と話者データが必要です。次の場所からダウンロードしてきます。なおOpen Jtalkの文字セットに合わせて辞書はUTF-8版を使います。
http://sourceforge.net/projects/open-jtalk/files/

それぞれの現時点での最新のアーカイブ名:
辞書、open_jtalk_dic_utf_8-1.00.tar.gz
話者、hts_voice_nitech_jp_atr503_m001-1.01.tar.gz
辞書の名前が更新されたときは、.mbtts 内の config.txt の変数 openjtalk_dic_ver の値を新しいバージョンに修正し対応します。音声ファイルの方は名前が変わった場合でも修正する必要はありません。

辞書も、話者データも、設定フォルダの open_jtalk フォルダの中にアーカイブのままコピーするだけです。あとは実行時に自動的に展開されます。
(2010.8.30 更新。データのコピーについての仕様変更)

これで、Open JTalk を使う準備は整いました。

AquesTalk2 のための準備は、「takayanの雑記帳: GNOME Orca で MBROLA と mecab を使って日本語をしゃべらせる方法」にも書きましたが、設定フォルダ「.mbtts」の中に各プラットフォーム向けの DLL を取り出し配置すればこの ライブラリの機能が利用できます。Aquestalk2の製品ページを開いて、該当するプラットフォームのアーカイブをダウンロードした後、DLLを抽出します。 Windows は AquesTalk2.dll、Linuxは libAquesTalk2.so.1.0、OSX は AquesTalk2 という名前のファイルです。追加の声種ファイルは、設定フォルダの 中に phont フォルダを作り、その中に入れるだけです。ここに入れるだけで、内部の処理で使用可能音声を問い合わせたときにリストアップされます。


あとは、mbtts の最新版をインストールします。これは展開したフォルダの中の mbtts.txt の手順通りにやります。
そして、以前の記事「takayanの雑記帳: GNOME Orca で MBROLA と mecab を使って日本語をしゃべらせる方法」を見て、Orca を修正インストールしてください。

GNOME Orcaがあれば音声を切り替えて、音声がどう聞こえるのかためしに聞けるのですが、Windows や Mac OS X でも確認しやすいように、mbtts の demo 用のスクリプトを修正しました。speechbox.py は以前から用意していたテキストボックスの内容をの読み上げるスクリプトですが、音声選択メニューを追加しました。それぞれの音声を試すのに使ってみてください。ただし実行には wxPython が必要です。


posted by takayan at 01:51 | Comment(4) | TrackBack(0) | GNOME Orca | このブログの読者になる | 更新情報をチェックする

2010年08月30日

VC++ で UTF-8ファイルがコンパイルできないとき、

先日、VC++で UTF-8で保存されたファイルのコンパイルに失敗して、面倒くさがってSHIFT_JIS版に逃げてしまったたわけですが、今回はその回避策です。

escapize.py
#!/usr/bin/env python
# -*- coding: utf8 -*-
import os
import re

def convert(n):
if not n: return
f = open(n,'r')
data = f.read()
f.close()

d = False
a = ''
for c in data:
if ord(c) >= 0x80:
d = True
a += u'\\x%0X' % (ord(c))
else:
a += c

if d:
print n
f = open(n,'w')
f.write(a.encode('sjis'))
f.close()

def rec_exec(func,p):
if not func: return
for n in os.listdir(p):
f = os.path.join(p,n)
if os.path.isfile(f):
if re.search( '\.(h|c)$', n ):
func(f)
elif os.path.isdir(f):
rec_exec(func,f)

rec_exec(convert,'.')

0x80 以上の文字コードを16進数表記エスケープシーケンスに置き換えていくだけです。そのソースのフォルダに置いて、この Python スクリプトを実行すれば、再帰的にファイルを見つけて変換してくれます。
欠点として、ソースの日本語が読めなくなってしまいます。そのため変換しない原版を別に残しておかないといけません。逆変換のスクリプトを作るという手もありますが、これこそ面倒なので作りません。

とにかく、これで Windows 版の Open Jtalk で UTF-8 版の辞書も使えるようになりました。


posted by takayan at 03:09 | Comment(0) | TrackBack(0) | プログラミング | このブログの読者になる | 更新情報をチェックする