android音訊淺析
Android Framework的音訊子系統中,每一個音訊流對應著一個AudioTrack類的一個例項,每個AudioTrack會在建立時註冊到AudioFlinger中,由AudioFlinger把所有的AudioTrack進行混合(Mixer),然後輸送到AudioHardware中進行播放。AudioTrack和AudioFlinger的通訊機制通常,AudioTrack和AudioFlinger並不在同一個程序中,它們通過android中的binder機制建立聯絡。
Android音訊處理的基本介面
在Android開發中,根據不同的場景,出於衝突處理策略的考慮,開發者需要利用不同的介面來進行音訊資源的播放。
AudioManager為上層應用提供了聲音設定管理介面.
AudioService為所有的音訊相關的設定提供服務。他定義了了一個AudioSystemThread 的類,用來監控音訊控制相關的訊號,當有請求時,它會通過呼叫AudioSystem 的介面實現音訊的控制,這裡的訊息處理是非同步的。此外在AudioService還抽象出了一套傳送音訊控制訊號的介面為AudioManager提供支援。AudioManager通過音訊服務,為上層提供了音量和鈴聲模式控制的介面,鈴聲模式控制包括揚聲器、耳機、藍芽等是否開啟,麥克風是否靜音等。在開發多媒體應用時會經常用到AudioManager,關於Android AudioManager音量控制流程。
AudioSystem提供了音訊系統的基本型別定義,以及基本操作的介面。
對於音調,可以通過ToneGenerator來播放;ToneGenerator提供了對DTMF音(ITU-T Q.23),以及呼叫監督音(3GPP TS 22.001)、專用音(3GPP TS 31.111)中規定的音訊的支援,根據呼叫狀態和漫遊狀態,該檔案產生的音訊路徑為下行音訊或者傳輸給揚聲器或耳機。
對於提示音,可以通過Ringtone來播放;Ringtone和RingtoneManager為鈴聲、提示音、鬧鐘等提供了快速播放,以及管理介面。實質是對媒體播放器提供了一個簡單的封裝。
對於錄音功能,則需要通過MediaRecorder和AudioRecord等來進行音訊記錄。
除了這些直接的音訊類外,對於音量調節、音訊裝置的管理等,Android還提供了相關的類來處理。
對於遊戲中的音訊資源,可以通過SoundPool來播放。
SoundPool能夠播放音訊流的組合音,這對遊戲應用而言顯然非常有用。SoundPool可以從APK包中的資原始檔或者檔案系統中的檔案將音訊資源載入到記憶體中。在底層的實現上,SoundPool通過媒體播放服務可以將音訊資源解碼為一個16bit的單聲道或者立體聲的PCM流,這使得應用避免了在回放過程中進行解碼造成的延遲。除了回放過程中延遲小的優點外,SoundPool還能夠對一定數量的音訊流進行同時播放。當要播放的音訊流數量超過SoundPool所設定的最大值時,SoundPool將會停止已播放的一條低優先順序的音訊流。SoundPool最大播放音訊流數量的設定,可以避免CPU過載和影響UI體驗。
Android平臺中關於音訊的播放還有另一種方式是MediaPlayer。MediaPlayer得特點是同一時間只能播放一個,適合較長但是對時間要求不高的情況。
二、MediaServer分析
MediaServer是整個android中media部分的核心和靈魂。幾乎所有與多媒體播放相關的內容都放在這裡。包括了音視訊的編解碼以及顯示輸出。
1. 先初始化AudioFlinger
其初始化通過AudioFlinger的父類BindService建立唯一的AudioFlinger例項。
2. 然後初始化MediaPlayerService
3. 最後初始化AudioPolicyService
三、AudioPolicyService 和 AudioPolicyManager分析
AudioPolicyService是Android音訊系統的兩大服務之一,另一個服務是AudioFlinger,這兩大服務都在系統啟動時有 MediaSever載入。
AudioPolicyService主要完成以下任務:
l JAVA應用層通過JNI,經由IAudioPolicyService介面,訪問AudioPolicyService提供的服務
l 輸入輸出裝置的連線狀態
l 系統的音訊策略(strategy)的切換
l 音量/音訊引數的設定
AudioPolicyManager
AudioPolicyService的很大一部分管理工作都是在AudioPolicyManager中完成的。包括音量管理,音訊策略(strategy)管理,輸入輸出裝置管理。
通過AudioPolicyService的 AudioCommandThread,最終會將設定應用到AudioFlinger的相應的Track中。
四、 AudioFlinger分析
AudioFlinger負責管理每個音軌AudioTrack及RecordTrack,主音量控制,每種聲音流的屬性設定,裝置控制,音效控制。AudioFlinger是android中的一個service,在android啟動時就已經被載入。
播放執行緒實際上是MixerThread的一個例項,會把該執行緒中的各個Track進行混合,必要時還要進行ReSample(重取樣)的動作,轉換為統一的取樣率(44.1K),然後通過音訊系統的AudioHardware層輸出音訊資料。
SRC[Sample Rate Converter,取樣頻率轉換] SRC的作用就是改變訊號的取樣率,低取樣率往高取樣率轉換時就是一個重取樣的過程,重取樣物件不再是原始訊號,而是這個低取樣率的訊號,因為取樣率不夠需要插入更多的取樣點以達到需要的取樣率和取樣大小。
三種平臺的音訊架構對比
一、android平臺
Android使用的是為智慧終端專門制定的ALSA(AdvancedLinux Sound Architecture,高階Linux聲音架構)框架。
從Android的音訊架構及流程分析,由於其驅動庫位於核心層,也就意味著音訊裝置廠商、使用者無法象PC平臺那樣安裝驅動來改善音質。我們在實際的應用中也能感受到,Android裝置音質普遍偏差。音質出現偏差一個主要的問題是處在SRC這裡。低取樣率往高取樣率轉換時就是一個重取樣的過程,重取樣物件不再是原始訊號,而是這個低取樣率的訊號,因為取樣率不夠需要插入更多的取樣點以達到需要的取樣率和取樣大小
理論上SRC可以通過更換演算法來實現音質提升,但卻不太現實,SRC需要大量的浮點運算的資源,即便有了高質量的SRC演算法,其運算也是以犧牲裝置效能和耗電量為代價的,實用性差。
二、windowsphone平臺
通用音訊架構(UAA)
UAA分為獨佔模式和共享模式,它最大程度的降低了音訊裝置驅動對系統穩定性的影響,而且還能夠增加訊號處理流程的透明度,處理環節可以得到控制,在理論上說,它可以實現更加優秀的音質,也能非常顯著的提升系統響應速度,大幅減低延時
應用程式在一般情況下都是走Shared Mode(共享模式)那條路徑,這個路徑被稱作通道,根據上面關於共享模式的介紹,所有的聲音訊號都會轉送至Audio Engine(音效引擎)部分,有軟體混音動作,就可能會經過SRC,使得聲音出現偏差。而當應用程式發出使用獨佔模式的需求後,系統會切斷共享模式這一條路徑,聲音訊號就會直接送達Kernel Mode最後到達底層的音訊裝置後輸出,音訊裝置在此時也會完全100%配合獨佔模式送來的音訊格式進行處理。
三、iOS平臺
我們再把目光投向iOS,iOS非常封閉,我們甚至無法獲知其架構的具體構成,但iOS裝置不存在硬體裝置多樣性的問題,因此要實現更好音質也會更加簡單。iOS可以實現針對性的開發和改良,以實現更好的音質。實際情況也是如此,目前為止,還沒有一款Android裝置的音質可以媲美任意一款iOS裝置,這種差距,我們認為不是來自硬體,而是作業系統。