2011-05-10 249 views
2

在我的應用程序中,我正在接收需要播放的LinearPCM格式的音頻數據。 我正在關注iOS SpeakHere示例。但是我無法得到如何以及在哪裏我應該提供緩衝區到AudioQueue如何向AudioQueue提供音頻緩衝區來播放音頻?

任何人都可以提供我通過AudioQueue在iOS中播放音頻緩衝區的工作示例嗎?

回答

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轉發到下一個副本將數據放入正確位置。