Как предоставить аудио буфер для 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 ждем, что следующая копия помещает данные в правильное место.

Другие вопросы по тегам