diff --git a/Assets/Mochineko/VoiceActivityDetection/UnityMicrophoneSource.cs b/Assets/Mochineko/VoiceActivityDetection/UnityMicrophoneSource.cs index 0f4f2e1..bef01af 100644 --- a/Assets/Mochineko/VoiceActivityDetection/UnityMicrophoneSource.cs +++ b/Assets/Mochineko/VoiceActivityDetection/UnityMicrophoneSource.cs @@ -19,6 +19,8 @@ public sealed class UnityMicrophoneSource : IVoiceSource private int lastPosition; private bool isActive = true; + private readonly object lockObject = new(); + private readonly Subject onSegmentRead = new(); IObservable IVoiceSource.OnSegmentRead => onSegmentRead; @@ -37,7 +39,8 @@ public UnityMicrophoneSource( { if (readBufferSize <= 0) { - throw new ArgumentOutOfRangeException(nameof(readBufferSize), readBufferSize, "Read buffer size must be greater than 0."); + throw new ArgumentOutOfRangeException(nameof(readBufferSize), readBufferSize, + "Read buffer size must be greater than 0."); } this.proxy = proxy; @@ -54,32 +57,35 @@ void IDisposable.Dispose() void IVoiceSource.Update() { - currentPosition = this.proxy.GetSamplePosition(); - if (currentPosition < 0) + lock (lockObject) { - lastPosition = 0; - return; - } + currentPosition = this.proxy.GetSamplePosition(); + if (currentPosition < 0) + { + lastPosition = 0; + return; + } - if (!isActive) - { - return; - } + if (!isActive) + { + return; + } - // No update of microphone audio - if (currentPosition == lastPosition) - { - return; - } + // No update of microphone audio + if (currentPosition == lastPosition) + { + return; + } - // Write current all data to loop buffer - this.audioClip.GetData(this.loopBuffer, offsetSamples: 0); + // Write current all data to loop buffer + this.audioClip.GetData(this.loopBuffer, offsetSamples: 0); - // Read samples from last position to current position - ReadCurrentSamples(); + // Read samples from last position to current position + ReadCurrentSamples(); - // Update last position - lastPosition = currentPosition; + // Update last position + lastPosition = currentPosition; + } } void IVoiceSource.SetSourceActive(bool isActive) diff --git a/Assets/Mochineko/VoiceActivityDetection/package.json b/Assets/Mochineko/VoiceActivityDetection/package.json index fe6540f..fecd6c4 100644 --- a/Assets/Mochineko/VoiceActivityDetection/package.json +++ b/Assets/Mochineko/VoiceActivityDetection/package.json @@ -1,6 +1,6 @@ { "name": "com.mochineko.voice-activity-detection", - "version": "0.3.1", + "version": "0.3.2", "displayName": "Voice Activity Detection", "description": "A voice activity detection library for Unity.", "unity": "2022.3", diff --git a/CHANGELOG.md b/CHANGELOG.md index fc2cf37..6d11564 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.3.2] - 2023-09-05 + +### Fixed +- Fix multi-thread conflict in `UnityMicrophoneSource.Update`. + ## [0.3.1] - 2023-08-01 -## Changed +### Changed - Improve timing to change flag of voice activity in `QueueingVoiceActivityDetector`. - Introduce array pool to avoid conflicting resources with multi-threading. diff --git a/README.md b/README.md index e874ef2..32bab47 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Add following dependencies to your `/Packages/manifest.json`. ```json { "dependencies": { - "com.mochineko.voice-activity-detection": "https://github.com/mochi-neko/voice-activity-detection-unity.git?path=/Assets/Mochineko/VoiceActivityDetection#0.3.1", + "com.mochineko.voice-activity-detection": "https://github.com/mochi-neko/voice-activity-detection-unity.git?path=/Assets/Mochineko/VoiceActivityDetection#0.3.2", "com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask", "com.neuecc.unirx": "https://github.com/neuecc/UniRx.git?path=Assets/Plugins/UniRx/Scripts", "com.naudio.core": "https://github.com/mochi-neko/simple-audio-codec-unity.git?path=/Assets/NAudio/NAudio.Core#0.2.0",