Как предоставить аудио буфер для AudioQueue для воспроизведения аудио?
В моем приложении я получаю аудиоданные в формате LinearPCM, которые мне нужно воспроизвести. Я следую примеру iOS SpeakHere. Однако я не могу понять, как и где я должен предоставить буфер для AudioQueue
,
Может кто-нибудь предоставить мне рабочий пример воспроизведения аудио буфера в iOS через AudioQueue
?
1 ответ
В примере 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
ждем, что следующая копия помещает данные в правильное место.