小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Android Audio System 之三: AudioPolicyService 和...

 John.Bouson 2012-01-08

Android Audio System 之三: AudioPolicyService 和 AudioPolicyManager

分類: 移動(dòng)開(kāi)發(fā)之Android 10889人閱讀 評(píng)論(7) 收藏 舉報(bào)

引言

    AudioPolicyService是Android音頻系統(tǒng)的兩大服務(wù)之一,另一個(gè)服務(wù)是AudioFlinger,這兩大服務(wù)都在系統(tǒng)啟動(dòng)時(shí)有MediaSever加載,加載的代碼位于:frameworks/base/media/mediaserver/main_mediaserver.cpp。AudioFlinger主要負(fù)責(zé)管理音頻數(shù)據(jù)處理以及和硬件抽象層相關(guān)的工作。本文主要介紹AudioPolicyService。

AudioPolicyService

    AudioPolicyService主要完成以下任務(wù):

  • JAVA應(yīng)用層通過(guò)JNI,經(jīng)由IAudioPolicyService接口,訪問(wèn)AudioPolicyService提供的服務(wù)
  • 輸入輸出設(shè)備的連接狀態(tài)
  • 系統(tǒng)的音頻策略(strategy)的切換
  • 音量/音頻參數(shù)的設(shè)置

    AudioPolicyService的構(gòu)成

    下面這張圖描述了AudioPolicyService的靜態(tài)結(jié)構(gòu):

 

進(jìn)一步說(shuō)明:

1. AudioPolicyService繼承了IAudioPolicyService接口,這樣AudioPolicyService就可以基于Android的Binder機(jī)制,向外部提供服務(wù);

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

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

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

AudioPolicyManager

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

輸入輸出設(shè)備管理

音頻系統(tǒng)為音頻設(shè)備定義了一個(gè)枚舉:AudioSystem::audio_devices,例如:DEVICE_OUT_SPEAKER,DEVICE_OUT_WIRED_HEADPHONE,DEVICE_OUT_BLUETOOTH_A2DP,DEVICE_IN_BUILTIN_MIC,DEVICE_IN_VOICE_CALL等等,每一個(gè)枚舉值其實(shí)對(duì)應(yīng)一個(gè)32bit整數(shù)的某一個(gè)位,所以這些值是可以進(jìn)行位或操作的,例如我希望同時(shí)打開(kāi)揚(yáng)聲器和耳機(jī),那么可以這樣:

  1. newDevice = DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADPHONE;  
  2. setOutputDevice(mHardwareOutput, newDevice);  

AudioPolicyManager中有兩個(gè)成員變量:mAvailableOutputDevices和mAvailableInputDevices,他們記錄了當(dāng)前可用的輸入和輸出設(shè)備,當(dāng)系統(tǒng)檢測(cè)到耳機(jī)或者藍(lán)牙已連接好時(shí),會(huì)調(diào)用AudioPolicyManager的成員函數(shù):

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

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

其他一些相關(guān)的函數(shù):

  • setForceUse()  設(shè)置某種場(chǎng)合強(qiáng)制使用某一設(shè)備,例如setForceUse(FOR_MEDIA, FORCE_SPEAKER)會(huì)在播放音樂(lè)時(shí)打開(kāi)揚(yáng)聲器
  • startOutput()/stopOutput()
  • startInput()/stopInput()

音量管理

AudioPolicyManager提供了一下幾個(gè)與音量相關(guān)的函數(shù):

  • initStreamVolume(AudioSystem::stream_type stream, int indexMin, int indexMax)
  • setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
  • getStreamVolumeIndex(AudioSystem::stream_type stream)

AudioService.java中定義了每一種音頻流的最大音量級(jí)別:

  1. /** @hide Maximum volume index values for audio streams */  
  2.     private int[] MAX_STREAM_VOLUME = new int[] {  
  3.         5,  // STREAM_VOICE_CALL   
  4.         7,  // STREAM_SYSTEM   
  5.         7,  // STREAM_RING   
  6.         15, // STREAM_MUSIC   
  7.         7,  // STREAM_ALARM   
  8.         7,  // STREAM_NOTIFICATION   
  9.         15, // STREAM_BLUETOOTH_SCO   
  10.         7,  // STREAM_SYSTEM_ENFORCED   
  11.         15, // STREAM_DTMF   
  12.         15  // STREAM_TTS   
  13.     };  

由此可見(jiàn),電話鈴聲可以有7個(gè)級(jí)別的音量,而音樂(lè)則可以有15個(gè)音量級(jí)別,java的代碼通過(guò)jni,最后調(diào)用AudioPolicyManager的initStreamVolume(),把這個(gè)數(shù)組的內(nèi)容傳入AudioPolicyManager中,這樣AudioPolicyManager也就記住了每一個(gè)音頻流的音量級(jí)別。應(yīng)用程序可以調(diào)用setStreamVolumeIndex設(shè)置各個(gè)音頻流的音量級(jí)別,setStreamVolumeIndex會(huì)把這個(gè)整數(shù)的音量級(jí)別轉(zhuǎn)化為適合人耳的對(duì)數(shù)級(jí)別,然后通過(guò)AudioPolicyService的AudioCommandThread,最終會(huì)將設(shè)置應(yīng)用到AudioFlinger的相應(yīng)的Track中。

音頻策略管理

 我想首先要搞清楚stream_type,device,strategy三者之間的關(guān)系:

  • AudioSystem::stream_type  音頻流的類型,一共有10種類型
  • AudioSystem::audio_devices  音頻輸入輸出設(shè)備,每一個(gè)bit代表一種設(shè)備,見(jiàn)前面的說(shuō)明
  • AudioPolicyManager::routing_strategy 音頻路由策略,可以有4種策略

getStrategy(stream_type)根據(jù)stream type,返回對(duì)應(yīng)的routing strategy值,getDeviceForStrategy()則是根據(jù)routing strategy,返回可用的device。Android把10種stream type歸納為4種路由策略,然后根據(jù)路由策略決定具體的輸出設(shè)備。

 

成員變量mOutputs

  1. KeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mOutputs;   // list of output descriptors  

這是AudioPolocyManager用管理輸出的鍵值對(duì)向量(數(shù)組),通常AudioPolocyManager會(huì)打開(kāi)3個(gè)輸出句柄(audio_io_handle_t),關(guān)于audio_io_handle_t,請(qǐng)參考另一編博客:http://blog.csdn.net/DroidPhone/archive/2010/10/14/5941344.aspx,它實(shí)際上就是AudioFlinger中某個(gè)PlaybackTread的ID。這3個(gè)句柄分別是:

  • mHardwareOutput            // hardware output handler
  • mA2dpOutput                   // A2DP output handler
  • mDuplicatedOutput          // duplicated output handler: outputs to hardware and A2DP

可以通過(guò)startOutput()把某一個(gè)stream type放入到相應(yīng)的輸出中。

 

popCount()

這個(gè)函數(shù)主要用來(lái)計(jì)算device變量中有多少個(gè)非0位(計(jì)算32位數(shù)種1的個(gè)數(shù)),例如該函數(shù)返回2,代表同時(shí)有兩個(gè)device要處理。之所以特別介紹它,是因?yàn)檫@個(gè)函數(shù)的實(shí)現(xiàn)很有意思:

  1. uint32_t AudioSystem::popCount(uint32_t u)  
  2. {  
  3.     u = ((u&0x55555555) + ((u>>1)&0x55555555));  
  4.     u = ((u&0x33333333) + ((u>>2)&0x33333333));  
  5.     u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));  
  6.     u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));  
  7.     u = ( u&0x0000ffff) + (u>>16);  
  8.     return u;  
  9. }  

不知道各位看懂了么?

 

 

AudioCommandThread

    這是AudioPolicyService中的一個(gè)線程,主要用于處理音頻設(shè)置相關(guān)的命令。包括:

  • START_TONE
  • STOP_TONE
  • SET_VOLUME
  • SET_PARAMETERS
  • SET_VOICE_VOLUME

     每種命令的參數(shù)有相應(yīng)的包裝:

  • class ToneData
  • class VolumeData
  • class ParametersData
  • class VoiceVolumeData

    START_TONE/STOP_TONE:播放電話系統(tǒng)中常用的特殊音調(diào),例如:TONE_DTMF_0,TONE_SUP_BUSY等等。

    SET_VOLUME:最終會(huì)調(diào)用AudioFlinger進(jìn)行音量設(shè)置

    SET_VOICE_VOLUME:最終會(huì)調(diào)用AudioFlinger進(jìn)行電話音量設(shè)置

    SET_PARAMETERS:通過(guò)一個(gè)KeyValuePairs形式的字符串進(jìn)行參數(shù)設(shè)置,KeyValuePairs的格式可以這樣:

 

  •  "sampling_rate=44100"
  • "channels=2"
  • "sampling_rate=44100;channels=2"     // 組合形式

    這些KeyValuePairs可以通過(guò)AudioPolicyService的成員函數(shù)setParameters()傳入。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多