【问题标题】:Why does the argument ioNumBytes of AudioFileReadPacketData cause a crash?为什么 AudioFileReadPacketData 的参数 ioNumBytes 会导致崩溃?
【发布时间】:2015-02-10 22:41:09
【问题描述】:

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

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 并发生上述错误。如果我的假设是正确的,由于我在多线程方面没有经验,有人可以更详细地解释一下这个问题。

谢谢。

【问题讨论】:

  • 请发布更多代码。 ioNumBytes 最初是什么?它与您的缓冲区大小匹配吗?
  • 没有更多代码了。一切都为 AudioFileReadDataPack 设置好了。只需要声明 numBytesReadFromFile 并且在调用 AudioFileReadDataPack 之前完成。

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


【解决方案1】:

参数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
                                    );

【讨论】:

  • 谢谢,但问题是 Apple 也没有初始化 numBytesReadFromFile。这是指南:link 清单 3-4。那么你能澄清一下 Apple 对输入和输出的含义吗?这是否意味着:它首先读取存储在 numBytesreadFromFile 中的值,然后将值存储在 numBytesReadFromFile 中?
  • 您链接到的示例使用 AudioFileReadPackets,这是一个具有不同语义的旧 API。对于AudioFileReadPacketData,必须将ioNumBytes 设置为缓冲区可以在函数调用之前保存的字节数,如果函数没有遇到错误,它将在返回时替换该值实际读取的字节数。
  • 谢谢!我没有注意到有什么不同。
猜你喜欢
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多