How to provide audio buffer to AudioQueue to play audio?

China☆狼群 提交于 2019-12-22 17:38:35

问题


In my application, I am receiving audio data in LinearPCM format, which I need to play. I am following iOS SpeakHere example. However I cannot get how and where I should provide a buffer to AudioQueue.

Can anyone provide me a working example of playing audio buffer in iOS via AudioQueue?


回答1:


In the SpeakHere example playback is achieved using AudioQueue.

In the set up of AudioQueue, a function is specified that will be called when the queue wants more data.

You can see that in this method:

void AQPlayer::SetupNewQueue() 

Here's the line that specifies the callback function:

    XThrowIfError(AudioQueueNewOutput(&mDataFormat, AQPlayer::AQBufferCallback, this, 
                                    CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &mQueue), "AudioQueueNew failed");

If you take a look at AQPlayer::AQBufferCallback, you'll see where it gets the data from. In this example, the data has been written out to a file on disk. That's a good solution if you want to save memory, or if there's a possibility the audio file could be quite large.

Anyway, looking at AQPlayer::AQBufferCallback, you'll see a call to a function AudioFileReadPackets. That's what reads in the audio packets from the file on disk. It reads them straight into the buffer that AudioQueue will use:

    OSStatus result = AudioFileReadPackets(THIS->GetAudioFileID(), false, &numBytes, inCompleteAQBuffer->mPacketDescriptions, THIS->GetCurrentPacket(), &nPackets, 
                                       inCompleteAQBuffer->mAudioData);

That buffer is inCompleteAQBuffer->mAudioData.

Finally, the callback function must enqueue the buffer as follows:

if (nPackets > 0) {
    inCompleteAQBuffer->mAudioDataByteSize = numBytes;      
    inCompleteAQBuffer->mPacketDescriptionCount = nPackets;     
    AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, 0, NULL);
    THIS->mCurrentPacket = (THIS->GetCurrentPacket() + nPackets);
} 

Note first that it has to check that we have some packets to play. It also has to specify how many bytes are in the buffer.

Then, this line here:

THIS->mCurrentPacket = (THIS->GetCurrentPacket() + nPackets);

That keeps a track of where we are overall in our audio buffer. In other words, as more data is copied in from the file, we need to position the mCurrentPacket forward to that the next copy puts data in the correct place.



来源:https://stackoverflow.com/questions/5953925/how-to-provide-audio-buffer-to-audioqueue-to-play-audio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!