Audio Queue Services callback: AudioStreamPacketDescription cannot be copied?

1.6k views Asked by At

I am creating a simple iOS app that records audio with a circular buffer. This means that it continually records audio, but only keeps the last 15 buffers in memory.

I do this by copying all the data I get from the AudioInputCallback:

void AudioInputCallback(
                    void *inUserData, 
                    AudioQueueRef inAQ, 
                    AudioQueueBufferRef inBuffer, 
                    const AudioTimeStamp *inStartTime, 
                    UInt32 inNumberPacketDescriptions, 
                    const AudioStreamPacketDescription *inPacketDescs) 

This works great and I can record an AIF file correctly when I save all my buffers to a file after I stop recording. So, the copying of the data to other buffers works correctly.

Problem however is that when I use M4A that uses variable packets, that same routine does not work. When I put the AudioFileWritePackets method in the callback it works correctly, but when I use it afterwards on the stored buffered data, it fails.

It turns out that this is caused by the data of const AudioStreamPacketDescription *inPacketDescs When I change that in the callback function itself (recording there) to my copy it fails immediately. However the data itself is identical.

This is the format:

struct AudioStreamPacketDescription {
   SInt64  mStartOffset;
   UInt32  mVariableFramesInPacket;
   UInt32  mDataByteSize;
};
typedef struct AudioStreamPacketDescription AudioStreamPacketDescription;

I create a copy in my code using the following method:

item.inPacketDescs = (AudioStreamPacketDescription *)(malloc(sizeof(AudioStreamPacketDescription)));

    item.inPacketDescs->mDataByteSize = inPacketDescs->mDataByteSize;
    item.inPacketDescs->mStartOffset = inPacketDescs->mStartOffset;
    item.inPacketDescs->mVariableFramesInPacket = inPacketDescs->mVariableFramesInPacket;

However, when then using the item.inPacketDescs instead of the inPacketDescs makes it fail immediately. And this while the data of these three fields is identical. (I checked using debugger).

I am a bit out of options now. I see that the supplied variable is const, so I am afraid that this has some meaningfull purpose, like that the AudioFileWritePackets requires it to be the same memory address or so? That would be amazingly stupid, but I don't really know anymore.

Any ideas on what is causing this? Ideas on how to save it differently to a circular buffer?

1

There are 1 answers

2
Peterdk On

It turns out that inPacketDescs is a array of AudioStreamPackedDescription. Therefore copying only the first value was failing.

Solution:

AudioStreamPacketDescription * test = (AudioStreamPacketDescription *)(malloc(inNumberPacketDescriptions * sizeof(AudioStreamPacketDescription)));
    memcpy(test, inPacketDescs, inNumberPacketDescriptions * sizeof(AudioStreamPacketDescription));