Android AudioPolicyService和AudioPolicyManager


 AudioPolicyService是Android音頻系統的兩大服務之一,另一個服務是AudioFlinger,這兩大服務都在系統啟動時有 MediaSever加載,加載的代碼位於:frameworks\base\media\mediaserver \main_mediaserver.cpp。AudioFlinger主要負責管理音頻數據處理以及和硬件抽象層相關的工作。本文主要介紹 AudioPolicyService。
AudioPolicyService
    
       AudioPolicyService主要完成以下任務:

       JAVA應用層通過JNI,經由IAudioPolicyService接口,訪問AudioPolicyService提供的服務 輸入輸出設備的連接狀態系統的音頻策略(strategy)的切換音量/音頻參數的設置 
    
       AudioPolicyService的構成
       進一步說明:

       1. AudioPolicyService繼承了IAudioPolicyService接口,這樣AudioPolicyService就可以基於Android的Binder機制,向外部提供服務;

        2. AudioPolicyService同時也繼承了AudioPolicyClientInterface類,他有一個AudioPolicyInterface類的成員指針mpPolicyManager,實際上就是指向了AudioPolicyManager;

       3. AudioPolicyManager類繼承了AudioPolicyInterface類以便向AudioPolicyService提供服務,反過來同時還有一個AudioPolicyClientInterface指針,該指針在構造函數中被初始化,指向了AudioPolicyService,實際上,AudioPolicyService是通過成員指針mpPolicyManager訪問AudioPolicyManager,而 AudioPolicyManager則通過AudioPolicyClientInterface(mpClientInterface)訪問 AudioPolicyService;

       4. AudioPolicyService有一個內部線程類AudioCommandThread,顧名思義,所有的命令(音量控制,輸入、輸出的切換等)最終都會在該線程中排隊執行;

       AudioPolicyManager

       AudioPolicyService的很大一部分管理工作都是在AudioPolicyManager中完成的。包括音量管理,音頻策略(strategy)管理,輸入輸出設備管理。

       輸入輸出設備管理

       音頻系統為音頻設備定義了一個枚舉:AudioSystem::audio_devices,例如:DEVICE_OUT_SPEAKER,DEVICE_OUT_WIRED_HEADPHONE,DEVICE_OUT_BLUETOOTH_A2DP,DEVICE_IN_BUILTIN_MIC,DEVICE_IN_VOICE_CALL 等等,每一個枚舉值其實對應一個32bit整數的某一個位,所以這些值是可以進行位或操作的,例如我希望同時打開揚聲器和耳機,那么可以這樣:

java代碼:

  1. newDevice = DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADPHONE; 
  2. setOutputDevice(mHardwareOutput, newDevice);
復制代碼


       AudioPolicyManager中有兩個成員變量:mAvailableOutputDevices和 mAvailableInputDevices,他們記錄了當前可用的輸入和輸出設備,當系統檢測到耳機或者藍牙已連接好時,會調用 AudioPolicyManager的成員函數:

java代碼:

  1. status_t AudioPolicyManager::setDeviceConnectionState(AudioSystem::audio_devices device, 
  2. AudioSystem::device_connection_state state, 
  3. const char *device_address)
復制代碼


       該函數根據傳入的device值和 state(DEVICE_STATE_AVAILABLE/DEVICE_STATE_UNAVAILABLE)設置 mAvailableOutputDevices或者mAvailableInputDevices,然后選擇相應的輸入或者輸出設備。

       其他一些相關的函數:

java代碼:

  1. setForceUse() 
  2. //設置某種場合強制使用某一設備,例如setForceUse(FOR_MEDIA, FORCE_SPEAKER)會在播放音樂時打開揚聲器 
  3. startOutput()/stopOutput() 
  4. startInput()/stopInput() 


 音量管理
       AudioPolicyManager提供了一下幾個與音量相關的函數:

java代碼:

  1. initStreamVolume(AudioSystem::stream_type stream, int indexMin, int indexMax) 
  2. setStreamVolumeIndex(AudioSystem::stream_type stream, int index) 
  3. getStreamVolumeIndex(AudioSystem::stream_type stream)


       由此可見,電話鈴聲可以有7個級別的音量,而音樂則可以有15個音量級別,java的代碼通過jni,最后調用 AudioPolicyManager的initStreamVolume(),把這個數組的內容傳入AudioPolicyManager中,這樣 AudioPolicyManager也就記住了每一個音頻流的音量級別。應用程序可以調用setStreamVolumeIndex設置各個音頻流的音量級別,setStreamVolumeIndex會把這個整數的音量級別轉化為適合人耳的對數級別,然后通過AudioPolicyService的 AudioCommandThread,最終會將設置應用到AudioFlinger的相應的Track中。

轉載地址:http://www.eoeandroid.com/thread-76214-1-1.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM