Using AVAudioSessionModeMeasurement with AVAudioSessionCategoryPlayAndRecord used to work fine under iOS 5.x, 6.x, and 7.0, but it now results in low volume / no sound from the speaker on some (not all) devices under iOS 7.1. Here's the code:
NSError* error = nil;
// Set Aduio Session category
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker
error:&error];
if( error ) ...
// Set Audio Session mode
[audioSession setMode:AVAudioSessionModeMeasurement error:&error];
if( error ) ...
Side note: Older versions of the code used the AudioSessionSetProperty function to set kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, but still had the same issue under iOS 7.1.
So far it looks like the low volume (or no sound) issue occurs only on iPad 4 devices. I don't know if it happens on all iPad 4's or only a subset, but only customers with iPad 4's have contacted us with this issue after upgrading to iOS 7.1. Removing the code that sets the mode to AVAudioSessionModeMeasurement fixes the issue; audio is heard at normal volume. However, not using the measurement mode affects the signal processing we do on the recorded audio, so it's definitely not desirable.
It doesn't seem to matter how the audio is played. Both AVAudioPlayer and Audio Queue Services exhibit the same low volume / no sound issue when the Measurement mode is set.
Because this issue only seems to affect iPad, I've tried removing the AVAudioSessionCategoryOptionDefaultToSpeaker option (which is normally needed for iPhones) to see if that would help, but that didn't make a change.
Plugging in headphones fixes the issue; audio is heard at normal volume through the headphones.
Assuming this is an iOS 7.1 bug, I've already reported it as a bug to Apple. However I wanted to ask you guys to see if I might have missed something special about iPad 4's, or maybe something else in my audio session setup. If you have an app that plays back audio (via AVAudioPlayer or Audio Queue Services), even if you let me know if audio still plays back fine on your iPad 4 after you change the category to AVAudioSessionCategoryPlayAndRecord and the mode to AVAudioSessionModeMeasurement, that would help tremendously. Your app doesn't need to actually record any audio; the issue happens whether audio is being recording or not.
Thanks in advance for any help.
Go to Settings > Sounds (or Settings > Sounds & Haptics), and drag the Ringer and Alerts slider back and forth a few times. If you can't hear any sound, or if your speaker button on the Ringer and Alerts slider is dimmed, your speaker may need to be serviced.
Just below the Silent switch, you'll find the Volume buttons, which adjust sounds for videos and music in increments. This also works if you're trying to increase ringer volume. If the buttons don't change anything, go to Settings > Sounds & Haptics, then check that Change with Buttons is turned on.
I've definitely run into this issue myself on iPads in iOS 7.
When recording, AVAudioSessionModeMeasurement does change playback volume on iOS 7.
Apple's docs state: Specify this mode if your app is performing measurement of audio input or output. ... If recording on devices with more than one built-in microphone, the primary microphone is used.
On iPhones, which have two speakers and two microphones, this sort can sort of make sense. When recording out of the microphone on the bottom of the phone, it plays audio out of the earpiece speaker so prevent interference. When being used in speakerphone mode, it uses the loud bottom speakers and a microphone in the earpiece.
On iPads in iOS 7, it seems to replicate this behavior by unilaterally lowering the playback volume.
To answer your question directly: Yes, I believe this is a bug, or at least a very undocumented feature.
After you are done recording and measuring, you can reset the silenced audio with:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&err];
if(err) NSLog(@"AudioSession reset category error at %s:%d", __FILE__, __LINE__);
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeDefault error:&err];
if(err) NSLog(@"AudioSession reset mode error at %s:%d", __FILE__, __LINE__);
Although that doesn't necessarily help, likewise with my confirmed findings that not using AVAudioSessionModeMeasurement solves the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With