From 3fbceec8de833416bf1ae049f959f222c3f1a4a0 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Tue, 02 Jun 2026 14:05:59 +0800
Subject: [PATCH] Prepare Round 1 model profile QA baseline

---
 privatevoice.src/internal/audio/recorder.go |   53 ++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/VoiceSnapGo/internal/audio/recorder.go b/privatevoice.src/internal/audio/recorder.go
similarity index 87%
rename from VoiceSnapGo/internal/audio/recorder.go
rename to privatevoice.src/internal/audio/recorder.go
index 43dc995..bef4072 100755
--- a/VoiceSnapGo/internal/audio/recorder.go
+++ b/privatevoice.src/internal/audio/recorder.go
@@ -3,6 +3,7 @@
 import (
 	"math"
 	"sync"
+	"time"
 	"voicesnap/internal/logger"
 
 	"github.com/gen2brain/malgo"
@@ -151,36 +152,28 @@
 
 // Stop stops recording and discards audio data.
 func (r *Recorder) Stop() {
-	device := r.detachDevice()
-	stopAndUninitDevice(device)
-
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	r.pcmBuf = nil
+	device, _ := r.detachDeviceAndPCM()
+	stopAndUninitDeviceAsync(device)
 }
 
 // StopAndGetSamples stops recording and returns the captured audio as float32 samples.
 func (r *Recorder) StopAndGetSamples() []float32 {
-	device := r.detachDevice()
-	stopAndUninitDevice(device)
+	device, pcm := r.detachDeviceAndPCM()
+	stopAndUninitDeviceAsync(device)
 
-	r.mu.Lock()
-	defer r.mu.Unlock()
-
-	if len(r.pcmBuf) < 2 {
+	if len(pcm) < 2 {
 		return nil
 	}
 
 	// Convert 16-bit PCM to float32
-	numSamples := len(r.pcmBuf) / 2
+	numSamples := len(pcm) / 2
 	samples := make([]float32, numSamples)
 	for i := 0; i < numSamples; i++ {
-		sample := int16(r.pcmBuf[i*2]) | int16(r.pcmBuf[i*2+1])<<8
+		sample := int16(pcm[i*2]) | int16(pcm[i*2+1])<<8
 		samples[i] = float32(sample) / 32768.0
 	}
 
 	logger.Info("Recording stopped, %d samples captured", numSamples)
-	r.pcmBuf = nil
 	return samples
 }
 
@@ -226,6 +219,36 @@
 	return device
 }
 
+func (r *Recorder) detachDeviceAndPCM() (*malgo.Device, []byte) {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+
+	device := r.device
+	r.device = nil
+	r.isRecording = false
+	pcm := append([]byte(nil), r.pcmBuf...)
+	r.pcmBuf = nil
+	return device, pcm
+}
+
+func stopAndUninitDeviceAsync(device *malgo.Device) {
+	if device == nil {
+		return
+	}
+	done := make(chan struct{})
+	go func() {
+		stopAndUninitDevice(device)
+		close(done)
+	}()
+	go func() {
+		select {
+		case <-done:
+		case <-time.After(2 * time.Second):
+			logger.Error("Audio device stop is still pending; continuing without blocking UI")
+		}
+	}()
+}
+
 func stopAndUninitDevice(device *malgo.Device) {
 	if device == nil {
 		return

--
Gitblit v1.9.3