2011-11-24 15 views
4

我正在寫一個iPhone應用程序,將播放音頻指令作爲它的一個特點。如何使用的iOS AudioUnit呈現回調正確

每次應用程序想要播放音頻時,它都會從非標準文件中讀取,並將該音頻的結果PCM數據放入內存緩衝區中。

即使我有PCM數據的緩衝區,我無法讓應用程序實際播放聲音。在搜索iOS文檔後,我開始實施一個AudioUnit。這個AudioUnit的問題是使用渲染回調(據我所知,唯一的方法來輸出聲音)。從Apple's developer documentation

...呈現回調有嚴格的性能要求,你必須 堅持。渲染回調存在於 上的實時優先級線程上,後續渲染調用異步到達。在渲染回調的主體中執行 的工作發生在此時間受限的 環境中。如果您的回調仍在 針對前生產樣品幀渲染調用下一次渲染調用 到達時,你的聲音一定的差距。出於這個原因,你不能拿 鎖,分配內存,訪問文件系統或網絡連接 或以其他方式在 的身體進行耗時的任務呈現回調函數

如果我不能在render回調方法中使用鎖我不能在寫入緩衝區時讀取緩衝區。沒有機會讀取文件並寫入緩衝區,因爲渲染回調將不斷訪問它。

唯一的例子I found實際上生成了渲染方法中的PCM數據,這是我無法做到的。

這是使用AudioUnits(與異步呈現回調)的唯一方法?

有沒有其他方法可以從內存播放PCM數據?

+0

寫得不錯的問題。非常感謝你幫助我的理解! – JohnK

回答

4

使用RemoteIO音頻單元可能需要在音頻單元回調之外擁有一個單獨的數據隊列(fifo或循環緩衝區),它可以在音頻單元呈現回調之前預先緩衝從文件讀取中足夠的音頻數據,以滿足更嚴重的案件延遲。然後,渲染回調只需要快速複製音頻數據,然後更新指示音頻數據已被使用的只寫標誌。

內置於iOS的替代方案是使用Audio Queue API,它爲您提供預緩衝。它允許您的應用程序提前在主運行循環中填充多個較大的音頻緩衝區。您仍然必須預先緩衝足夠的數據以允許文件,網絡,鎖定或其他延遲的最大值。

另一種策略是,如果文件或網絡讀取沒有跟上,則可以使用替代音頻數據來提供實時呈現回調,例如快速創建一個音頻緩衝區,以逐漸減弱靜音(然後取消縮減真正的數據開始再次到達)。