public IEnumerator TestAnimatedSay() { var model = GameObject.Find(Constants.ChatdollModelName)?.GetComponent <ModelController>(); if (model == null) { Debug.LogError("Chatdoll model not found"); yield break; } // Normal case var animatedVoiceRequest = new AnimatedVoiceRequest(); // 1st frame animatedVoiceRequest.AddVoiceTTS("これはアニメーションと声、表情のテストです。", description: "voice0101"); animatedVoiceRequest.AddAnimation("AGIA_Idle_classy_01_left_hand_on_waist", description: "animation0101"); animatedVoiceRequest.AddFace("LittleSmile", description: "face0101"); // 2nd frame animatedVoiceRequest.AddVoiceTTS("アニメーションと表情が途中で切り替わります。瞬きがとまっていることを確認してください。", description: "voice0201", postGap: 3.0f, asNewFrame: true); animatedVoiceRequest.AddAnimation("AGIA_Idle_calm_02_hands_on_front", duration: 2.0f, description: "animation0201"); animatedVoiceRequest.AddAnimation("AGIA_Idle_calm_01_hands_on_back", description: "animation0202"); animatedVoiceRequest.AddFace("Smile", duration: 3.0f, description: "face0201"); animatedVoiceRequest.AddFace("Neutral", description: "face0202"); var recorder = new ActionHistoryRecorder(true); model.History = recorder; var animTask = model.AnimatedSay(animatedVoiceRequest, CancellationToken.None); // Blink is disabled while talking yield return(new WaitForSeconds(1.0f)); // Wait 1sec to ensure start Assert.IsFalse(model.IsBlinkEnabled); // Wait for end yield return(new WaitUntil(() => animTask.IsCompleted)); // Confirm blink started yield return(new WaitForSeconds(0.1f)); Assert.IsTrue(model.IsBlinkEnabled); //var startTick = animationStartHistory.Timestamp; Assert.LessOrEqual(recorder.GetGapOfHistories("animation0101", "face0101"), 1); Assert.LessOrEqual(recorder.GetGapOfHistories("animation0101", "voice0101"), 1000); // 1000 = start delay by download tts :( // Start at the same time Assert.LessOrEqual(recorder.GetGapOfHistories("animation0201", "face0201"), 1); Assert.LessOrEqual(recorder.GetGapOfHistories("animation0201", "voice0201"), 1000); // 1000 = start delay by download tts :( // Duration Assert.GreaterOrEqual(recorder.GetGapOfHistories("animation0201", "animation0202"), 2000); Assert.LessOrEqual(recorder.GetGapOfHistories("animation0201", "animation0202"), 2100); Assert.GreaterOrEqual(recorder.GetGapOfHistories("face0201", "face0202"), 3000); Assert.LessOrEqual(recorder.GetGapOfHistories("face0201", "face0202"), 3100); // Interval to next case (idling) yield return(new WaitForSeconds(5.0f)); }
public IEnumerator TestAnimatedSayBlinking() { var model = GameObject.Find(Constants.ChatdollModelName)?.GetComponent <ModelController>(); if (model == null) { Debug.LogError("Chatdoll model not found"); yield break; } var animatedVoiceRequestNoBlink = new AnimatedVoiceRequest(disableBlink: false); animatedVoiceRequestNoBlink.AddVoiceTTS("これはまばたきをしながら、発話やアニメーションをするテストです。まばたきしていることを確認してください。"); animatedVoiceRequestNoBlink.AddAnimation("AGIA_Idle_classy_01_left_hand_on_waist"); animatedVoiceRequestNoBlink.AddFace("LittleSmile"); // Blinking before start Assert.IsTrue(model.IsBlinkEnabled); var animNBTask = model.AnimatedSay(animatedVoiceRequestNoBlink, CancellationToken.None); yield return(new WaitForSeconds(1.0f)); // Continue blinking while speaking Assert.IsTrue(model.IsBlinkEnabled); yield return(new WaitUntil(() => animNBTask.IsCompleted)); // Interval to next case (idling) yield return(new WaitForSeconds(5.0f)); }
public IEnumerator TestAnimatedSayCancel() { var model = GameObject.Find(Constants.ChatdollModelName)?.GetComponent <ModelController>(); if (model == null) { Debug.LogError("Chatdoll model not found"); yield break; } var cts = new CancellationTokenSource(); var animatedVoiceRequestToCancel = new AnimatedVoiceRequest(); animatedVoiceRequestToCancel.AddVoiceTTS("この話は途中でキャンセルされます。アニメーションも止まることを確認してください。そのため、最後まで聴けてしまったらテストは失敗ということになります。"); animatedVoiceRequestToCancel.AddAnimation("AGIA_Idle_classy_01_left_hand_on_waist"); animatedVoiceRequestToCancel.AddFace("Smile"); var animCancelTask = model.AnimatedSay(animatedVoiceRequestToCancel, cts.Token); // Cancel after continue animation 3 seconds yield return(new WaitForSeconds(5.0f)); cts.Cancel(); model.StopSpeech(); // Speech doesn't stop by canceling yield return(new WaitForSeconds(1.0f)); // Confirm that animation task is stopped Assert.IsTrue(animCancelTask.IsCompleted); // Interval to next case (idling) yield return(new WaitForSeconds(5.0f)); }
protected virtual void Awake() { // Get components chatdoll = gameObject.GetComponent <Chatdoll>(); modelController = gameObject.GetComponent <ModelController>(); voiceRequestProvider = gameObject.GetComponent <VoiceRequestProviderBase>(); cameraRequestProvider = gameObject.GetComponent <CameraRequestProvider>(); qrcodeRequestProvider = gameObject.GetComponent <QRCodeRequestProvider>(); wakeWordListener = GetComponent <WakeWordListenerBase>(); // Prompt var httpPrompter = gameObject.GetComponent <HttpPrompter>(); if (httpPrompter != null) { chatdoll.OnPromptAsync = httpPrompter.OnPromptAsync; } else { if (!string.IsNullOrEmpty(PromptVoice)) { if (PromptVoiceType == VoiceSource.Local) { PromptAnimatedVoiceRequest.AddVoice(PromptVoice); } else if (PromptVoiceType == VoiceSource.Web) { PromptAnimatedVoiceRequest.AddVoiceWeb(PromptVoice); } else if (PromptVoiceType == VoiceSource.TTS) { PromptAnimatedVoiceRequest.AddVoiceTTS(PromptVoice); } } if (!string.IsNullOrEmpty(PromptFace)) { PromptAnimatedVoiceRequest.AddFace(PromptFace); } if (!string.IsNullOrEmpty(PromptAnimation)) { PromptAnimatedVoiceRequest.AddAnimation(PromptAnimation); } chatdoll.OnPromptAsync = async(r, u, c, t) => { await modelController.AnimatedSay(PromptAnimatedVoiceRequest, t); }; } // Error chatdoll.OnErrorAsync = async(r, c, t) => { await modelController.AnimatedSay(ErrorAnimatedVoiceRequest, t); }; // Wakeword Listener if (wakeWordListener != null) { // Register wakeword if (wakeWordListener.WakeWords.Count == 0) { if (!string.IsNullOrEmpty(WakeWord)) { wakeWordListener.WakeWords.Add(new WakeWord() { Text = WakeWord, Intent = string.Empty }); } } // Register cancel word if (wakeWordListener.CancelWords.Count == 0) { if (!string.IsNullOrEmpty(CancelWord)) { wakeWordListener.CancelWords.Add(CancelWord); } } // Awaken wakeWordListener.OnWakeAsync = async(wakeword) => { var skipPrompt = false; Request preRequest = null; // Set request type, intent and inline request if set if (wakeword.RequestType != RequestType.None || !string.IsNullOrEmpty(wakeword.Intent) || !string.IsNullOrEmpty(wakeword.InlineRequestText)) { preRequest = new Request(wakeword.RequestType); preRequest.Intent = wakeword.Intent; if (!string.IsNullOrEmpty(wakeword.InlineRequestText)) { preRequest.Text = wakeword.InlineRequestText; skipPrompt = true; } } // Invoke chat await chatdoll.StartChatAsync(GetUserId(), skipPrompt, preRequest); }; // Cancel wakeWordListener.OnCancelAsync = async() => { chatdoll.StopChat(); }; // Raise voice detection threshold when chatting wakeWordListener.ShouldRaiseThreshold = () => { return(chatdoll.IsChatting); }; } // Voice Request Provider if (voiceRequestProvider != null) { // Set message window if (voiceRequestProvider.MessageWindow == null) { InstantiateMessageWindos(); voiceRequestProvider.MessageWindow = MessageWindow; } // Register cancel word to request provider if (voiceRequestProvider.CancelWords.Count == 0) { voiceRequestProvider.CancelWords.Add(CancelWord); } } // Camera and QRCode Request Provider if (cameraRequestProvider.ChatdollCamera == null) { InstantiateCamera(); cameraRequestProvider.ChatdollCamera = ChatdollCamera; } if (qrcodeRequestProvider.ChatdollCamera == null) { InstantiateCamera(); qrcodeRequestProvider.ChatdollCamera = ChatdollCamera; } }
public void AddFace(string name, float duration = 0.0f, string description = null, bool asNewFrame = false) { AnimatedVoiceRequest.AddFace(name, duration, description); }
public void TestAnimatedVoiceRequest() { var animatedVoiceRequest = new AnimatedVoiceRequest(); Assert.AreEqual(new Dictionary <string, List <AnimatedVoice> >(), animatedVoiceRequest.AnimatedVoices); Assert.IsTrue(animatedVoiceRequest.DisableBlink); Assert.IsTrue(animatedVoiceRequest.StartIdlingOnEnd); Assert.IsTrue(animatedVoiceRequest.StopIdlingOnStart); Assert.IsTrue(animatedVoiceRequest.StopLayeredAnimations); Assert.AreEqual(string.Empty, animatedVoiceRequest.BaseLayerName); // 1st frame animatedVoiceRequest.AddAnimation("Walk"); animatedVoiceRequest.AddAnimation("Run", 2.0f, 1.0f, 0.5f, 0.1f); animatedVoiceRequest.AddAnimation("WaveHands", "UpperBody", 3.0f, 2.0f, 0.8f, 0.2f, "upper animation"); animatedVoiceRequest.AddVoice("Hello"); animatedVoiceRequest.AddVoice("Goodby", 0.1f, 0.2f); animatedVoiceRequest.AddFace("Neutral"); animatedVoiceRequest.AddFace("Default", 0.1f, "default face"); // 2nd frame animatedVoiceRequest.AddAnimation("Jump", asNewFrame: true); animatedVoiceRequest.AddVoiceWeb("https://voice.local/goodmorning"); animatedVoiceRequest.AddVoiceWeb("https://voice.local/goodafternoon", 0.1f, 0.2f); animatedVoiceRequest.AddFace("Cry"); // 3rd frame var ttsConfig = new TTSConfiguration("TestTTSFuncName"); ttsConfig.Params.Add("key1", "val1"); ttsConfig.Params.Add("key2", 2.0f); animatedVoiceRequest.AddVoiceTTS("Good afternoon.", asNewFrame: true); animatedVoiceRequest.AddVoiceTTS("Good evening.", 0.1f, 0.2f, ttsConfig: ttsConfig); animatedVoiceRequest.AddAnimation("HandsFront"); animatedVoiceRequest.AddFace("Jito"); // 4th frame animatedVoiceRequest.AddFace("Surprise", asNewFrame: true); animatedVoiceRequest.AddVoice("GoodNight"); animatedVoiceRequest.AddAnimation("HandsBack"); // 1st frame var animation0101 = animatedVoiceRequest.AnimatedVoices[0].Animations[string.Empty][0]; Assert.AreEqual("Walk", animation0101.Name); Assert.AreEqual(string.Empty, animation0101.LayerName); Assert.AreEqual(0.0f, animation0101.Duration); Assert.AreEqual(-1.0f, animation0101.FadeLength); Assert.AreEqual(1.0f, animation0101.Weight); Assert.AreEqual(0.0f, animation0101.PreGap); Assert.IsNull(animation0101.Description); Assert.AreEqual(0.0f, animation0101.Length); var animation0102 = animatedVoiceRequest.AnimatedVoices[0].Animations[string.Empty][1]; Assert.AreEqual("Run", animation0102.Name); Assert.AreEqual(string.Empty, animation0102.LayerName); Assert.AreEqual(2.0f, animation0102.Duration); Assert.AreEqual(1.0f, animation0102.FadeLength); Assert.AreEqual(0.5f, animation0102.Weight); Assert.AreEqual(0.1f, animation0102.PreGap); Assert.IsNull(animation0102.Description); Assert.AreEqual(2.1f, animation0102.Length); var animation0103 = animatedVoiceRequest.AnimatedVoices[0].Animations["UpperBody"][0]; Assert.AreEqual("WaveHands", animation0103.Name); Assert.AreEqual("UpperBody", animation0103.LayerName); Assert.AreEqual(3.0f, animation0103.Duration); Assert.AreEqual(2.0f, animation0103.FadeLength); Assert.AreEqual(0.8f, animation0103.Weight); Assert.AreEqual(0.2f, animation0103.PreGap); Assert.AreEqual("upper animation", animation0103.Description); Assert.AreEqual(3.2f, animation0103.Length); var voice0101 = animatedVoiceRequest.AnimatedVoices[0].Voices[0]; Assert.AreEqual("Hello", voice0101.Name); Assert.AreEqual(0.0f, voice0101.PreGap); Assert.AreEqual(0.0f, voice0101.PostGap); Assert.IsNull(voice0101.Text); Assert.IsNull(voice0101.Url); Assert.IsNull(voice0101.TTSConfig); Assert.AreEqual(string.Empty, voice0101.GetTTSFunctionName()); Assert.IsNull(voice0101.GetTTSParam("key1")); Assert.AreEqual(VoiceSource.Local, voice0101.Source); Assert.IsFalse(voice0101.UseCache); var voice0102 = animatedVoiceRequest.AnimatedVoices[0].Voices[1]; Assert.AreEqual("Goodby", voice0102.Name); Assert.AreEqual(0.1f, voice0102.PreGap); Assert.AreEqual(0.2f, voice0102.PostGap); Assert.IsNull(voice0102.Text); Assert.IsNull(voice0102.Url); Assert.IsNull(voice0102.TTSConfig); Assert.AreEqual(string.Empty, voice0102.GetTTSFunctionName()); Assert.IsNull(voice0102.GetTTSParam("key1")); Assert.AreEqual(VoiceSource.Local, voice0102.Source); Assert.IsFalse(voice0102.UseCache); var face0101 = animatedVoiceRequest.AnimatedVoices[0].Faces[0]; Assert.AreEqual("Neutral", face0101.Name); Assert.AreEqual(0.0f, face0101.Duration); Assert.IsNull(face0101.Description); var face0102 = animatedVoiceRequest.AnimatedVoices[0].Faces[1]; Assert.AreEqual("Default", face0102.Name); Assert.AreEqual(0.1f, face0102.Duration); Assert.AreEqual("default face", face0102.Description); // 2nd frame var animation0201 = animatedVoiceRequest.AnimatedVoices[1].Animations[string.Empty][0]; Assert.AreEqual("Jump", animation0201.Name); var voice0201 = animatedVoiceRequest.AnimatedVoices[1].Voices[0]; Assert.AreEqual(string.Empty, voice0201.Name); Assert.AreEqual(0.0f, voice0201.PreGap); Assert.AreEqual(0.0f, voice0201.PostGap); Assert.IsNull(voice0201.Text); Assert.AreEqual("https://voice.local/goodmorning", voice0201.Url); Assert.IsNull(voice0201.TTSConfig); Assert.AreEqual(string.Empty, voice0201.GetTTSFunctionName()); Assert.IsNull(voice0201.GetTTSParam("key1")); Assert.AreEqual(VoiceSource.Web, voice0201.Source); Assert.IsTrue(voice0201.UseCache); Assert.AreEqual("https://voice.local/goodmorning", voice0201.CacheKey); var voice0202 = animatedVoiceRequest.AnimatedVoices[1].Voices[1]; Assert.AreEqual(string.Empty, voice0202.Name); Assert.AreEqual(0.1f, voice0202.PreGap); Assert.AreEqual(0.2f, voice0202.PostGap); Assert.IsNull(voice0202.Text); Assert.AreEqual("https://voice.local/goodafternoon", voice0202.Url); Assert.IsNull(voice0202.TTSConfig); Assert.AreEqual(string.Empty, voice0202.GetTTSFunctionName()); Assert.IsNull(voice0202.GetTTSParam("key1")); Assert.AreEqual(VoiceSource.Web, voice0202.Source); Assert.IsTrue(voice0202.UseCache); Assert.AreEqual("https://voice.local/goodafternoon", voice0202.CacheKey); var face0201 = animatedVoiceRequest.AnimatedVoices[1].Faces[0]; Assert.AreEqual("Cry", face0201.Name); // 3rd frame var voice0301 = animatedVoiceRequest.AnimatedVoices[2].Voices[0]; Assert.AreEqual(string.Empty, voice0301.Name); Assert.AreEqual(0.0f, voice0301.PreGap); Assert.AreEqual(0.0f, voice0301.PostGap); Assert.AreEqual("Good afternoon.", voice0301.Text); Assert.AreEqual(string.Empty, voice0301.Url); Assert.IsNull(voice0301.TTSConfig); Assert.AreEqual(VoiceSource.TTS, voice0301.Source); Assert.IsTrue(voice0301.UseCache); var voice0302 = animatedVoiceRequest.AnimatedVoices[2].Voices[1]; Assert.AreEqual(string.Empty, voice0302.Name); Assert.AreEqual(0.1f, voice0302.PreGap); Assert.AreEqual(0.2f, voice0302.PostGap); Assert.AreEqual("Good evening.", voice0302.Text); Assert.AreEqual(string.Empty, voice0302.Url); Assert.AreEqual("TestTTSFuncName", voice0302.GetTTSFunctionName()); Assert.AreEqual("val1", voice0302.GetTTSParam("key1")); Assert.AreEqual(2.0f, voice0302.GetTTSParam("key2")); Assert.AreEqual(VoiceSource.TTS, voice0302.Source); Assert.IsTrue(voice0302.UseCache); var animation0301 = animatedVoiceRequest.AnimatedVoices[2].Animations[string.Empty][0]; Assert.AreEqual("HandsFront", animation0301.Name); var face0301 = animatedVoiceRequest.AnimatedVoices[2].Faces[0]; Assert.AreEqual("Jito", face0301.Name); // 4th frame var face0401 = animatedVoiceRequest.AnimatedVoices[3].Faces[0]; Assert.AreEqual("Surprise", face0401.Name); var voice0401 = animatedVoiceRequest.AnimatedVoices[3].Voices[0]; Assert.AreEqual("GoodNight", voice0401.Name); var animation0401 = animatedVoiceRequest.AnimatedVoices[3].Animations[string.Empty][0]; Assert.AreEqual("HandsBack", animation0401.Name); }