7

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.

Arda
  • 757
  • 10
  • 18
  • 1
    https://stackoverflow.com/questions/45155648/avaudiosessions-playandrecord-category-and-avaudiosessionmodemeasurement-are-in – P i Apr 26 '18 at 13:13
  • 1
    Apple eventually closed my bug report, stating it is by design: https://bugreport.apple.com/web/?problemID=16402045 – Arda Apr 26 '18 at 23:25

1 Answers1

4

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.

Andy Korth
  • 261
  • 3
  • 9
  • Hi Andy, thanks for your reply. Note that the API works fine on most iPad models (iPad 2, iPad 3, iPad Air); it only fails on iPad 4. So it's not really an iPhone vs. iPad thing. Also, unless something has changed in iOS 7.1, the measurement mode eliminates extra filtering as well (i.e. it changes more than just what microphone is used), therefore it is essential on iPads too for any app that does signal processing, even if the iPads have only a single microphone. – Arda Jul 25 '14 at 05:27
  • By the way, I've released an updated version of the app to a large user base back in March with this mode disabled just for iPad 4, and haven't heard a single customer complaint since, further confirming that other iPad models don't exhibit the same issue. – Arda Jul 25 '14 at 05:31
  • Oh, good to know about the iPad Air. I noticed it with the iPad 4, and assumed all newer devices would have the issue also. Other than not having tested on the Airs, your findings line up with mine. Thanks! – Andy Korth Jul 30 '14 at 16:18
  • Has this issue been fixed? – P i Apr 26 '18 at 13:08
  • 1
    @Pi No. I eventually abandoned the measurement mode as it has been nothing but pain since iOS 7.1. I guess one option would have been to enable it only when headphones are plugged in, but I tweaked my signal processing algorithm to work perfectly fine without the measurement mode, so there wasn't any reason left to take any risks with this mode that behaves so differently from one device model to another. – Arda Apr 26 '18 at 23:38