The issue is still there in Xcode 15.4. Just restarting the device resolves the problem.
Post
Replies
Boosts
Views
Activity
Hey, Did you find any fix for this?
Using kAudioUnitSubType_VoiceProcessingIO for AudioComponentDescription was the issue.
I got the same issue when I ran the app on a device that doesn't have a SIM card. I show up local network permission alert on app startup and if it is denied by the user the first time there is no way the user can change that in the settings as the app is not available there. Even the app is shown in Privacy & Security -> Local Network but not in the settings list. I tried cleaning the build folder, restarting the device etc.
These are some related code segments. enableMic programmatically is the issue.
private var audioEngine: AVAudioEngine?
private var inputNode: AVAudioNode!
private func setupAudioSession() {
do {
let session = AVAudioSession.sharedInstance()
try session.setCategory(.playAndRecord, options: [.defaultToSpeaker, .allowBluetooth])
try session.setActive(true)
} catch {
print(error)
}
}
func setupAudioEngine() {
audioEngine?.stop()
audioEngine?.reset()
setupAudioSession()
audioEngine = AVAudioEngine()
inputNode = audioEngine?.inputNode
guard let hardwareSampleRate = audioEngine?.inputNode.inputFormat(forBus: 0).sampleRate else { return }
let format = AVAudioFormat(standardFormatWithSampleRate: hardwareSampleRate, channels: 1)
let requiredBufferSize: AVAudioFrameCount = 4800
inputNode.installTap(onBus: 0,
bufferSize: requiredBufferSize,
format: format
) { [self] (buffer: AVAudioPCMBuffer, _: AVAudioTime) in
/* process the buffer */
}
audioEngine?.prepare()
}
func startRecording() {
do {
try audioEngine?.start()
} catch {
print("Could not start audioEngine: \(error)")
}
}
private func observeRouteChanges() {
NotificationCenter.default.addObserver(self,
selector: #selector(handleRouteChange),
name: AVAudioSession.routeChangeNotification,
object: nil)
}
@objc func handleRouteChange(notification: Notification) {
guard let userInfo = notification.userInfo,
let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else {
return
}
switch reason {
case .newDeviceAvailable, .oldDeviceUnavailable:
/* enableMic with current route AVAudioSession.sharedInstance().currentRoute.inputs.first */
default: ()
}
}
private func enableMic(mic: AVAudioSessionPortDescription?) {
let session = AVAudioSession.sharedInstance()
do {
try session.setPreferredInput(mic)
/* re-setup the audio engine and start */
} catch {
print(error)
}
}