| | |
| | | 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 { |
| | |
| | | |
| | | // State |
| | | isRecording bool |
| | | bufferLimitHit bool |
| | | maxVolume float64 |
| | | currentVolume float64 |
| | | volumeCallback func(float64) |
| | |
| | | } |
| | | |
| | | r.pcmBuf = nil |
| | | r.bufferLimitHit = false |
| | | r.maxVolume = 0 |
| | | r.currentVolume = 0 |
| | | |
| | |
| | | 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) |
| | | }() |
| | |
| | | } |
| | | |
| | | // 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 |