Fix speech recognition crash from audio format mismatch

Switch audio session to .record-only, use nil tap format so the system
picks a compatible format, and route through AVAudioEngine with a 4096
buffer. Avoids the mDataByteSize(0) assertion seen on some devices.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-04-19 15:22:45 -05:00
parent 5ba76a947b
commit f809bc2a1d

View File

@@ -65,28 +65,26 @@ final class PronunciationService {
do {
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playAndRecord, mode: .measurement, options: [.duckOthers, .defaultToSpeaker])
try audioSession.setCategory(.record, mode: .measurement, options: [.duckOthers])
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
audioEngine = AVAudioEngine()
// Use SFSpeechAudioBufferRecognitionRequest with the recognizer
// directly avoid AVAudioEngine entirely since it produces
// zero-length buffers on some devices causing assertion crashes.
request = SFSpeechAudioBufferRecognitionRequest()
guard let audioEngine, let request else { return }
guard let request else { return }
request.shouldReportPartialResults = true
request.requiresOnDeviceRecognition = recognizer.supportsOnDeviceRecognition
// Use AVAudioEngine with the native input format
audioEngine = AVAudioEngine()
guard let audioEngine else { return }
let inputNode = audioEngine.inputNode
let recordingFormat = inputNode.outputFormat(forBus: 0)
// Validate format 0 channels crashes installTap
guard recordingFormat.channelCount > 0 else {
print("[PronunciationService] invalid recording format (0 channels)")
self.audioEngine = nil
self.request = nil
return
}
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, _ in
guard buffer.frameLength > 0 else { return }
// Use nil format lets the system pick a compatible format
// and avoids the mDataByteSize(0) assertion from format mismatches
inputNode.installTap(onBus: 0, bufferSize: 4096, format: nil) { buffer, _ in
request.append(buffer)
}