Does iOS preprocess microphone data on modern iPhones?


I play a .WAV trigger tone and have a JUCE iOS decoder app that catches it by processing the microphone data. It works perfectly on my iPhone 5. It is extremely robust.

Someone else is loading exactly the same code onto their iPhone6 and iPhoneX. They are playing the trigger tone from an identical MacBook Pro, but the decoder does not correctly recognise the tone.

The only explanation I can think of is that on these more modern devices there is maybe some preprocessing done on the microphone data, maybe some kind of echo-cancellation?

Does anyone know if this is true? And if so, is there any way to disable this preprocessing?

Setting iPhone sample rate from 48000 to 44100

^ this looks like the culprit.

However it’s very strange that it works on an iPhone 5S but not on an iPhone 6. All of the devices are using the latest iOS. And if I look at detailed comparisons between the two models I find no mention of anything related to microphone preprocessing.


It turns out my particular problem is due to the fact that the iPhone <= 5S samples from the microphone at 44.1 kHz and >= 6S @ 48 kHz.

I was trying (on my 5S) to set the sample rate to 48000:

AudioDeviceManager::AudioDeviceSetup audioSetup;
deviceManager.getAudioDeviceSetup (audioSetup);
audioSetup.sampleRate = 48000.0;
auto ret = deviceManager.setAudioDeviceSetup (audioSetup, true);

setAudioDeviceSetup does not return any error, and in fact a subsequent call to getAudioDeviceSetup reports that the sample rate has been successfully changed to 48000.

Even deviceManager.getCurrentAudioDevice()->getCurrentSampleRate() reports 48000.


    void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override {
        LOG("prepareToPlay sampleRate: %.1f", sampleRate);

… correctly reports that the sample rate has been reverted to its system value of 44100.

I wonder if this is something that might be improved in JUCE – it took us a while to figure out that the sample rate is misreporting.


Unfortunately the one in prepareToPlay is the only one you can trust. On Apple’s mobile devices both the sample rate and buffer size can be changed underneath your feet by other apps (which share the same AudioSession in the OS), or by the OS itself. If this happens then we restart the audio and you get a new prepareToPlay call with the updated info. It’s possible that the system is reverting between your audio device setup code and the start of the audio processing.

If you want to find out more about what’s going on you can get a debugger inside the iOSAudioDevice class and enable more verbose logging by setting the macro JUCE_IOS_AUDIO_LOGGING 1.


Something that might help is setting the JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS option in the juce_audio_devices module options.


Just to report that setting JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS doesn’t lift the 44.1kHz limit on my iPhone 5S.