Skip to content

Commit

Permalink
Merge pull request #307 from uezo/fix-mic-volume-update
Browse files Browse the repository at this point in the history
Fix bug where mic volume changes are not applied immediately
  • Loading branch information
uezo committed Jun 29, 2024
2 parents 7165a1a + a0fcff4 commit ced025e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 67 deletions.
24 changes: 2 additions & 22 deletions Scripts/Dialog/RequestProvider/VoiceRequestProviderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<float> OnDetectVoice;
public Action<AudioClip> OnRecordingEnd = (a) => { Debug.Log("Recording voice request ended"); };
public Action<Exception> OnError = (e) => { Debug.LogError($"Recording voice request error: {e.Message}\n{e.StackTrace}"); };

// Actions for each status
#pragma warning disable CS1998
Expand Down Expand Up @@ -109,16 +99,6 @@ public virtual async UniTask<Request> 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
Expand Down
37 changes: 13 additions & 24 deletions Scripts/Dialog/WakeWordListener/WakeWordListenerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, UniTask> 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<float> OnDetectVoice;
public Action<AudioClip> OnRecordingEnd;
public Action<Exception> OnError = (e) => { Debug.LogError($"Recording wakeword error: {e.Message}\n{e.StackTrace}"); };

// Protected members for recording voice and recognize task
protected CancellationTokenSource cancellationTokenSource;

Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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)
Expand Down
57 changes: 36 additions & 21 deletions Scripts/IO/VoiceRecorderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<float> onDetectVoice;
protected Action<AudioClip> onRecordingEnd;
protected Action<Exception> 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<float> OnDetectVoice;
public Action<AudioClip> OnRecordingEnd;
public Action<Exception> OnError;

// Microphone controller
public Func<bool> UnmuteOnListeningStart { get; set; } = () => { return true; };
Expand All @@ -56,18 +56,18 @@ 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)
{
// Set recording starttime
recordingStartTime = Time.time;
// Invoke recording start event handler
onRecordingStart?.Invoke();
(OnRecordingStart ?? OnRecordingStartDefault).Invoke();
}
IsRecording = true;
lastVoiceDetectedTime = Time.time;
Expand All @@ -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();
}
Expand All @@ -104,7 +104,7 @@ private void LateUpdate()
catch (Exception ex)
{
StopListening();
onError?.Invoke(ex);
(OnError ?? OnErrorDefault).Invoke(ex);
}
}

Expand All @@ -129,7 +129,7 @@ public void StartListening()

// Recognized as listening started
IsListening = true;
onListeningStart?.Invoke();
OnListeningStart?.Invoke();
}

public void StopListening()
Expand All @@ -146,7 +146,7 @@ public void StopListening()

// Recognized as listening stopped
IsListening = false;
onListeningStop?.Invoke();
OnListeningStop?.Invoke();
}

public async UniTask<VoiceRecorderResponse> GetVoiceAsync(float timeout, CancellationToken token)
Expand Down Expand Up @@ -191,6 +191,21 @@ public async UniTask<VoiceRecorderResponse> 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
Expand Down

0 comments on commit ced025e

Please sign in to comment.