diff --git a/Scripts/Dialog/RequestProvider/VoiceRequestProviderBase.cs b/Scripts/Dialog/RequestProvider/VoiceRequestProviderBase.cs index 6b7dc72..293b5af 100644 --- a/Scripts/Dialog/RequestProvider/VoiceRequestProviderBase.cs +++ b/Scripts/Dialog/RequestProvider/VoiceRequestProviderBase.cs @@ -10,6 +10,8 @@ namespace ChatdollKit.Dialog { public class VoiceRequestProviderBase : VoiceRecorderBase, IVoiceRequestProvider { + public float ListeningTimeout = 20.0f; + // This provides voice request public RequestType RequestType { get; } = RequestType.Voice; @@ -20,22 +22,10 @@ public class VoiceRequestProviderBase : VoiceRecorderBase, IVoiceRequestProvider [Header("Test and Debug")] public bool PrintResult = false; - [Header("Voice Recorder Settings")] - public float VoiceDetectionThreshold = -50.0f; - public float VoiceDetectionMinimumLength = 0.3f; - public float SilenceDurationToEndRecording = 1.0f; - public float ListeningTimeout = 20.0f; - [Header("UI")] public IMessageWindow MessageWindow; [SerializeField] protected string listeningMessage = "[ Listening ... ]"; - public Action OnListeningStart; - public Action OnListeningStop; - public Action OnRecordingStart = () => { Debug.Log("Recording voice request started"); }; - public Action OnDetectVoice; - public Action OnRecordingEnd = (a) => { Debug.Log("Recording voice request ended"); }; - public Action OnError = (e) => { Debug.LogError($"Recording voice request error: {e.Message}\n{e.StackTrace}"); }; // Actions for each status #pragma warning disable CS1998 @@ -109,16 +99,6 @@ public virtual async UniTask GetRequestAsync(CancellationToken token) var request = new Request(RequestType); - voiceDetectionThreshold = VoiceDetectionThreshold; - voiceDetectionMinimumLength = VoiceDetectionMinimumLength; - silenceDurationToEndRecording = SilenceDurationToEndRecording; - onListeningStart = OnListeningStart; - onListeningStop = OnListeningStop; - onRecordingStart = OnRecordingStart; - onDetectVoice = OnDetectVoice; - onRecordingEnd = OnRecordingEnd; - onError = OnError; - StartListening(); try diff --git a/Scripts/Dialog/WakeWordListener/WakeWordListenerBase.cs b/Scripts/Dialog/WakeWordListener/WakeWordListenerBase.cs index 08837e4..bc9c2ff 100644 --- a/Scripts/Dialog/WakeWordListener/WakeWordListenerBase.cs +++ b/Scripts/Dialog/WakeWordListener/WakeWordListenerBase.cs @@ -10,26 +10,15 @@ namespace ChatdollKit.Dialog { public class WakeWordListenerBase : VoiceRecorderBase, IWakeWordListener { + public float VoiceDetectionRaisedThreshold = -15.0f; + public float VoiceRecognitionMaximumLength = 3.0f; + public bool AutoStart = true; public Func OnRecognizedAsync; [Header("Test and Debug")] public bool PrintResult = false; - [Header("Voice Recorder Settings")] - public float VoiceDetectionThreshold = -50.0f; - public float VoiceDetectionRaisedThreshold = -15.0f; - public float VoiceDetectionMinimumLength = 0.2f; - public float SilenceDurationToEndRecording = 0.3f; - public float VoiceRecognitionMaximumLength = 3.0f; - - public Action OnListeningStart; - public Action OnListeningStop; - public Action OnRecordingStart; - public Action OnDetectVoice; - public Action OnRecordingEnd; - public Action OnError = (e) => { Debug.LogError($"Recording wakeword error: {e.Message}\n{e.StackTrace}"); }; - // Protected members for recording voice and recognize task protected CancellationTokenSource cancellationTokenSource; @@ -70,7 +59,7 @@ protected virtual void Start() protected virtual void Update() { // Observe which threshold should be applied in every frames - voiceDetectionThreshold = ShouldRaiseThreshold() ? VoiceDetectionRaisedThreshold : VoiceDetectionThreshold; + VoiceDetectionThreshold = ShouldRaiseThreshold() ? VoiceDetectionRaisedThreshold : VoiceDetectionThreshold; } protected override void OnDestroy() @@ -140,15 +129,15 @@ protected virtual async UniTask StartListeningAsync() while (!token.IsCancellationRequested) { - voiceDetectionThreshold = VoiceDetectionThreshold; - voiceDetectionMinimumLength = VoiceDetectionMinimumLength; - silenceDurationToEndRecording = SilenceDurationToEndRecording; - onListeningStart = OnListeningStart; - onListeningStop = OnListeningStop; - onRecordingStart = OnRecordingStart; - onDetectVoice = OnDetectVoice; - onRecordingEnd = OnRecordingEnd; - onError = OnError; + //voiceDetectionThreshold = VoiceDetectionThreshold; + //voiceDetectionMinimumLength = VoiceDetectionMinimumLength; + //silenceDurationToEndRecording = SilenceDurationToEndRecording; + //onListeningStart = OnListeningStart; + //onListeningStop = OnListeningStop; + //onRecordingStart = OnRecordingStart; + //onDetectVoice = OnDetectVoice; + //onRecordingEnd = OnRecordingEnd; + //onError = OnError; var voiceRecorderResponse = await GetVoiceAsync(0.0f, token); if (voiceRecorderResponse != null) diff --git a/Scripts/IO/VoiceRecorderBase.cs b/Scripts/IO/VoiceRecorderBase.cs index dba783c..7dd2c87 100644 --- a/Scripts/IO/VoiceRecorderBase.cs +++ b/Scripts/IO/VoiceRecorderBase.cs @@ -22,16 +22,16 @@ public class VoiceRecorderBase : MonoBehaviour private float recordingStartTime; // Runtime configurations - protected float voiceDetectionThreshold; - protected float voiceDetectionMaxThreshold = 0.7f; - protected float voiceDetectionMinimumLength; - protected float silenceDurationToEndRecording; - protected Action onListeningStart; - protected Action onListeningStop; - protected Action onRecordingStart; - protected Action onDetectVoice; - protected Action onRecordingEnd; - protected Action onError; + [Header("Voice Recorder Settings")] + public float VoiceDetectionThreshold = -50.0f; + public float VoiceDetectionMinimumLength = 0.3f; + public float SilenceDurationToEndRecording = 1.0f; + public Action OnListeningStart; + public Action OnListeningStop; + public Action OnRecordingStart; + public Action OnDetectVoice; + public Action OnRecordingEnd; + public Action OnError; // Microphone controller public Func UnmuteOnListeningStart { get; set; } = () => { return true; }; @@ -56,10 +56,10 @@ private void LateUpdate() // Handle recorded voice recordedData.AddRange(capturedData.Data); - if (capturedData.Volume > voiceDetectionThreshold && capturedData.Volume < voiceDetectionMaxThreshold) + if (capturedData.Volume > VoiceDetectionThreshold) { IsDetectingVoice = true; - onDetectVoice?.Invoke(capturedData.Volume); + OnDetectVoice?.Invoke(capturedData.Volume); // Start or continue recording when the volume of captured sound is larger than threshold if (!IsRecording) @@ -67,7 +67,7 @@ private void LateUpdate() // Set recording starttime recordingStartTime = Time.time; // Invoke recording start event handler - onRecordingStart?.Invoke(); + (OnRecordingStart ?? OnRecordingStartDefault).Invoke(); } IsRecording = true; lastVoiceDetectedTime = Time.time; @@ -77,20 +77,20 @@ private void LateUpdate() IsDetectingVoice = false; if (IsRecording) { - if (Time.time - lastVoiceDetectedTime >= silenceDurationToEndRecording) + if (Time.time - lastVoiceDetectedTime >= SilenceDurationToEndRecording) { // End recording when silence is longer than configured duration IsRecording = false; - var recordedLength = recordedData.Count / (float)(capturedData.Frequency * capturedData.ChannelCount) - silenceDurationToEndRecording; - if (recordedLength >= voiceDetectionMinimumLength) + var recordedLength = recordedData.Count / (float)(capturedData.Frequency * capturedData.ChannelCount) - SilenceDurationToEndRecording; + if (recordedLength >= VoiceDetectionMinimumLength) { lastRecordedVoice = new VoiceRecorderResponse(recordingStartTime, recordedData, capturedData.ChannelCount, capturedData.Frequency); - onRecordingEnd?.Invoke(lastRecordedVoice.Voice); + (OnRecordingEnd ?? OnRecordingEndDefault).Invoke(lastRecordedVoice.Voice); } else { - onRecordingEnd?.Invoke(null); + (OnRecordingEnd ?? OnRecordingEndDefault).Invoke(null); } recordedData.Clear(); } @@ -104,7 +104,7 @@ private void LateUpdate() catch (Exception ex) { StopListening(); - onError?.Invoke(ex); + (OnError ?? OnErrorDefault).Invoke(ex); } } @@ -129,7 +129,7 @@ public void StartListening() // Recognized as listening started IsListening = true; - onListeningStart?.Invoke(); + OnListeningStart?.Invoke(); } public void StopListening() @@ -146,7 +146,7 @@ public void StopListening() // Recognized as listening stopped IsListening = false; - onListeningStop?.Invoke(); + OnListeningStop?.Invoke(); } public async UniTask GetVoiceAsync(float timeout, CancellationToken token) @@ -191,6 +191,21 @@ public async UniTask GetVoiceAsync(float timeout, Cancell return null; } + + protected virtual void OnRecordingStartDefault() + { + Debug.Log($"Recording start: {gameObject.name}"); + } + + protected virtual void OnRecordingEndDefault(AudioClip audioClip) + { + Debug.Log($"Recording end: {gameObject.name}"); + } + + protected virtual void OnErrorDefault(Exception ex) + { + Debug.LogError($"Recording error at {gameObject.name}: {ex.Message}\n{ex.StackTrace}"); + } } public class VoiceRecorderResponse