3

I have an audio related app that has multichannel mixer to play m4a files at a time. I'm using the AudioToolBox framework to stream audio, but on iOS9 the framework throws me exception in mixer rendering callback where i am streaming the audio files.

Interestingly apps compiled with the iOS9 SDK continue to stream the same file perfectly on iOS7/8 devices, but not iOS9. Now i can't figure out if Apple broke something in iOS9, or we have the files encoded wrong on our end, but they play just fine on both iOS 7/8 but not 9.

Exception:

malloc: *** error for object 0x7fac74056e08: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug

It works for all other formats does not give any exception or any kind of memory errors but does not work for m4a format which is very surprising.

Here is a code to load files which works for wav,aif etc formats but not for m4a:

- (void)loadFiles{

    AVAudioFormat *clientFormat = [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatFloat32
                                                                   sampleRate:kGraphSampleRate
                                                                     channels:1
                                                                  interleaved:NO];
    for (int i = 0; i < numFiles && i < maxBufs; i++)  {

        ExtAudioFileRef xafref = 0;

        // open one of the two source files
        OSStatus result = ExtAudioFileOpenURL(sourceURL[i], &xafref);
        if (result || !xafref) {break; }

        // get the file data format, this represents the file's actual data format
        AudioStreamBasicDescription fileFormat;
        UInt32 propSize = sizeof(fileFormat);

        result = ExtAudioFileGetProperty(xafref, kExtAudioFileProperty_FileDataFormat, &propSize, &fileFormat);
        if (result) { break; }

        // set the client format - this is the format we want back from ExtAudioFile and corresponds to the format
        // we will be providing to the input callback of the mixer, therefore the data type must be the same

        double rateRatio = kGraphSampleRate / fileFormat.mSampleRate;

        propSize = sizeof(AudioStreamBasicDescription);
        result = ExtAudioFileSetProperty(xafref, kExtAudioFileProperty_ClientDataFormat, propSize, clientFormat.streamDescription);
        if (result) { break; }

        // get the file's length in sample frames
        UInt64 numFrames = 0;
        propSize = sizeof(numFrames);
        result = ExtAudioFileGetProperty(xafref, kExtAudioFileProperty_FileLengthFrames, &propSize, &numFrames);
        if (result) { break; }

        if(i==metronomeBusIndex)
            numFrames = (numFrames+6484)*4;
        //numFrames = (numFrames * rateRatio); // account for any sample rate conversion
        numFrames *= rateRatio;


        // set up our buffer
        mSoundBuffer[i].numFrames = (UInt32)numFrames;
        mSoundBuffer[i].asbd = *(clientFormat.streamDescription);

        UInt32 samples = (UInt32)numFrames * mSoundBuffer[i].asbd.mChannelsPerFrame;
        mSoundBuffer[i].data = (Float32 *)calloc(samples, sizeof(Float32));
        mSoundBuffer[i].sampleNum = 0;

        // set up a AudioBufferList to read data into
        AudioBufferList bufList;
        bufList.mNumberBuffers = 1;
        bufList.mBuffers[0].mNumberChannels = 1;
        bufList.mBuffers[0].mData = mSoundBuffer[i].data;
        bufList.mBuffers[0].mDataByteSize = samples * sizeof(Float32);

        // perform a synchronous sequential read of the audio data out of the file into our allocated data buffer
        UInt32 numPackets = (UInt32)numFrames;

        result = ExtAudioFileRead(xafref, &numPackets, &bufList);
        if (result) {
            free(mSoundBuffer[i].data);
            mSoundBuffer[i].data = 0;
        }

        // close the file and dispose the ExtAudioFileRef
        ExtAudioFileDispose(xafref);
    }

    // [clientFormat release];
}

If anyone could point me in the right direction, how do i go about debugging the issue? Do we need to re-encode our files in some specific way?

  • Please be more concrete on your problem. What is the exception about? What functions do you rely on? Have you considered the [iOS 9 Diff](https://developer.apple.com/library/prerelease/ios/releasenotes/General/iOS90APIDiffs/Objective-C/AudioToolbox.html)? – Michael Dorner Sep 30 '15 at 20:33
  • Michael could you look into it now or you need more concrete things? And yes I did check iOS9 Diff...could not find anything out of it which will help me to find solution. – Tech_Intelliswift Oct 01 '15 at 05:25
  • You do some `if (result) { break; }`; which checks are fine and which one fails? Where is the exception thrown? What does the [debugger](http://stackoverflow.com/a/22417528/1864294) tell us? – Michael Dorner Oct 01 '15 at 06:08
  • Excption is thrown at this line: ExtAudioFileDispose(xafref); and debugger gives this : malloc: *** error for object 0x7fe03c804c08: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug – Tech_Intelliswift Oct 01 '15 at 07:05

1 Answers1

0

I tried it on iOS 9.1.beta3 yesterday and things seem to be back to normal.

Try it out. Let us know if it works out for you too.

Vibhor Mahajan
  • 306
  • 2
  • 3