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

Why does the argument ioNumBytes of AudioFileReadPacketData cause a crash?

我遇到了一些非常奇怪的事情(至少对我来说是这样,但我是个菜鸟)。

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: On output, the number of bytes of audio data that were read from the audio file.

到目前为止一切顺利。 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 并发生上述错误。如果我的假设是正确的,有人可以更详细地解释一下这个问题吗,因为我没有多线程经验。

谢谢。

参数ioNumBytesAudioFileReadPacketData是一个in/out参数。 documentation 表示:

On input, the size of the outBuffer parameter, in bytes. On output, the number of bytes actually read.

You will see a difference in the input and output values if the byte size for the number of packets you request in the ioNumPackets parameter is smaller than the buffer size you pass in the outBuffer parameter. In this case, the output value for this parameter is smaller than its input value.

调用函数时的值决定了将向您的缓冲区写入多少数据。如果您发布的代码是正确的,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
                                    );