Jim Leask Jim Leask - 25 days ago 7
iOS Question

No sound issue kills audio for all apps on the device

We are losing sound (no sound) in our app, but this is somehow causing all other apps to also lose sound. I don't know how it would even be possible for us to block the sound from an external app like the Apple Music app.

We are dumping the contents of our

AVAudioSession
session and there are no differences that we can see between when sound is working and not. We have verified that the route output is still the iPhone's speaker, even when we lost sound.

This is happening on the iPhone 6s & 6s Plus with the speaker. We can "fix" the audio by changing the output route, such as plug in and unplug headphones.

How is it possible to impact the ability to play sound of other apps, which may help troubleshoot what is happening?

Answer

We tracked down the source of the problem to having bad data in the audio buffer that was sent to Core Audio. Specifically, one of the audio processing steps output data that was NaN (Not a Number), instead of a float in the valid range of +/- 1.0.

It appears that on some devices, if the data contains NaN, it kills the audio of the whole device.

We worked around it by looping through the audio data checking for NaN values, and converting them to 0.0 instead. Note that checking if a float is NaN is a strange check (or it seems strange to me). NaN is not equal to anything, including itself.

Some pseudocode to work around the problem until we get new libraries that have a proper fix:

float        *interleavedAudio; // pointer to a buffer of the audio data
unsigned int  numberOfSamples;  // number of left/right samples in the audio buffer
unsigned int  numberOfLeftRightSamples = numberOfSamples * 2; // number of float values in the audio buffer

// loop through each float in the audio data
for (unsigned int i = 0; i < numberOfLeftRightSamples; i++)
{
    float *sample = interleavedAudio + i;

    // NaN is never equal to anything, including itself
    if( *sample != *sample )
    {
        // This sample is NaN - force it to 0.0 so it doesn't corrupt the audio
        *sample = 0.0;
    }
}