Filip Chabik
Filip Chabik

Reputation: 1

ios 8.1 calling AudioConvertFillComplexBuffer make a infinite loop with cpuload 100%

I'm converting audio by using the AudioToolBox.AudioConverter library.

AudioStreamBasicDescription inDescription;
inDescription.mSampleRate = 44100;
inDescription.mFormatID = kAudioFormatMPEGLayer3;
inDescription.mFormatFlags = 0;
inDescription.mBytesPerPacket = 0;
inDescription.mFramesPerPacket = 1152;
inDescription.mBytesPerFrame = 0;
inDescription.mChannelsPerFrame = 2;
inDescription.mBitsPerChannel = 0;
inDescription.mReserved = 0;

AudioStreamBasicDescription outDescription;
audioDescription.mFormatID = kAudioFormatLinearPCM
audioDescription.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagsNativeEndian;
audioDescription.mChannelsPerFrame = 2;
audioDescription.mBytesPerPacket = sizeof(SInt16)*audioDescription.mChannelsPerFrame;
audioDescription.mFramesPerPacket = 1;
audioDescription.mBytesPerFrame = sizeof(SInt16)*audioDescription.mChannelsPerFrame;
audioDescription.mBitsPerChannel = 8 * sizeof(SInt16);
audioDescription.mSampleRate = 44100.0;

This is the conversion part with mp3AudioData...

AudioBufferList *mp3Audio = (AudioBufferList *)malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer));

mp3Audio->mNumberBuffers = 1;
mp3Audio->mBuffers[0].mNumberChannels  = 2;
mp3Audio->mBuffers[0].mDataByteSize = chunkLen;
mp3Audio->mBuffers[0].mData = calloc(chunkLen, sizeof(uint8_t));
memcpy(mp3Audio->mBuffers[0].mData, chunkData, chunkLen);

AudioStreamPacketDescription *packetDescription =
(AudioStreamPacketDescription*)malloc(sizeof(AudioStreamPacketDescription) * frames);
packetDescription->mDataByteSize = chunkLen;
packetDescription->mStartOffset = 0;
packetDescription->mVariableFramesInPacket = 1;

OSStatus result = AudioConverterFillComplexBuffer(audioConverter,
                                                  fillComplexBufferInputProc,
                                                  &(struct fillComplexBufferInputProc_t) { .bufferList =mp3Audio, .frames = frames, .packetDescriptions = packetDescription },
                                                  &frames,
                                                  pcmAudio,
                                                  NULL);

free(mp3Audio->mBuffers[0].mData);
free(mp3Audio);
free(packetDescription);

The first running of AudioConverterFillComplexBuffer is OK but when I run that function a second time, the infinite loop happens with cpuload 100%.

This code is OK on an IOS 7 device, but when I run it on an IOS 8 device, the infinite loop happens.

Could anyone tell me why this happens on IOS 8?

fillComplexBufferInputProc function:

static OSStatus fillComplexBufferInputProc(AudioConverterRef             inAudioConverter,
                                           UInt32                        *ioNumberDataPackets,
                                           AudioBufferList               *ioData,
                                           AudioStreamPacketDescription  **outDataPacketDescription,
                                           void                          *inUserData) {
    struct fillComplexBufferInputProc_t *arg = inUserData;

    for (int i = 0; i < ioData->mNumberBuffers; i++) {
        ioData->mBuffers[i].mData = arg->bufferList->mBuffers[i].mData;
        ioData->mBuffers[i].mDataByteSize = arg->bufferList->mBuffers[i].mDataByteSize;
    }

    if (NULL == *outDataPacketDescription) {
        *outDataPacketDescription = arg->packetDescriptions;
    }

    *ioNumberDataPackets = arg->frames;

    return noErr;
}

Upvotes: 0

Views: 136

Answers (1)

Rod Chen
Rod Chen

Reputation: 522

Because it seems no possible infinite loop in your code (except for-loop in fillComplexBufferInputProc function), I suggest you use Instruments (Time Profiler) to see what method is using the majority of CPU time. Check the stack trace for more information, so maybe we can help. Here is a tutorial for time profiler.

Upvotes: 1

Related Questions