Ariver
2026-06-02 3fbceec8de833416bf1ae049f959f222c3f1a4a0
privatevoice.src/internal/audio/recorder.go
File was renamed from VoiceSnapGo/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