I am implementing Speech Recognition in my app. When I first present the view controller with the speech recognition logic, everything works fine. However, when I try presen
First, a small issue. When tapping the device's microphone, you'll want to use the format of the input bus:
let recordingFormat = node.inputFormat(forBus: 0)
Second, after some digging it seems like this crash most commonly stems from your application's shared AVAudioSession category settings. Make sure you have your audio session configured like so if you're going to be performing live microphone audio processing:
private func configureAudioSession() {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: .mixWithOthers)
try AVAudioSession.sharedInstance().setActive(true)
} catch { }
}
You can replace this code:
let recordingFormat = node.outputFormat(forBus: 0)
with the following:
let recordingFormat = AVAudioFormat(standardFormatWithSampleRate: 44100, channels: 1)
This code fixed the problem.
I was getting the required condition is false: IsFormatSampleRateAndChannelCountValid(format)
crash when attempting to use speech recognition while taking a phone call, which caused the sample rate to equal zero.
My solution was to create the below audioInputIsBusy()
function and call it before try audioSession.setCategory(.record, mode: .measurement, options: .duckOthers)
That prevented the crash and I displayed a message that the "speech recognition is unavailable" and then reset the audioEngine with audioEngine = AVAudioEngine()
.
func audioInputIsBusy(recordingFormat: AVAudioFormat) -> Bool {
guard recordingFormat.sampleRate == 0 || recordingFormat.channelCount == 0 else {
return false
}
return true
}
ps: let recordingFormat = audioEngine.inputNode.outputFormat(forBus: 0)
There are two possible ways to solve this problem.
inputFormat.channelCount
. It may be throwing the error because the mic is in use in another application or somewhere else you yours.if(inputNode.inputFormat(forBus: 0).channelCount == 0){
NSLog("Not enough available inputs!")
return
}
audioEngine
.audioEngine.reset()
try this, before start running each time:
audioEngine = AVAudioEngine()