I just filed a bug report with Apple, but I wanted to post here in case people had input about this. I would love to hear that there is just some assumption or logic that I am messing up.
When an AVAudioEngine with voice processing io enabled is running, all other audio sources within the app that are started later will have low volume (seemingly not routed to the speakers?). After either setting the AVAudioSession category to .playAndRecord
or overriding the AVAudioSession output route to speaker, the volume corrects itself (output seems to route to the speakers now).
The exact reproduction steps in the code can be broken down as follows. Make sure you have record permissions:
- Create an AVAudioEngine
- Access each engine's
.mainMixerNode
- Create an AVPlayer with some audio file (This is also reproducible with AVAudioPlayer and AVAudioEngine)
- Configure the session with the following:
AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .videoChat, options: [.defaultToSpeaker])
(Note that I'm setting.defaultToSpeaker
) - Activate the session with
AVAudioSession.sharedInstance().setActive(true)
- Enable voice processing on the engine with the following:
try! engine.outputNode.setVoiceProcessingEnabled(true)
- Start engine with the following:
try! engine.start()
- Start the
AVPlayer
and note the volume. You may need to increase the system volume to hear what you're playing. - You can call either of the following and the audio from the
AVPlayer
will fix its volume:
AVAudioSession.sharedInstance().setCategory(AVAudioSession.sharedInstance().category)
AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
- Note that the volume instantly raises
- If you were to have another audio source (AVAudioPlayer, AVPlayer, AVAudioEngine), that is started after step 9, you would need to repeat step 9 again.
Obviously, this is not ideal and can cause some very unexpected volume changes for end users.
This was reproducible on iOS 13.6, 15.7, and 16.2.1 (latest).
If anyone has ideas as to how to prevent this or work around it other than the workaround demonstrated here, I'm all ears.