From 5fbe9789faf05ce99bbff6ec4cd0b905519acbd0 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Fri, 03 Jul 2026 05:18:07 +0800
Subject: [PATCH] Freeze R221 2.2.2 source baseline

---
 C1.source/privatevoice.src/internal/audio/recorder.go |   41 +++++++++++++++++++++++++++++++++++++----
 1 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/C1.source/privatevoice.src/internal/audio/recorder.go b/C1.source/privatevoice.src/internal/audio/recorder.go
index 5842248..9cf8b92 100755
--- a/C1.source/privatevoice.src/internal/audio/recorder.go
+++ b/C1.source/privatevoice.src/internal/audio/recorder.go
@@ -10,11 +10,17 @@
 )
 
 const (
-	sampleRate       = 16000
-	channels         = 1
-	bitsPerSample    = 16
-	silenceThreshold = 0.05
+	sampleRate            = 16000
+	channels              = 1
+	bitsPerSample         = 16
+	silenceThreshold      = 0.05
+	maxRecordingSeconds   = 15 * 60
+	maxPCMBufferBytes     = sampleRate * channels * (bitsPerSample / 8) * maxRecordingSeconds
+	MaxRecordingDuration  = time.Duration(maxRecordingSeconds) * time.Second
+	maxPendingDeviceStops = 2
 )
+
+var pendingDeviceStops = make(chan struct{}, maxPendingDeviceStops)
 
 // InputDevice represents an audio input device.
 type InputDevice struct {
@@ -37,6 +43,7 @@
 
 	// State
 	isRecording    bool
+	bufferLimitHit bool
 	maxVolume      float64
 	currentVolume  float64
 	volumeCallback func(float64)
@@ -106,6 +113,7 @@
 	}
 
 	r.pcmBuf = nil
+	r.bufferLimitHit = false
 	r.maxVolume = 0
 	r.currentVolume = 0
 
@@ -249,8 +257,18 @@
 	if device == nil {
 		return
 	}
+	select {
+	case pendingDeviceStops <- struct{}{}:
+	case <-time.After(100 * time.Millisecond):
+		logger.Error("Audio device stop queue saturated; stopping synchronously")
+		stopAndUninitDevice(device)
+		return
+	}
 	done := make(chan struct{})
 	go func() {
+		defer func() {
+			<-pendingDeviceStops
+		}()
 		stopAndUninitDevice(device)
 		close(done)
 	}()
@@ -296,6 +314,21 @@
 	}
 
 	// Append raw PCM data
+	if len(r.pcmBuf) >= maxPCMBufferBytes {
+		if !r.bufferLimitHit {
+			logger.Error("Recording buffer limit reached; dropping additional audio max_seconds=%d", maxRecordingSeconds)
+			r.bufferLimitHit = true
+		}
+		r.mu.Unlock()
+		return
+	}
+	if len(r.pcmBuf)+len(input) > maxPCMBufferBytes {
+		input = input[:maxPCMBufferBytes-len(r.pcmBuf)]
+		if !r.bufferLimitHit {
+			logger.Error("Recording buffer limit reached; truncating audio max_seconds=%d", maxRecordingSeconds)
+			r.bufferLimitHit = true
+		}
+	}
 	r.pcmBuf = append(r.pcmBuf, input...)
 
 	// Calculate RMS volume

--
Gitblit v1.9.3