在系統啟動時MediaSever載入了兩個服務:AudioPolicyService和AudioFlinger。
1.3.1 AudioPolicyService
AudioPolicyService主要完成以下任務
JAVA應用程式層通過JNI,經由IAudioPolicyService介面,訪問AudioPolicyService提供的服務
輸入輸出裝置的串連狀態
系統的音頻策略(strategy)的切換
音量/音頻參數的設定
1.3.2 AudioFlinger
AudioFlinger向下訪問AudioHardware,實現輸出音頻資料,控制音頻參數。同時,AudioFlinger向上通過IAudioFinger介面提供服務。所以,AudioFlinger在Android的音頻系統架構中起著承上啟下的作用
1.3.3 how towork
AudioTrack:Android的音頻子系統中,每一個音頻流對應著一個AudioTrack類的一個執行個體,每個AudioTrack會在建立時註冊到AudioFlinger中,由AudioFlinger把所有的AudioTrack進行混合(Mixer),然後輸送到AudioHardware中進行播放,目前Android的Froyo版本設定了同時最多可以建立32個音頻流,開闢的空間是1M,每個音軌32K,也就是說,Mixer最多會同時處理32個AudioTrack的資料流。
binder:AudioTrack和AudioFlinger並不在同一個進程中,它們通過android中的binder機制建立聯絡。
audio_track_cblk_t實現了一個環形FIFO;
AudioTrack是FIFO的資料生產者;
AudioFlinger是FIFO的資料消費者。
建立聯絡的過程
Java層通過JNI,new AudioTrack();
根據StreamType等參數,通過一系列的調用getOutput();
如有必要,AudioFlinger根據StreamType開啟不同硬體裝置;
AudioFlinger為該輸出裝置建立混音線程:MixerThread(),並把該線程的id作為getOutput()的傳回值返回給AudioTrack;
AudioTrack通過binder機制調用AudioFlinger的createTrack();
AudioFlinger註冊該AudioTrack到MixerThread中;
AudioFlinger建立一個用於控制的TrackHandle,並以IAudioTrack這一介面作為createTrack()的傳回值;
AudioTrack通過IAudioTrack介面,得到在AudioFlinger中建立的FIFO(audio_track_cblk_t);
AudioTrack建立自己的監控線程:AudioTrackThread;
自此,AudioTrack建立了和AudioFlinger的全部聯絡工作,接下來,AudioTrack可以:通過IAudioTrack介面控制該音軌的狀態,例如start,stop,pause等等;通過對FIFO的寫入,實現連續的音頻播放;監控線程監控事件的發生,並通過audioCallback回呼函數與使用者程式進行互動;
FIFO的管理
audio_track_cblk_t結構是FIFO實現的關鍵,該結構是在createTrack的時候,由AudioFlinger申請相應的記憶體,然後通過IMemory介面返回AudioTrack的,這樣AudioTrack和AudioFlinger管理著同一個 audio_track_cblk_t,通過它實現了環形FIFO,AudioTrack向FIFO中寫入音頻資料,AudioFlinger從FIFO 中讀取音頻資料,經Mixer後送給AudioHardware進行播放。
audio_track_cblk_t的主要資料成員:
user -- AudioTrack當前的寫位置的位移
userBase -- AudioTrack寫位移的基準位置,結合user的值方可確定FIFO地址指標
server -- AudioFlinger當前的讀位置的位移
serverBase -- AudioFlinger讀位移的基準位置,結合server的值方可確定FIFO地址指標
frameCount -- FIFO的大小,以音頻資料的幀為單位,16bit的音頻每幀的大小是2位元組
buffers -- 指向FIFO的起始地址
out -- 音頻流的方向,對於AudioTrack,out=1,對於AudioRecord,out=0
audio_track_cblk_t的主要成員函數:
framesAvailable_l()和framesAvailable()用於擷取FIFO中可寫的空閑空間的大小,只是加鎖和不加鎖的區別。