日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Android深入淺出之Audio第三部分AudioPolicy

一 目的

我們提供的服務(wù)有:做網(wǎng)站、網(wǎng)站制作、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、精河ssl等。為近千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的精河網(wǎng)站制作公司

上回我們說(shuō)了AudioFlinger(AF),總感覺(jué)代碼里邊有好多東西沒(méi)說(shuō)清楚,心里發(fā)毛。就看了看AF的流程,我們敢說(shuō)自己深入了解了Android系統(tǒng)嗎?AudioPolicyService(APS)是個(gè)什么東西?為什么要有它的存在?下層的Audio HAL層又是怎么結(jié)合到Android中來(lái)的?更有甚者,問(wèn)個(gè)實(shí)在問(wèn)題:插入耳機(jī)后,聲音又怎么從最開(kāi)始的外放變成從耳機(jī)輸出了?調(diào)節(jié)音量的時(shí)候到底是調(diào)節(jié)Music的還是調(diào)節(jié)來(lái)電音量呢?這些東西,我們?cè)贏F的流程中統(tǒng)統(tǒng)都沒(méi)講到。但是這些他們又是至關(guān)重要的。從我個(gè)人理解來(lái)看,策略(Policy)比流程更復(fù)雜和難懂。

當(dāng)然,遵循我們的傳統(tǒng)分析習(xí)慣,得有一個(gè)切入點(diǎn),否則我們都不知道從何入手了。

這里的切入點(diǎn)將是:

l         AF和APS系統(tǒng)第一次起來(lái)后,到底干了什么。

l         檢測(cè)到耳機(jī)插入事件后,AF和APS的處理。

大家跟著我一步步來(lái)看,很快就發(fā)現(xiàn),啊哈,APS也不是那么難嘛。

另外,這次代碼分析的格式將參考《Linux內(nèi)核情景分析》的樣子,函數(shù)調(diào)用的解析將采用深度優(yōu)先的辦法,即先解釋所調(diào)用的函數(shù),然后再出來(lái)繼續(xù)講。

我曾經(jīng)數(shù)度放棄分析APS,關(guān)鍵原因是我沒(méi)找到切入點(diǎn),只知道代碼從頭看到尾!

二 AF和APS的誕生

這個(gè)東西,已經(jīng)說(shuō)得太多了。在framework/base/media/MediaServer/Main_MediaServer中。

我們看看。

 
 
 
  1. int main(int argc, char** argv) 
  2.  
  3.  
  4.     sp proc(ProcessState::self()); 
  5.  
  6.     sp sm = defaultServiceManager(); 
  7.  
  8.     //先創(chuàng)建AF 
  9.  
  10. AudioFlinger::instantiate(); 
  11.  
  12.     //再創(chuàng)建APS 
  13.  
  14. AudioPolicyService::instantiate(); 
  15.  
  16.   
  17.  
  18.     ProcessState::self()->startThreadPool(); 
  19.  
  20.     IPCThreadState::self()->joinThreadPool(); 
  21.  

2.1 new AudioFlinger

前面說(shuō)過(guò),instantiate內(nèi)部會(huì)實(shí)例化一個(gè)對(duì)象,那直接看AF的構(gòu)造函數(shù)。

 
 
 
  1. AudioFlinger::AudioFlinger() 
  2.  
  3.     : BnAudioFlinger(),//基類構(gòu)造函數(shù) 
  4.  
  5.         mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextThreadId(0) 
  6.  

注意mAudioHardware和mNextThreadId

mHardwareStatus = AUDIO_HW_IDLE;

//創(chuàng)建audio的HAL代表

    mAudioHardware = AudioHardwareInterface::create();

mHardwareStatus = AUDIO_HW_INIT;

//下面這些不至于會(huì)使用APS吧?APS還沒(méi)創(chuàng)建呢!

 
 
 
  1. if (mAudioHardware->initCheck() == NO_ERROR) { 
  2.  
  3.        setMode(AudioSystem::MODE_NORMAL); 
  4.  
  5.        setMasterVolume(1.0f); 
  6.  
  7.        setMasterMute(false); 
  8.  
  9.    } 

感覺(jué)上,AF的構(gòu)造函數(shù)就是創(chuàng)建了一個(gè)最重要的AudioHardWare的HAL代表。

其他好像是沒(méi)干什么策略上的事情。

不過(guò):AF創(chuàng)建了一個(gè)AudioHardware的HAL對(duì)象。注意整個(gè)系統(tǒng)就這一個(gè)AudioHardware了。也就是說(shuō),不管是線控耳機(jī),藍(lán)牙耳機(jī),麥克,外放等等,最后都會(huì)由這一個(gè)HAL統(tǒng)一管理。

再看APS吧。

2.2 new AudioPolicyService

 
 
 
  1. AudioPolicyService::AudioPolicyService() 
  2.  
  3.     : BnAudioPolicyService() , mpPolicyManager(NULL) 
  4.  
  5.  
  6.   //  mpPolicyManager?策略管理器?可能很重要 
  7.  
  8. char value[PROPERTY_VALUE_MAX]; 
  9.  
  10.   
  11.  
  12.     // TonePlayback?播放鈴聲的?為什么放在這里?以后來(lái)看看 
  13.  
  14.     mTonePlaybackThread = new AudioCommandThread(String8("")); 
  15.  
  16. // Audio Command?音頻命令?看到Command,我就想到設(shè)計(jì)模式中的Command模式了 
  17.  
  18. //Android尤其是MediaPlayerService中大量使用了這種模式。 
  19.  
  20.     mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread")); 
  21.  
  22.   
  23.  
  24. #if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST) 
  25.  
  26.  //注意AudioPolicyManagerBase的構(gòu)造函數(shù),把this傳進(jìn)去了。 
  27.  
  28.     mpPolicyManager = new AudioPolicyManagerBase(this); 
  29.  
  30.     //先假設(shè)我們使用Generic的Audio設(shè)備吧。 
  31.  
  32. #else 
  33.  
  34.     ... 
  35.  
  36.     
  37.  
  38. #endif 

// 根據(jù)系統(tǒng)屬性來(lái)判斷攝像機(jī)是否強(qiáng)制使用聲音。這個(gè)...為什么會(huì)放在這里?

//手機(jī)帶攝像機(jī)好像剛出來(lái)的時(shí)候,為了防止偷拍,強(qiáng)制按快門(mén)的時(shí)候必須發(fā)出聲音

//就是這個(gè)目的吧?

 
 
 
  1.  property_get("ro.camera.sound.forced", value, "0"); 
  2.  
  3. mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value); 
  4.  

so easy!,不至于吧?我們不應(yīng)該放過(guò)任何一個(gè)疑問(wèn)!這么多疑問(wèn),先看哪個(gè)呢?這里分析的是Audio Policy,而構(gòu)造函數(shù)中又創(chuàng)建了一個(gè)AudioPolicyManagerBase,而且不同廠商還可以實(shí)現(xiàn)自己的AudioPolicyManager,看來(lái)這個(gè)對(duì)于音頻策略有至關(guān)重要的作用了。

不得不說(shuō)的是,Android代碼中的這些命名在關(guān)鍵地方上還是比較慎重和準(zhǔn)確的。

另外,AudioPolicyManagerBase的構(gòu)造函數(shù)可是把APS傳進(jìn)去了,看來(lái)又會(huì)有一些回調(diào)靠APS了。真繞。

2.3 AudioPolicyManagerBase

代碼位置在framework/base/libs/audioflinger/AudioPolicyManagerBase.cpp中

 
 
 
  1. AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface) 
  2.  
  3.     : 
  4.  
  5.  mPhoneState(AudioSystem::MODE_NORMAL), ---->這里有電話的狀態(tài)? 
  6.  
  7. mRingerMode(0), 
  8.  
  9. mMusicStopTime(0), 
  10.  
  11.  mLimitRingtoneVolume(false) 
  12.  
  13.  
  14. [--->mPhoneState(AudioSystem::MODE_NORMAL)] 

   AudioSystem其實(shí)是窺視Android如何管理音頻系統(tǒng)的好地方。位置在

framework/base/include/media/AudioSystem.h中,定義了大量的枚舉之類的東西來(lái)表達(dá)Google對(duì)音頻系統(tǒng)的看法。我們只能見(jiàn)招拆招了。

下面是audio_mode的定義。這里要注意一個(gè)地方:

這些定義都和SDK中的JAVA層定義類似。實(shí)際上應(yīng)該說(shuō)先有C++層的定義,然后再反映到JAVA層中。但是C++層的定義一般沒(méi)有解釋說(shuō)明,而SDK中有。所以我們不能不面對(duì)的一個(gè)痛苦現(xiàn)實(shí)就是:常常需要參考SDK的說(shuō)明才能搞明白到底是什么。

關(guān)于C++的AudioSystem這塊,SDK的說(shuō)明在AudioManager中。

 
 
 
  1. enum audio_mode { 
  2.  
  3. //解釋參考SDK說(shuō)明,以下不再說(shuō)明 
  4.  
  5.         MODE_INVALID = -2, //無(wú)效mode 
  6.  
  7.         MODE_CURRENT = -1,//當(dāng)前mode,和音頻設(shè)備的切換(路由)有關(guān) 
  8.  
  9.         MODE_NORMAL = 0,//正常mode,沒(méi)有電話和鈴聲 
  10.  
  11.         MODE_RINGTONE,//收到來(lái)電信號(hào)了,此時(shí)會(huì)有鈴聲 
  12.  
  13.         MODE_IN_CALL,//電話mode,這里表示已經(jīng)建立通話了 
  14.  
  15.         NUM_MODES  // Android大量采用這種技巧來(lái)表示枚舉結(jié)束了。 
  16.  
  17.     }; 

好,繼續(xù):

 
 
 
  1. ... 
  2.  
  3. mPhoneState(AudioSystem::MODE_NORMAL), ---->這里有電話的狀態(tài)? 
  4.  
  5. mRingerMode(0), 
  6.  
  7. mMusicStopTime(0), 
  8.  
  9.  mLimitRingtoneVolume(false) 
  10.  
 
 
 
  1. mpClientInterface = clientInterface;//BT,保存APS對(duì)象。 
  2.  
  3. //forceUse?這是個(gè)什么玩意兒? 
  4.  
  5.     for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) { 
  6.  
  7.         mForceUse[i] = AudioSystem::FORCE_NONE; 
  8.  
  9.     } 

[---->AudioSystem::FORCE_NONE和AudioSystem::NUM_FORCE_USE]

注意,這里有兩個(gè)枚舉,太無(wú)恥了。先看看FORCE_NONE這個(gè)

 
 
 
  1. enum forced_config {強(qiáng)制_配置,看名字好像是強(qiáng)制使用設(shè)備吧,比如外放,耳機(jī),藍(lán)牙等 
  2.  
  3.         FORCE_NONE, 
  4.  
  5.         FORCE_SPEAKER, 
  6.  
  7.         FORCE_HEADPHONES, 
  8.  
  9.         FORCE_BT_SCO, 
  10.  
  11.         FORCE_BT_A2DP, 
  12.  
  13.         FORCE_WIRED_ACCESSORY, 
  14.  
  15.         FORCE_BT_CAR_DOCK, 
  16.  
  17.         FORCE_BT_DESK_DOCK, 
  18.  
  19.         NUM_FORCE_CONFIG, 
  20.  
  21.         FORCE_DEFAULT = FORCE_NONE //這個(gè),太無(wú)聊了。 
  22.  
  23. }; 

再看看AudioSystem::NUM_FORCE_USE這個(gè)

 
 
 
  1. enum force_use { 
  2.  
  3.         FOR_COMMUNICATION,//這里是for_xxx,不是force_xxx。 
  4.  
  5.         FOR_MEDIA, 
  6.  
  7.         FOR_RECORD, 
  8.  
  9.         FOR_DOCK, 
  10.  
  11.         NUM_FORCE_USE 
  12.  
  13.     }; 

不懂,兩個(gè)都不懂。為何?能猜出來(lái)什么嗎?也不行。因?yàn)槲覀儧](méi)找到合適的場(chǎng)景!那好吧,我們?nèi)DK找找。恩

我看到AudioManager這個(gè)函數(shù)setSpeakerphoneOn (boolean on)。好吧,我

這么調(diào)用

setSpeakerphoneOn(true),看看實(shí)現(xiàn)。

這次我沒(méi)再浪費(fèi)時(shí)間了,我用一個(gè)新的工具coolfind,把搜索framework目錄,尋找*.java文件,匹配字符串setSpeakerphone。終于,我在

 
 
 
  1. framework/base/media/java/android/media/AudioService.java中找到了。 
  2.  
  3. public void setSpeakerphoneOn(boolean on){ 
  4.  
  5.         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { 
  6.  
  7.             return; 
  8.  
  9.         } 
  10.  
  11.         if (on) { 

//看到這里,是不是明白十之八九了?下面這個(gè)調(diào)用是:

//強(qiáng)制通話使用speaker!原來(lái)是這么個(gè)意思!

        

 
 
 
  1. AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, 
  2.  
  3. ioSystem.FORCE_SPEAKER); 
  4.  
  5.          mForcedUseForComm = AudioSystem.FORCE_SPEAKER; 
  6.  
  7.      } else { 
  8.  
  9.          AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, 
  10.  
  11. ioSystem.FORCE_NONE); 
  12.  
  13.          mForcedUseForComm = AudioSystem.FORCE_NONE; 
  14.  
  15.      } 
  16.  
  17.  } 

好了,說(shuō)點(diǎn)題外話,既然Android源碼都放開(kāi)給我們了,有什么理由我們不去多搜搜呢?上網(wǎng)google也是搜,查源代碼也是一樣嗎。不過(guò)我們要有目的:就是找到一個(gè)合適的使用場(chǎng)景。

force_use和force_config就不用我再解釋了吧?

 
 
 
  1. [--->AudioPolicyManagerBase::AudioPolicyManagerBase] 
  2.  
  3. ... 

//下面這個(gè)意思就是把幾種for_use的情況使用的設(shè)備全部置為NONE。

//比如設(shè)置FOR_MEDIA的場(chǎng)景,使用的設(shè)備就是FORCE_NONE

 
 
 
  1. for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) { 
  2.  
  3.         mForceUse[i] = AudioSystem::FORCE_NONE; 
  4.  
  5.     } 

  // 目前可以的輸出設(shè)備,耳機(jī)和外放

 
 
 
  1.  mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE | 
  2.  
  3.                         AudioSystem::DEVICE_OUT_SPEAKER; 
  4.  
  5. //目前可用的輸入設(shè)備,內(nèi)置MIC 
  6.  
  7.     mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC; 
  8.  
  9. 又得來(lái)看看AudioSystem是怎么定義輸入輸出設(shè)備的了。 
  10.  
  11. [--->mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE] 
  12.  
  13. enum audio_devices { 
  14.  
  15.         // output devices 
  16.  
  17.         DEVICE_OUT_EARPIECE = 0x1, 
  18.  
  19.         DEVICE_OUT_SPEAKER = 0x2, 
  20.  
  21.         DEVICE_OUT_WIRED_HEADSET = 0x4, 
  22.  
  23.         DEVICE_OUT_WIRED_HEADPHONE = 0x8, 
  24.  
  25.         DEVICE_OUT_BLUETOOTH_SCO = 0x10, 
  26.  
  27.         DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20, 
  28.  
  29.         DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40, 
  30.  
  31.         DEVICE_OUT_BLUETOOTH_A2DP = 0x80, 
  32.  
  33.         DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100, 
  34.  
  35.         DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200, 
  36.  
  37.         DEVICE_OUT_AUX_DIGITAL = 0x400, 
  38.  
  39.         DEVICE_OUT_DEFAULT = 0x8000, 
  40.  
  41.         DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | 
  42.  
  43.  DEVICE_OUT_WIRED_HEADSET | DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO | DEVICE_OUT_BLUETOOTH_SCO_HEADSET |DEVICE_OUT_BLUETOOTH_SCO_CARKIT | 
  44.  
  45.  DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | 
  46.  
  47.  DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL | DEVICE_OUT_DEFAULT), 
  48.  
  49.    DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | 
  50.  
  51. DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER), 
  52.  
  53.   
  54.  
  55.         // input devices 
  56.  
  57.         DEVICE_IN_COMMUNICATION = 0x10000, 
  58.  
  59.         DEVICE_IN_AMBIENT = 0x20000, 
  60.  
  61.         DEVICE_IN_BUILTIN_MIC = 0x40000, 
  62.  
  63.         DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x80000, 
  64.  
  65.         DEVICE_IN_WIRED_HEADSET = 0x100000, 
  66.  
  67.         DEVICE_IN_AUX_DIGITAL = 0x200000, 
  68.  
  69.         DEVICE_IN_VOICE_CALL = 0x400000, 
  70.  
  71.         DEVICE_IN_BACK_MIC = 0x800000, 
  72.  
  73.         DEVICE_IN_DEFAULT = 0x80000000, 
  74.  
  75.         DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | 
  76.  
  77. DEVICE_IN_BUILTIN_MIC |DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | 
  78.  
  79.   DEVICE_IN_AUX_DIGITAL | DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | 
  80.  
  81. DEVICE_IN_DEFAULT) 
  82.  
  83.     }; 

一些比較容易眼花的東西我標(biāo)成紅色的了。這么多東西,不過(guò)沒(méi)什么我們不明白的了。

得嘞,繼續(xù)走。

[--->AudioPolicyManagerBase::AudioPolicyManagerBase]

// 目前可以的輸出設(shè)備,又有耳機(jī)又有外放,配置很強(qiáng)悍啊。

//注意這里是OR操作符,最終mAvailableOutputDevices = 0X3

    mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE |

                        AudioSystem::DEVICE_OUT_SPEAKER;

//目前可用的輸入設(shè)備,內(nèi)置MIC,mAvailableInputDevices為0x4000,不過(guò)我們不關(guān)注input

 mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC;

下面東西就很少了,我們一氣呵成。

//創(chuàng)建一個(gè)AudioOutputDescriptor,并設(shè)置它的device為外設(shè)0x2

 
 
 
  1. AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(); 
  2.  
  3. outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER; 

//調(diào)用APS的openOutput,得到一個(gè)mHardwareOutput東東。這是個(gè)int型

//不過(guò)保不準(zhǔn)是一個(gè)指針也不一定喔。

//而且,下面的參數(shù)都是指針類型(flags除外),難道?有人會(huì)改value嗎?

 
 
 
  1. mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice, 
  2.  
  3.                                     &outputDesc->mSamplingRate, 
  4.  
  5.                                     &outputDesc->mFormat, 
  6.  
  7.                                     &outputDesc->mChannels, 
  8.  
  9.                                     &outputDesc->mLatency, 
  10.  
  11.                                     outputDesc->mFlags); 

//這個(gè)...估計(jì)是把int和指針加入到一個(gè)map了,方便管理。

addOutput(mHardwareOutput, outputDesc);

//不知道干嘛,待會(huì)看。

setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true);

//不知道干嘛,待會(huì)看。

    updateDeviceForStrategy();

好了,上面還有一系列函數(shù),等著我們調(diào)用呢。我們一個(gè)一個(gè)看。

提前說(shuō)一下,這塊可是AudioManagerBase的核心喔。

[---->AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor()]

AudioOutputDescriptor是個(gè)什么?我不是神,我也得看注釋。

// descriptor for audio outputs. Used to maintain current configuration of each opened audio output

// and keep track of the usage of this output by each audio stream type.

明白了么?大概意思就是它,是這么一個(gè)東西:

l         描述audio輸出的,可以用來(lái)保存一些配置信息。

l         跟蹤音頻stream類型使用這個(gè)output的一些情況。

沒(méi)明白吧?以后碰到場(chǎng)景就明白了。

它的構(gòu)造函數(shù)干了如下勾當(dāng):

 
 
 
  1. AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor() 
  2.  
  3.     : mId(0), mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0), 
  4.  
  5.     mFlags((AudioSystem::output_flags)0), mDevice(0), mOutput1(0), mOutput2(0) 
  6.  
  7. {} 

//很好,統(tǒng)統(tǒng)都置零了。上面這些東西不用我解釋了吧?命名規(guī)則也可以看出來(lái)。

OK,go on.

[--->mHardwareOutput = mpClientInterface->openOutput()]:

這里調(diào)用的是APS的openOutput,看看去:

 
 
 
  1. [--->AudioPolicyService::openOutput] 
  2.  
  3. audio_io_handle_t AudioPolicyService::openOutput(uint32_t *pDevices, 
  4.  
  5.                                 uint32_t *pSamplingRate, 
  6.  
  7.                                 uint32_t *pFormat, 
  8.  
  9.                                 uint32_t *pChannels, 
  10.  
  11.                                 uint32_t *pLatencyMs, 
  12.  
  13.                                 AudioSystem::output_flags flags) 
  14.  
  15.  
  16. sp af = AudioSystem::get_audio_flinger(); 
  17.  
  18. //娘希匹,搞到AF去了 
  19.  
  20. return af->openOutput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, 
  21.  
  22.  pLatencyMs, flags); 
  23.  
  24.  
  25. [----->AudioFlinger::openOutput] 
  26.  
  27. int AudioFlinger::openOutput(uint32_t *pDevices, 
  28.  
  29.                                 uint32_t *pSamplingRate, 
  30.  
  31.                                 uint32_t *pFormat, 
  32.  
  33.                                 uint32_t *pChannels, 
  34.  
  35.                                 uint32_t *pLatencyMs, 
  36.  
  37.                                 uint32_t flags) 
  38.  
  39.  
  40. //我們思考下傳進(jìn)來(lái)的值吧 
  41.  
  42. //*pDevices=0x2,代表外放 
  43.  
  44. //其他都是0。 嘿嘿,有了值,這不就知道下面該怎么走了嗎? 
  45.  
  46.     status_t status; 
  47.  
  48.     PlaybackThread *thread = NULL; 
  49.  
  50.     mHardwareStatus = AUDIO_HW_OUTPUT_OPEN; 
  51.  
  52.     uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0; 
  53.  
  54.     uint32_t format = pFormat ? *pFormat : 0; 
  55.  
  56.     uint32_t channels = pChannels ? *pChannels : 0; 
  57.  
  58.     uint32_t latency = pLatencyMs ? *pLatencyMs : 0; 
  59.  
  60.   
  61.  
  62.      Mutex::Autolock _l(mLock); 
  63.  
  64. //HAL對(duì)象得到一個(gè)AudioStreamOut,傳進(jìn)去的值會(huì)改嗎? 
  65.  
  66.     AudioStreamOut *output = mAudioHardware->openOutputStream(*pDevices, 
  67.  
  68.                                                              (int *)&format, 
  69.  
  70.                                                              &channels, 
  71.  
  72.                                                              &samplingRate, 
  73.  
  74.                                                              &status); 
  75.  
  76.       mHardwareStatus = AUDIO_HW_IDLE; 
  77.  
  78.   
  79.  
  80. if (output != 0) { 

#p#

//走哪個(gè)分支?我把答案告訴大家吧。

//剛才那個(gè)mAudioHardware->openOutputStream確實(shí)會(huì)更改指針對(duì)應(yīng)的value。

//當(dāng)然,我們說(shuō)了,AF使用的是GENERIC的Audio硬件。大家有興趣可以去看看它的實(shí)現(xiàn)。

//我待會(huì)再貼出它的內(nèi)容。反正到這里。

//那幾個(gè)值變成:format為PCM_16_BIT,channels為2,samplingRate為44100

//這樣的話,那只能走else分支了。

      

 
 
 
  1. if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) || 
  2.  
  3.            (format != AudioSystem::PCM_16_BIT) || 
  4.  
  5.            (channels != AudioSystem::CHANNEL_OUT_STEREO)) { 
  6.  
  7.            thread = new DirectOutputThread(this, output, ++mNextThreadId); 
  8.  
  9.           } else { 

//還記得前兩節(jié)分析的同學(xué),看到這里是不是明白了?恩,原來(lái)

//open一個(gè)Output,就會(huì)在AF中創(chuàng)建一個(gè)混音線程。設(shè)計(jì)得真好。

//想象下,所有設(shè)置為外放的程序,它的輸出都是這個(gè)外放stream混音線程來(lái)工作

//所有設(shè)置為耳機(jī)的程序,它的輸出都是這個(gè)耳機(jī)stream混音線程來(lái)完成。

//為什么對(duì)stream特加強(qiáng)調(diào)呢,沒(méi)看見(jiàn)

//我們調(diào)用的是mAudioHardware->openOutputStream(0x2,,,)嘛。返回的

//是一個(gè)AudioStreamOut,可不是設(shè)備喔。Android把這些個(gè)東西都交給HAL層去實(shí)現(xiàn)了。

//不用自己來(lái)管理系統(tǒng)上有什么耳機(jī),外設(shè),藍(lán)牙真實(shí)設(shè)備之類的東東,它反正用AudioStreamOut來(lái)表示它想要的就可以了。例如Generic的Audio Hal只支持一個(gè)OutputStream。--> only my opinion

           thread = new MixerThread(this, output, ++mNextThreadId);

  }

//好了,又多得了一個(gè)線程,

 
 
 
  1. mPlaybackThreads.add(mNextThreadId, thread); 
  2.  
  3.       if (pSamplingRate) *pSamplingRate = samplingRate; 
  4.  
  5.       if (pFormat) *pFormat = format; 
  6.  
  7.       if (pChannels) *pChannels = channels; 
  8.  
  9.       if (pLatencyMs) *pLatencyMs = thread->latency(); 

//從這里返回的是混音線程的索引。

        return mNextThreadId;

    return 0;//如果沒(méi)創(chuàng)建成功線程,則返回零。

}

好,我們回到AudioManagerBase中。

 
 
 
  1. [--->AudioPolicyManagerBase::AudioPolicyManagerBase] 
  2.  
  3. mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice, 
  4.  
  5.                                     &outputDesc->mSamplingRate, 
  6.  
  7.                                     &outputDesc->mFormat, 
  8.  
  9.                                     &outputDesc->mChannels, 
  10.  
  11.                                     &outputDesc->mLatency, 
  12.  
  13.                                     outputDesc->mFlags); 

//上面實(shí)際就返回一個(gè)線程index。我有點(diǎn)疑惑,難道APS就只這么一個(gè)實(shí)際是線程index的東西就就行了嗎?雖然它把這個(gè)index當(dāng)成hardware的標(biāo)識(shí)了。

  //這個(gè)...估計(jì)是把int和指針加入到一個(gè)map了,方便管理。不看了。

addOutput(mHardwareOutput, outputDesc);

//不知道干嘛,待會(huì)看。

 
 
 
  1. setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true); 
  2.  
  3. [--->setOutputDevice(mHardwareOutput,...)] 

這個(gè)函數(shù),很重要!另外,再傳點(diǎn)技巧。不要老在source insight中后退后退了,直接找到window菜單,里邊列出了最近打開(kāi)的文件,找到我們的AudioManagerBase.cpp,不就行了嗎?

void AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, uint32_t device, bool force, int delayMs)

{

//注意我們的參數(shù):

// output = 1,

//device為AudioSystem::DEVICE_OUT_SPEAKER

// force為true,delayMs用默認(rèn)值0

//map吧?剛才通過(guò)addOutput已經(jīng)加進(jìn)去了

 
 
 
  1. AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 
  2.  
  3.   
  4.  
  5.     if (outputDesc->isDuplicated()) { 
  6.  
  7.         setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); 
  8.  
  9.         setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); 
  10.  
  11.         return; 
  12.  

//還記得addOutput前設(shè)置的device嗎?對(duì)了,為0X3,外放|耳機(jī)

 
 
 
  1. uint32_t prevDevice = (uint32_t)outputDesc->device(); 
  2.  
  3. 現(xiàn)在設(shè)置的是外設(shè), 
  4.  
  5.     if ((device == 0 || device == prevDevice) && !force) { 
  6.  
  7.         return; 
  8.  
  9.     } 
  10.  
  11. //喔,設(shè)置這個(gè)outputDesc為外放 
  12.  
  13.     outputDesc->mDevice = device; 
  14.  
  15. popCount為2,因?yàn)閐evice=0x2=0010 

//另外,我對(duì)下面這個(gè)output== mHardwareOutput尤其感興趣。還記得我們剛才的疑問(wèn)嗎?

// mHardwareOutput實(shí)際上是AF返回的一個(gè)線程索引,那AMB怎么根據(jù)這樣一個(gè)東西來(lái)

//管理所有的線程呢?果然,這里就比較了output是不是等于最初創(chuàng)建的線程索引

//這就表明。雖然只有這么一個(gè)mHardwareOutput,但實(shí)際上還是能夠操作其他output的!

 
 
 
  1.   if (output == mHardwareOutput && AudioSystem::popCount(device) == 2) { 
  2.  
  3.       setStrategyMute(STRATEGY_MEDIA, true, output); 
  4.  
  5. usleep(outputDesc->mLatency*2*1000); 
  6.  
  7.   } 

// 暈,又冒出來(lái)一個(gè)AudioParameter,不過(guò)意思卻很明白

//說(shuō)我們要設(shè)置路由,新的輸出設(shè)備為外放

//等我們以后講由外放切換到耳機(jī),再來(lái)看這個(gè)問(wèn)題。

 
 
 
  1. AudioParameter param = AudioParameter(); 
  2.  
  3.     param.addInt(String8(AudioParameter::keyRouting), (int)device); 
  4.  
  5.     mpClientInterface->setParameters(mHardwareOutput, param.toString(), delayMs); 
  6.  
  7.     // update stream volumes according to new device 
  8.  
  9.     applyStreamVolumes(output, device, delayMs); 

    // if changing from a combined headset + speaker route, unmute media streams

    if (output == mHardwareOutput && AudioSystem::popCount(prevDevice) == 2) {

      //這里說(shuō),把media的音量置為0。以后再說(shuō)。 

setStrategyMute(STRATEGY_MEDIA, false, output, delayMs);

    }

}

好了,返回了。

setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true);

這個(gè)調(diào)研,更新了mHardwareOutput對(duì)應(yīng)的輸出路由設(shè)備,而且還發(fā)了一個(gè)命令給APS,說(shuō)你給我更新對(duì)應(yīng)混音線程的輸出路由設(shè)備。

 
 
 
  1. [--->AudioPolicyManagerBase::AudioPolicyManagerBase] 
  2.  
  3.     .....    
  4.  
  5. addOutput(mHardwareOutput, outputDesc); 
  6.  
  7.         setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, 
  8.  
  9. true); 

  //只剩下最后一個(gè)函數(shù)了

 
 
 
  1. updateDeviceForStrategy(); 
  2.  
  3. [----->updateDeviceForStrategy()] 
  4.  
  5.   void AudioPolicyManagerBase::updateDeviceForStrategy() 
  6.  
  7.  
  8.     for (int i = 0; i < NUM_STRATEGIES; i++) { 
  9.  
  10.         mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false); 
  11.  
  12.     } 
  13.  

暈,又出來(lái)一個(gè)枚舉。我們看看

 
 
 
  1. [---->for (int i = 0; i < NUM_STRATEGIES; i++)] 
  2.  
  3. NUM_STRATEGIES在hardware/libhardware_legacy/include/hardware_legacy/ 
  4.  
  5. AudioPolicyManagerBase.h中定義。 
  6.  
  7. enum routing_strategy { 
  8.  
  9. //好像很好理解 
  10.  
  11.             STRATEGY_MEDIA, 
  12.  
  13.             STRATEGY_PHONE,//通話音嗎? 
  14.  
  15.             STRATEGY_SONIFICATION,//除了其他三個(gè)外的,可以是鈴聲,提醒聲等。 
  16.  
  17.             STRATEGY_DTMF,//好像是撥號(hào)音 
  18.  
  19.             NUM_STRATEGIES 
  20.  
  21.         }; 

這個(gè),反正我在SDK上沒(méi)找到對(duì)應(yīng)說(shuō)明,我們待到以后看看會(huì)不會(huì)柳暗花明呢?

[----->getDeviceForStrategy((routing_strategy)i, false)]

看這個(gè)函數(shù)名的意思是,為各種策略找到它對(duì)應(yīng)的設(shè)備。

uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, bool fromCache)

{

  //  fromCache為false

//放眼望去,這個(gè)函數(shù)好像涉及到很對(duì)策略方面的事情。

//我們大概講解下,至于系統(tǒng)為什么要這么做,問(wèn)Google吧。

 
 
 
  1. uint32_t device = 0; 
  2.  
  3.   
  4.  
  5.     switch (strategy) { 
  6.  
  7.     case STRATEGY_DTMF: 
  8.  
  9.         if (mPhoneState != AudioSystem::MODE_IN_CALL) { 
  10.  
  11.             //如果在打電話過(guò)程中,你再按按鍵,則和MEDIA走一個(gè)設(shè)備 
  12.  
  13.             device = getDeviceForStrategy(STRATEGY_MEDIA, false); 
  14.  
  15.             break; 
  16.  
  17.         } 

        //注意這里沒(méi)有break,所以在其他mode下,DTMF和PHONE用一個(gè)策略

    case STRATEGY_PHONE:

       //還得判斷用戶是不是強(qiáng)制使用了輸出設(shè)備。

 
 
 
  1.   switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { 
  2.  
  3.         case AudioSystem::FORCE_BT_SCO: 
  4.  
  5.             if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) { 
  6.  
  7.                 device = mAvailableOutputDevices & 
  8.  
  9.  AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 
  10.  
  11.                 if (device) break; 
  12.  
  13.             } 
  14.  
  15.             device = mAvailableOutputDevices & 
  16.  
  17. AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 
  18.  
  19.             if (device) break; 
  20.  
  21.             device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO; 
  22.  
  23.             if (device) break; 
  24.  
  25.             // if SCO device is requested but no SCO device is available, fall back to default 
  26.  
  27. // case&n
    當(dāng)前題目:Android深入淺出之Audio第三部分AudioPolicy
    當(dāng)前URL:http://www.5511xx.com/article/dhghjcc.html