今回は前回に引き続き、mikutterに関するレシピをお届けします。mikutterプラグインを書き、タイムラインにツイートが増える度に、その内容を音声出力するようにします。
プラグインの概要
本連載の第250回と第251回では、日本語テキストから音声を合成し、サウンドサブシステムから出力しました。これらを処理するPython 2スクリプトを用意したわけですが、今回はこれをRubyに移植し、mikutterプラグインとして利用可能にします。
処理内容などはほぼ前回を踏襲します。すなわち、日本語テキストをMeCabを使って形態素解析し、辞書から発音を取得します。その結果を利用してMbrola向けに音素リストを作成し、mbrolaコマンドを使って音声を合成します。音声データはaplayを使ってサウンドサブシステムに出力します。
MeCabとMbrolaに関しては、本連載の第250回と第251回を参照してください。
MeCabと辞書の準備
まずは、RubyスクリプトからMeCabを使えるようにします。MeCabにはRubyバインディングがあり、Ubuntuでは「ruby-mecab」パッケージとしてインストール可能です。以下のコマンドを実行し、インストールしてください。依存関係で、MeCab本体のパッケージもインストールされます。
次にMeCabが利用する辞書をインストールします。今回も「mecab-naist-jdic」を利用します。以下のコマンドを実行し、インストールしてください。
システム上に辞書が複数存在する可能性があるため、第251回のAlternativeを使う手順に従って、デフォルトで使われる辞書を確認してください。
これで、RubyスクリプトからMeCabを利用する準備が整いました。実際に利用できるかどうかを確認するために、以下のサンプルを実行してください。
以下のような出力が得られたら成功です。
Mbrolaの準備
次はMbrolaの準備です。まず「mbrola」パッケージをインストールします。
次に、音声データベースをインストールします。日本語発音用データベースはUbuntuのリポジトリからは提供されていないため、Copying the MBROLA Bin and Databasesから、jp3をダウンロードします。
これでmbrolaを使う準備が整いました。実際に使えるかどうか、以下のサンプルを使って確認してみましょう。
サンプルをsample.phoというファイルに保存し、以下のコマンドを実行してください。ここでは、サンプルとjp3データベースがカレントワーキングディレクトリに保存されたと仮定しています。
「わたしはみくったーちゃん」と聞こえたら成功です。もし聞こえない場合は、psコマンドなどでPulseAudioサウンドサーバーが起動していることを確認してください。
なお上記コマンドを実行するとmbrolaプロセスがコアダンプします。筆者が確認する限りfree(3)やmunmap(2)の実行でSIGSEGVが送出されることから、プロセスのVMA上でバッファーオーバーランが発生し、不正な値がポインタに書かれたのだと思います。しかしUbuntuやDebianのバグトラッキングシステムでは、類似のバグを見つけられませんでした。mbrolaは非オープンソースソフトウェアであり、ビルド済みバイナリのみが配布されています。そのため、これ以上の調査はできませんでした。今回のレシピは、この問題を無視して進めます。mbrolaは面白いソフトウェアであるだけに、残念です。
プラグインの作成
以上で準備が整いました。前回の最後のサンプルについて、プラグイン名とクラス名をそれぞれ「mecabrola」と「Mecabrola」に変更しつつ、拡張します。以下がエントリーポイントとハンドラー部分です。
今回は簡便のため、1回のブロック呼び出しで1メッセージだけ処理します。まずMecabrolaクラスのインスタンスメソッド「tokenize_message」でMeCabを用いた形態素解析を行います。次に「generate_pho_lines」メソッドでMbrolaの音素リスト(phoフォーマット)のデータを生成します。「write_pho_file」メソッドで一時ファイルに書き出し、「run_mbrola_aplay」メソッドで音声合成と音声出力を行います。
Mecabrolaクラスの各メソッドの内部処理に関しては、割愛します。
プラグインの試験
以下がプラグインの圧縮アーカイブです。
mikutterの作法に従って「~/.mikutter/pluin/mecabrola」以下に配置してください。同じディレクトリにmbrolaのjp1あるいはjp3データベースも配置してください。
mikutterを再起動すると、きっと何らかの音声出力が聞こえるはずです。おそらく、多くのツイート内容について、発声が途中で切れると思います。多くの場合、「与えたphoフォーマットデータ内のエントリーに、jp1/jp3データベースに収録されていない音素組み合わせがあり、処理を中断した」というのが原因です。これに関しては、本連載の第252回を参照してください。筆者のTLに流れてくるツイートから生成した音素組み合わせにおいて、よく見られたものは以下でした。
- u-xo: フォロワーの「ふぉ」など
- u-xe: ウェブの「うぇ」など
- u-xi: イポンツィの「ツィ」など
- dZ-_: じょうろの「じょ」など
- S-j: 商標の「しょ」など
- dZ-j: 順列の「じゅ」など
どのような組み合わせで終了しているかは、mikutterを--debugオプション付きで実行して確認できます。
加えて、英単語は無声としているので発音されない点に留意してください。プラグインには他にも改善すべき点が多々ありますが、紙面の都合上、ここで開発を終えたいと思います。
まとめ
本レシピではTwitterプラグインであるmikutterのプラグインを書き、mikutterの機能を拡張しました。日本語テキストの自然言語処理、テキスト読み上げと言った学術領域の成果を援用し、プラグインの機能を実装しました。mikutterのプラグインは比較的書きやすいように思いましたので、みなさんも好みの機能を実装してmikutterに親しんでみるとよいでしょう。