From 14f801be6ea478678209c381fd188d7a58eadf93 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Mon, 18 May 2026 01:29:40 +0800
Subject: [PATCH] fix: avoid recorder stop deadlock
---
VoiceSnapGo/internal/audio/recorder.go | 59 +++++++++++++++++++++++++++++++++++++----------------------
1 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/VoiceSnapGo/internal/audio/recorder.go b/VoiceSnapGo/internal/audio/recorder.go
index 94bdd10..43dc995 100755
--- a/VoiceSnapGo/internal/audio/recorder.go
+++ b/VoiceSnapGo/internal/audio/recorder.go
@@ -9,9 +9,9 @@
)
const (
- sampleRate = 16000
- channels = 1
- bitsPerSample = 16
+ sampleRate = 16000
+ channels = 1
+ bitsPerSample = 16
silenceThreshold = 0.05
)
@@ -25,8 +25,8 @@
type Recorder struct {
mu sync.Mutex
- ctx *malgo.AllocatedContext
- device *malgo.Device
+ ctx *malgo.AllocatedContext
+ device *malgo.Device
// PCM buffer (16-bit signed, little-endian)
pcmBuf []byte
@@ -35,11 +35,11 @@
preferredDevice string
// State
- isRecording bool
- maxVolume float64
- currentVolume float64
- volumeCallback func(float64)
- deviceChangeCb func(string)
+ isRecording bool
+ maxVolume float64
+ currentVolume float64
+ volumeCallback func(float64)
+ deviceChangeCb func(string)
}
// NewRecorder creates a new audio recorder backed by malgo.
@@ -151,19 +151,21 @@
// Stop stops recording and discards audio data.
func (r *Recorder) Stop() {
+ device := r.detachDevice()
+ stopAndUninitDevice(device)
+
r.mu.Lock()
defer r.mu.Unlock()
-
- r.stopDevice()
r.pcmBuf = nil
}
// StopAndGetSamples stops recording and returns the captured audio as float32 samples.
func (r *Recorder) StopAndGetSamples() []float32 {
+ device := r.detachDevice()
+ stopAndUninitDevice(device)
+
r.mu.Lock()
defer r.mu.Unlock()
-
- r.stopDevice()
if len(r.pcmBuf) < 2 {
return nil
@@ -203,23 +205,36 @@
// Close releases all audio resources.
func (r *Recorder) Close() {
+ device := r.detachDevice()
+ stopAndUninitDevice(device)
+
r.mu.Lock()
defer r.mu.Unlock()
-
- r.stopDevice()
if r.ctx != nil {
r.ctx.Free()
r.ctx = nil
}
}
-func (r *Recorder) stopDevice() {
- if r.device != nil {
- r.device.Stop()
- r.device.Uninit()
- r.device = nil
- }
+func (r *Recorder) detachDevice() *malgo.Device {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+
+ device := r.device
+ r.device = nil
r.isRecording = false
+ return device
+}
+
+func stopAndUninitDevice(device *malgo.Device) {
+ if device == nil {
+ return
+ }
+ logger.Info("Stopping audio device")
+ device.Stop()
+ logger.Info("Audio device stopped")
+ device.Uninit()
+ logger.Info("Audio device uninitialized")
}
func (r *Recorder) onData(input []byte) {
--
Gitblit v1.9.3