为什么AudioFileReadPacketData的参数ioNumBytes会导致崩溃?

时间:2015-02-10 22:41:10

标签: ios core-audio exc-bad-access audioqueue

我有一些非常奇怪的东西(至少对我来说,但我是一个菜鸟)。

UInt32 numBytesReadFromFile;
OSStatus err = AudioFileReadPacketData(
                                    audioFile, // The audio file whose audio packets you want to read.
                                    NO, // is cache set?
                                    &numBytesReadFromFile, // On output, the number of bytes of audio data that were read from the audio file.
                                    (AudioStreamPacketDescription *)_packetDescriptions, // array of packet descriptions of data that was read from the audio file (for CBR null)
                                    currentPacket, // the next packet to be read into buffer
                                    &numPackets, // number of actually read buffers
                                    _audioQueueBuffer->mAudioData
                                    );

AudioFileReadPacketData从音频文件中读取数据并将其放入缓冲区。

所以我的问题是关于参数numBytesReadFromFile。 Apple writes

  

numBytesReadFromFile:输出时,是从音频文件中读取的音频数据的字节数。

到目前为止一切顺利。 Apple在上面的示例代码中声明了numBytesReadFromFile,但对我来说这行代码崩溃了!我得到了一个EXC BAD ACCESS。

UInt32 numBytesReadFromFile;

我需要像这样声明numBytesReadFromFile,一切正常:

UInt32 numBytesReadFromFile = 2048; // 2048 = size of my buffer

然而这也崩溃了

UInt32 numBytesReadFromFile = 12
UInt32 numBytesReadFromFile = sizeof(UInt32)

但这不是

UInt32 numBytesReadFromFile = 1021; // a random number

我不是一个非常有经验的C程序员,但据我所知,我通过声明numBytesReadFromFile保留了一些内存,方法audiofilereadpacketdata将其数据写入变量的地址。如果我错了,请纠正我。

那为什么会崩溃?我想我还没有解决这个真正的问题。

我的假设是我有某种多线程问题。当我准备队列时,我在主线程上调用AudioFileReadPacketData并声明

UInt32 numBytesReadFromFile;

工作正常。我开始播放音频并调用一个回调,它在音频队列的内部后台线程上调用AudioFilereadPacketData,并发生上述错误。如果我的假设是正确的,那么有人可以更详细地向我解释这个问题,因为我没有多线程经验。

感谢。

1 个答案:

答案 0 :(得分:2)

参数ioNumBytesAudioFileReadPacketData是输入/输出参数。 documentation说:

  

输入时,outBuffer参数的大小,以字节为单位。在输出时,   实际读取的字节数。

     

如果是字节,您将看到输入和输出值的差异   您在ioNumPackets中请求的数据包大小   参数小于在outBuffer中传递的缓冲区大小   参数。在这种情况下,此参数的输出值为   小于其输入值。

调用函数时的值决定了将多少数据写入缓冲区。如果您发布的代码是正确的,numBytesReadFromFile永远不会初始化为_audioQueueBuffer->mAudioData的大小,并且程序崩溃,因为它尝试将未确定数量的数据写入_audioQueueBuffer->mAudioData。尝试在函数调用之前设置参数:

UInt32 numBytesReadFromFile = _audioQueueBuffer->mAudioDataByteSize;
OSStatus err = AudioFileReadPacketData(
                                    audioFile, // The audio file whose audio packets you want to read.
                                    NO, // is cache set?
                                    &numBytesReadFromFile, // On output, the number of bytes of audio data that were read from the audio file.
                                    (AudioStreamPacketDescription *)_packetDescriptions, // array of packet descriptions of data that was read from the audio file (for CBR null)
                                    currentPacket, // the next packet to be read into buffer
                                    &numPackets, // number of actually read buffers
                                    _audioQueueBuffer->mAudioData
                                    );