Android 4.1 版本引入了內部框架更改,以實現更低延遲的音訊輸出路徑。公共客戶端 API 或 HAL API 的變更極少。本文檔描述了最初的設計,該設計隨著時間的推移而不斷發展。充分了解此設計應有助於設備 OEM 和 SoC 供應商在其特定設備和晶片組上正確實施設計。本文不適合應用程式開發人員。
曲目創作
用戶端可以選擇在 AudioTrack C++ 建構子或AudioTrack::set()
的audio_output_flags_t
參數中設定位元AUDIO_OUTPUT_FLAG_FAST
。目前唯一這樣做的客戶是:
- 基於OpenSL ES或AAudio的 Android 原生音訊
- android.media.SoundPool
- android.media.ToneGenerator
AudioTrack C++ 實作會審核AUDIO_OUTPUT_FLAG_FAST
請求,並且可以選擇在用戶端層級拒絕該請求。如果它決定傳遞請求,則會使用IAudioTrack
工廠方法IAudioFlinger::createTrack()
的track_flags_t
參數的TRACK_FAST
位元來執行此操作。
AudioFlinger 音訊伺服器審查TRACK_FAST
請求,並且可以選擇在伺服器層級拒絕該請求。它透過共享記憶體控制塊的CBLK_FAST
位元通知客戶端請求是否被接受。
影響決策的因素包括:
- 此輸出存在快速混合器線程(見下文)
- 追蹤取樣率
- 存在用於執行該軌道的回調處理程序的客戶端線程
- 軌道緩衝區大小
- 可用的快速通道插槽(見下文)
如果客戶的請求被接受,則稱為「快速通道」。否則它被稱為“正常軌道”。
混合器線程
當AudioFlinger創建一個普通的混音器線程時,它決定是否也創建一個快速混音器線程。普通混音器和快速混音器都不與特定軌道相關聯,而是與一組軌道相關聯。總是有一個正常的混合器線程。快速混合器線程(如果存在)服從於普通混合器線程並在其控制下運行。
快速攪拌機
特徵
快速混合器線程提供以下功能:
- 混合普通混音器的子混音和最多 7 個客戶端快速軌道
- 每軌衰減
省略的功能:
- 每軌取樣率轉換
- 每軌效果
- 每個混合效果
時期
快速混合器定期運行,建議的週期為兩到三毫秒 (ms),如果需要調度穩定性,則週期稍長,為 5 毫秒。選擇這個數字是為了考慮到完整的緩衝區管道,總延遲約為 10 毫秒。較小的值是可能的,但可能會導致功耗增加和故障的可能性,這取決於 CPU 調度的可預測性。更大的值是可能的,最多 20 毫秒,但會導致總延遲降低,因此應避免。
調度
快速混頻器以提升的SCHED_FIFO
優先權運作。它需要很少的 CPU 時間,但必須經常運行並且調度抖動較低。抖動表示週期時間的變化:它是實際週期時間與預期週期時間之間的差異。運轉太晚會因欠載而導致故障。運行太早會導致由於在軌道提供資料之前從快速軌道拉出而導致故障。
阻塞
理想情況下,快速混合器執行緒永遠不會阻塞,除了 HAL write()
處。快速混合器內發生的其他阻塞被視為錯誤。特別是要避免互斥體。相反,使用非阻塞演算法(也稱為無鎖演算法)。有關此主題的更多信息,請參閱避免優先級反轉。
與其他組件的關係
快速混音師與客戶幾乎沒有直接互動。特別是,它看不到綁定級操作,但它確實存取客戶端的共享記憶體控制塊。
快速混音器透過狀態佇列接收來自普通混音器的命令。
除了提取軌道數據之外,與客戶端的互動是透過普通的混音器進行的。
快速混音器的主要接收器是音訊 HAL。
普通攪拌機
特徵
所有功能均已啟用:
- 多達 32 首曲目
- 每軌衰減
- 每軌取樣率轉換
- 效果處理
時期
此週期被計算為>= 20 ms 的快速混頻器週期的第一個整數倍。
調度
普通混合器以較高的SCHED_OTHER
優先權運作。
阻塞
普通混合器被允許阻塞,並且經常在各種互斥體以及阻塞管道處這樣做以寫入其子混合。
與其他組件的關係
普通混音器與外界進行廣泛的交互,包括活頁夾線程、音訊策略管理器、快速混音器線程和客戶端軌道。
普通混音器的水槽是通往快速混音器軌道 0 的阻塞管道。
旗幟
AUDIO_OUTPUT_FLAG_FAST
位元是一個提示。無法保證該請求會被滿足。
AUDIO_OUTPUT_FLAG_FAST
是客戶端層級的概念。它不會出現在伺服器中。
TRACK_FAST
是一個客戶端 -> 伺服器概念。