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

问题描述:

我有一些非常奇怪的东西(至少对我来说,但我是一个noob)。为什么AudioFileReadPacketData的参数ioNumBytes会导致崩溃?

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 

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

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

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

UInt32 numBytesReadFromFile; 

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

谢谢。

+0

请发布更多代码。最初是什么'ioNumBytes'?它是否符合您的缓冲区大小? – sbooth 2015-02-11 13:41:01

+0

没有更多的代码。一切都设置为AudioFileReadDataPack。只需要声明numBytesReadFromFile,并在调用AudioFileReadDataPack之前完成。 – Duc 2015-02-11 21:08:10

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

谢谢,但问题是Apple不会初始化numBytesReadFromFile。这里是指南:[链接](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/AQPlayback/PlayingAudio.html#//apple_ref/doc/uid/TP40005343-CH3-SW2 )清单3-4。那么你能否澄清苹果在输入和输出方面的含义?这是否意味着:首先它读取存储在numBytesreadFromFile中的值,然后将值存储在numBytesReadFromFile中? – Duc 2015-02-11 21:16:28

+1

您链接的示例使用'AudioFileReadPackets',它是一个具有不同语义的旧API。使用'AudioFileReadPacketData',有必要在函数调用之前将'ioNumBytes'设置为缓冲区可容纳的字节数,并且如果函数没有遇到错误,它将在返回时用该字节数替换该值实际阅读。 – sbooth 2015-02-12 02:19:25

+0

谢谢!我没有注意到有什么区别。 – Duc 2015-02-12 12:14:20