Using OpenJTalk RTC (C++) for Windows
OpenHRIは音声対話に関する複数のフリーソフトを使いやすくまとめたRTC群です。
ここでは音声合成用RTCである、OpenJTalkRTCの使用方法を説明します。
OpenHRIのインストール方法や各フリーソフトの解説はこちらをご覧ください。
1. はじめに
OpenHRIの音声合成RTCである、OpenJTalkRTCを使用して音声合成システムを構築します。
作成するRTCは以下のようになります。
-
TimedStringConsoleIn
コンソールに入力された文字列をUTF-8形式でポートから出力します。
5. おわりに
OpenHRIの中の、OpenJTalkRTCを使って音声合成システムを作成しました。
本来、音声合成は高度な内容ですが、OpenHRIを使用することで簡単に実現することができました。
画面に文字を出力するのではなく、システムから音声が出力されることでデモンストレーションとしては見栄えがするものとなります。
ぜひ、自分のシステムに音声合成を利用してみください。
参考文献
-
「UTF-8エンコードについて」, 『RAPT's programing Tips Libraries』<http://www.atmark.gr.jp/~s2000/r/rtl/encode.html/>(2014/06/15アクセス)
それではソースコードを解説します。
-
1-23行目
Shift-JIS形式の文字列をUTF-8形式の文字列に変換する関数です[1]。
OpenJTalkRTCはUTF-8形式の文字列が必要となるため、このような変換が必要となります。
convert_Shift-JIS8toUTF8関数は以下のようになります。
UTF-8形式の文字列 convert_ShiftJIStoUTF8(Shift-JIS形式の文字列)
-
2-6行目
空の文字列の場合は、空の文字列を返します。
-
9行目
Shift-JIS形式の文字列を、いったんUnicodeに変換します。
まずは、以下の関数を使って変換後の文字列のサイズを求めます。
ワイド文字数 MultiByteToWideChar(コードページ,
文字の種類を指定するフラグ,
マップ元の文字列のアドレス,
マップ元の文字列のバイト数,
マップ先のワイド文字列を入れるバッファのアドレス,
バッファのサイズ)
コードページには、ANSIコードページ(Shift-JIS)を示す、CP_ACPを指定します。
文字の種類を指定するフラグに0を指定します。
マップ元の文字列のポインタを渡すために、c_str()メソッドを使用します。
マップ元の文字列のバイト数に-1を渡し、文字列の長さを自動的に計算してもらいます。
マップ元のワイド文字列を入れるバッファのアドレスにNULLを指定します。
バッファのサイズに0を指定することで、ワイド文字数を返します。
-
10行目
計算した文字列の長さ分だけ、WCHAR型の配列を動的に確保します。
-
11行目
先ほどの文字数の計算に使った、MultiByteToWideChar関数を使って文字列を変換します。
先ほどは指定しなかった、マップ先のワイド文字列を入れるバッファと、バッファのサイズを指定します。
-
14行目
UnicodeからUTF-8形式の文字列に変換します。
まずは、以下の関数を使って変換後の文字列のサイズを求めます。
バイト数 WideCharToMultiByte(コードページ,
文字の種類を指定するフラグ,
マップ元のワイド文字列のアドレス,
マップ元のワイド文字列のバイト数,
マップ先の文字列を入れるバッファのアドレス,
バッファのサイズ,
マップ出来ない文字の規定値のアドレス
既定の文字を使ったときにセットするフラグのアドレス)
コードページには、UTF-8を示す、CP_UTF8を指定します。
文字の種類を指定するフラグに0を指定します。
マップ元のワイド文字列のポインタを渡します。
マップ元のワイド文字列のバイト数に-1を渡し、文字列の長さを自動的に計算してもらいます。
マップ元の文字列を入れるバッファのアドレスにNULLを指定します。
バッファのサイズに0を指定することで、ワイド文字数を返します。
マップ出来ない文字の規定値のアドレスにNULLを指定します。
既定の文字を使ったときにセットするフラグのアドレスにNULLを指定します。
-
15行目
計算した文字列の長さ分だけ、char型の配列を動的に確保します。
-
16行目
先ほどの文字数の計算に使った、WideCharToMultiByte関数を使って文字列を変換します。
先ほどは指定しなかった、マップ先の文字列を入れるバッファと、バッファのサイズを指定します。
-
18行目
ワイド文字を格納していたWCHAR型の配列を開放します。
-
19行目
std::stringクラスにUTF-8に変換した文字列を格納します。
-
20行目
UTF-8の文字を格納していたchar型の配列を開放します。
-
21行目
std::stringクラスに格納したUTF-8形式の文字列を返します。
-
25-36行目
コンソールから入力された文字列をUTF-8形式のテキストデータとしてOutPortより出力します。
-
26-28行目
コンソール上にテキスト入力をうながし、std::stringクラスに格納します。
-
30行目
Shift-JIS形式の文字列を、UTF-8形式に変換します。
-
32-33行目
TimedString型の文字列データは、*char型である必要があるためc_str()メソッドを使用して値を渡します。
その後、OutPortから出力します。
以上で、TimedStringConsoleInのコーディングは終了です。
コードが入力し終わったら、ビルドを行ってください。
4. 動作確認
合成した音声を確認するためにスピーカーが必要ですので、PCにスピーカーを接続してください。
まず、ネームサービスとRT System Editorを実行します。
次に、作成したTimedStringConsoleInと、OpenJTalkRTC、PortAudioOutputを実行します。
OpenJTalkRTCとPortAudioOutputは64bitのWindowsでは、以下のの場所にあります。
各実行ファイルをダブルクリックして起動してください。
-
OpenJTalkRTC
C:\Program Files (x86)\OpenHRIVoice\openjtalkrtc.exe
-
PortAudioOutput
C:\Program Files (x86)\OpenHRIAudio\portaudiooutput.exe
各RTCを以下のように接続して、Activateしてください。
TimedStringConsoleInのコンソール上に、好きな日本語を入力してください。
入力された文字列が、男性が発話したような音声になってスピーカーから出力されるのが確認できると思います。
また、OpenJTalkRTCには、character、format、rateというコンフィグレーションが設定されています。
characterはデフォルトではmaleになっていますが、femaleに変更することで女性のような発話に変更することができます。
2. 音声合成システムの構成
コンソール上に入力された文字列を、音声合成するシステムを構築します。
構築するシステムは以下のようになっています。
-
OpenJTalkRTC
受け取ったテキストデータを音声データに変換して出力します。
-
PortAudioOutput
受け取った音声データをスピーカーのような音声出力デバイスから出力し、音を鳴らします。
-
TimeStringConsoleIn
コンソールから入力された文字列を出力します。


3. TimedStringConsoleIn RTC
TimedStringConsoleIn RTCを作成します。
テンプレートを以下に従って設定てください。
-
モジュール名
TimedStringConsoleIn
-
ベンダ名
あなたの名前
-
モジュールカテゴリ
Hobby
-
実行周期
1000
-
アクションコールバック
onInitialize
onExecute
-
データポート
・stringポート
ポート名(OutPort) string
データ型 TimedString
変数名 string
表示位置 RIGHT
-
言語
C++
プロジェクトの設定が終わったら、TimedStringConsoleIn.cppに以下のコードを記述します。
以下のコードは抜粋となります。生成したテンプレートに当てはめて下さい。