gpt4 book ai didi

iphone - 如何向AudioQueue提供音频缓冲区来播放音频?

转载 作者:行者123 更新时间:2023-12-03 20:16:12 25 4
gpt4 key购买 nike

在我的应用程序中,我正在接收 LinearPCM 格式的音频数据,我需要播放该数据。我正在关注 iOS SpeakHere 示例。但是我不知道应该如何以及在哪里为 AudioQueue 提供缓冲区。

任何人都可以为我提供一个通过 AudioQueue 在 iOS 中播放音频缓冲区的工作示例吗?

最佳答案

在 SpeakHere 示例中,播放是使用 AudioQueue 实现的。

AudioQueue的设置中,指定了一个函数,当队列需要更多数据时将调用该函数。

你可以在这个方法中看到:

void AQPlayer::SetupNewQueue() 

这是指定回调函数的行:

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

如果您查看AQPlayer::AQBufferCallback,您将看到它从哪里获取数据。在此示例中,数据已写出到磁盘上的文件中。如果您想节省内存,或者音频文件可能非常大,那么这是一个很好的解决方案。

无论如何,查看AQPlayer::AQBufferCallback,您将看到对函数AudioFileReadPackets的调用。这就是从磁盘上的文件中读取音频数据包的方法。它将它们直接读入 AudioQueue 将使用的缓冲区:

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

该缓冲区是inCompleteAQBuffer->mAudioData

最后,回调函数必须将缓冲区排入队列,如下所示:

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

首先请注意,它必须检查我们是否有一些数据包要播放。它还必须指定缓冲区中有多少字节。

然后,这一行在这里:

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

它可以跟踪我们在音频缓冲区中的整体位置。换句话说,随着从文件中复制更多数据,我们需要将 mCurrentPacket 向前定位,以便下一个副本将数据放入正确的位置。

关于iphone - 如何向AudioQueue提供音频缓冲区来播放音频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5953925/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com