AVAudioEngine - Required condition is false: format.sampleRate == hwFormat.sampleRate AudioProcessorEngine.installTap()

func start() {
        do {
            try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: .mixWithOthers)
        } catch let error {
            print("Error setting audio session category: \(error.localizedDescription)")
        }
       
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch let error {
            print("Activating play and record AVAudioSession failed with error: \(error.localizedDescription)")
        }
       
        self.audioEngine.reset()
        self.audioEngine.prepare()
       
        if !self.audioEngine.isRunning {
            self.installTap()
       
            do {
                try self.audioEngine.start()
            } catch let error {
                print("Error starting engine: \(error.localizedDescription)")
                if isCalibrationConfig {
                    AnalyticsFunctions.reportErrorRecordingFailed()
                }
            }
        }
    }

func installTap() {
        print("Engine started and tap is installed")
        let mic = self.audioEngine.inputNode
        let micFormat = mic.inputFormat(forBus: 0)
   
       
 
        if !isMicTapInstalled {
            mic.installTap(onBus: 0, bufferSize: 2048, format: micFormat) { (buffer, time) in
                if let delegate = self.delegate {
                    if self.isAnalysisConfig {
                        if AVAudioSession.sharedInstance().isOtherAudioPlaying || self.calibrationValidation {
                            delegate.pcmTap(pcmBuffer: buffer)
                        }
                    }
                    if self.isCalibrationConfig {
                        delegate.pcmForCalibrationTap(pcmBuffer: buffer)
                    }
                }
            }
            self.isMicTapInstalled = true
        }
    }


func stop() {
        self.removeTap()
        self.audioEngine.stop()
        AudioUnitUninitialize(self.audioEngine.inputNode.audioUnit!)
        self.audioEngine.reset()
        print("Audio engine did stop and removeTap() was called")
    }


This is the code basically start(), installTap() and stop(). Engine is initialized in the Class.


The exception comes in on the new iPhone X and above where on route change starting the engine results in the exception:


Fatal Exception: com.apple.coreaudio.avfaudio
required condition is false: format.sampleRate == hwFormat.sampleRate

Example: If a user starts the app with earphones connected starting and stopping the engine works normally. However if the user starts the app with earphones disconnected and then connects earphones once inside the app then tries to start the engine. Results in the above exception.


I would like to understand what is actually happening? Is the inputNode sampleRate of the built in Mic different to the standard headset mic sampleRate? If not where does it possible change? Should I be handling the reinitialization of the mic on route change?

Replies

Did you ever find a solution to this? I just hit the same exception.