この記事は、公開時点での NUWA Robotics 社製のロボット Kebbi Air に表情付きでしゃべってもらう方法の覚書です。
NuwaRobotAPIのJavaDocの内容をもとに作成しています。
NUWA Robot SDK の使い方についてはこちらを参照ください。
KebbiのTTS機能
TTS とは、Text to Speech の略で、指定した文章を自然に読み上げる機能です。文ごとに以下のパラメータを設定することができます。
-
locale
(読み上げ言語) -
volume
(声の大きさ) -
pitch
(声の高さ・抑揚) -
speed
(話す速さ) -
gain
(2024年12月現在はサポートされていないパラメータのようです)
Kebbi の TTS はstartTTS
という関数を呼び出すことで実行できます。locale
はstartTTS
内で指定しますが,他のパラメータ指定はsetSpeakParameter
という別の関数で行います。
TTS機能の使い方
サンプルコードはMainActivity
クラスの中で実装することを想定しています。
// APIを使用するための前準備
IClientId clientId = new IClientId(this.getPackageName());
NuwaRobotAPI robotAPI = new NuwaRobotAPI(this,clientId);
// パラメータを設定
robotAPI.setSpeakParameter(NORMAL, "isForced", "true"); // パラメータを反映させるための命令
robotAPI.setSpeakParameter(NORMAL, "speed", "100"); // 50~200の間で、何故か文字列で設定
// 読み上げる言葉を設定
robotAPI.startTTS("初めまして、私はKebbiです");
// 読み上げる文の先頭に"//"を入れることで、文をディスプレイに表示させずにしゃべらせることができます。
robotAPI.startTTS("//" + "今話していることはディスプレイに表示されません");
TTSが完了すると、VoiceEventListener
のonTTSComplete
がコールバックされます。
// VoiceEventListener
robotAPI.registerVoiceEventListener(new VoiceEventListener() {
@Override
public void onTTSComplete(boolean b) {
// Kebbiがしゃべり終えたらどうするかを記述
}
}
コールバックを利用して別々のパラメータの言葉を続けてしゃべらせることもできます。次がそのサンプルコードです。
// しゃべる内容とパラメータ
private int step = 0;
ArrayList<String> text = new ArrayList<String>() {{
add("初めまして");
add("//わたしはケビーです");
}};
ArrayList<String> speed = new ArrayList<String>() {{
add("100");
add("150");
}};
private void tts(String current_text, String current_speed){
robotAPI.setSpeakParameter(NORMAL, "speed", current_speed);
robotAPI.startTTS(current_text);
}
// VoiceEventListener
robotAPI.registerVoiceEventListener(new VoiceEventListener() {
@Override
public void onTTSComplete(boolean b) {
step++;
if(step<text.size())
tts(text.get(step), speed.get(step));
}
}
Kebbiの表情を制御する
Kebbiの表情は、顔全体と口元の2種類を設定することができます。playFaceAnimation
を使用して顔全体を、mouthEmotionOn
を使用して口元を設定することができます。(それぞれのプレビューはこちら:faceAnimation, mouthEmotion)
表情制御の使い方
サンプルコードはMainActivity
クラスの中で実装することを想定しています。
// APIを使用するための前準備(TTSと同様、プロジェクト中に1つだけ書いてあればOK)
IClientId clientId = new IClientId(this.getPackageName());
NuwaRobotAPI robotAPI = new NuwaRobotAPI(this,clientId);
// 表情制御のための準備
robotAPI.initFaceControl(context, context.getClass().getName(), FaceControlConnect);
robotAPI.UnityFaceManager().showUnity();
// パラメータを設定
robotAPI.UnityFaceManager().playFaceAnimation(faceExpression);
robotAPI.UnityFaceManager().mouthEmotionOn(75, mouthExpression); // 1つ目の引数で口の動きの速さを設定
// 表情をデフォルト状態にリセット
robotAPI.UnityFaceManager().playFaceAnimationDefault();
robotAPI.UnityFaceManager().mouthOff();
Kebbiに表情付きでしゃべらせる
以上を踏まえて、表情付きでしゃべるようにしてみましょう。組み合わせると次のようになります。
// APIを使用するための前準備
IClientId clientId = new IClientId(this.getPackageName());
NuwaRobotAPI robotAPI = new NuwaRobotAPI(this,clientId);
private void speak(){
// 表情制御のための準備
robotAPI.initFaceControl(context, context.getClass().getName(), FaceControlConnect);
robotAPI.UnityFaceManager().showUnity();
// TTSパラメータを設定
robotAPI.setSpeakParameter(NORMAL, "isForced", "true"); // パラメータを反映させるための命令
robotAPI.setSpeakParameter(NORMAL, "speed", "100"); // 50~200の間で、何故か文字列で設定
// 表情を設定
robotAPI.UnityFaceManager().playFaceAnimation(faceExpression);
robotAPI.UnityFaceManager().mouthEmotionOn(75, mouthExpression); // 1つ目の引数で口の動きの速さを設定
// 読み上げる言葉を設定
robotAPI.startTTS("初めまして、私はKebbiです");
}
// VoiceEventListener
robotAPI.registerVoiceEventListener(new VoiceEventListener() {
@Override
public void onTTSComplete(boolean b) {
// 表情をデフォルト状態にリセット
robotAPI.UnityFaceManager().playFaceAnimationDefault();
robotAPI.UnityFaceManager().mouthOff();
}
}
このように、しゃべり終えた段階で表情をデフォルトに戻すようにしてやると、TTSの例のように言葉ごとに表情を変えたり、間を作りたいときに口パク状態にならなかったりと利点があります。
おわりに
以上でNUWA Robot SDKを用いてKebbiに好きな言葉をしゃべらせることができるようになりました。実際に活用するときは他の動作や処理に合わせて使うことになると思うので、handlerで管理すると良いと思います。
記述に不明点、誤り等見つけましたらお知らせください。よろしくお願いいたします。
制御しようと思って実現できなかったこと
しゃべりの抑揚のみの変更
TTSエンジンの都合でパラメータpitch
を使用すると声調と抑揚の両方が設定されるらしく、個別の調整はできないとのことでした。
しゃべっていない状態での表情の変更
faceAnimationのプレビューを見てわかるように、表情は口元のモーションもセットのようです。口元の動きは mouthEmotionで上書きが可能ですが、口元を消すことはできませんでした。よってしゃべっていない状態での表情はデフォルトのものしか設定できません。
トラブルシューティング
TTSのパラメータを設定したのに反映されない
TTS機能の使い方セクションのサンプルコードを参考に、APIを使用するための前準備やsetSpeakParameter
の引数がNORMAL
になっているか、true
になっているかを確認してください。isForced
はfalse
に戻すまでに1度呼べば大丈夫です。
顔が表示されない
表情制御のセクションのサンプルコードを参考に、APIを使用するための前準備やinitFaceControl
、showUnity
が呼び出されているかを確認してください。これらも1度呼べば大丈夫です。