昨天分析了一把snd_kcontrol,可以認為上層應用的確是通過名稱標識name來遍曆底層的snd_kcontrol鏈表,從而找到相匹配的kcontrol。見snd_ctl_find_id函數
/** * snd_ctl_find_id - find the control instance with the given id * @card: the card instance * @id: the id to search * * Finds the control instance with the given id from the card. * * Returns the pointer of the instance if found, or NULL if not. * * The caller must down card->controls_rwsem before calling this function * (if the race condition can happen). */struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, struct snd_ctl_elem_id *id){struct snd_kcontrol *kctl;if (snd_BUG_ON(!card || !id))return NULL;if (id->numid != 0)return snd_ctl_find_numid(card, id->numid);list_for_each_entry(kctl, &card->controls, list) {if (kctl->id.iface != id->iface)continue;if (kctl->id.device != id->device)continue;if (kctl->id.subdevice != id->subdevice)continue;if (strncmp(kctl->id.name, id->name, sizeof(kctl->id.name)))continue;if (kctl->id.index > id->index)continue;if (kctl->id.index + kctl->count <= id->index)continue;return kctl;}return NULL;}
今天繼續跟蹤Android音頻系統時,發現無論如何都找不到Android與snd_kcontrol的連接點,無論是name還是numid(alsa_amixer controls列印出來的那個numid,即是核心層snd_kcontrol鏈表元素的numid)都找不到相關關鍵字。但是它確實可以進行調節音量等控制。後來我修改核心的Codec驅動,將音量控制的kcontrol.name換成其他字串,重新編譯,Android還是可以進行音量控制。
看起來有點像是通過numid來控制的,《Android音頻HAL移植》一文有提到:“裝置的切換就需要和驅動聯調。例如,目前earpiece的id為10,那麼就可以通過ALSA的amixer設定earpiece的開和關,以及大小。而id的值就需要做驅動的同事提供。”但是還不能就此肯定。目前也沒有找到儲存這些值的指令檔。
繼續以上問題,我在調節音量時,列印Codec寄存器的值,發現volume寄存器的值根本不會發生變化,但是音量確確實實是變化的。那時就在懷疑我們Android的音量大小不是通過硬體來實現的,而是有自身的sw mixer機制。晚上和Vic一起吃飯時,聊起這個,肯定了我的猜測。
今天繼續跟蹤Android音頻系統時,發現無論如何都找不到Android與snd_kcontrol的連接點,無論是name還是numid(alsa_amixer controls列印出來的那個numid,即是核心層snd_kcontrol鏈表元素的numid)都找不到相關關鍵字。但是它確實可以進行調節音量等控制。後來我修改核心的Codec驅動,將音量控制的kcontrol.name換成其他字串,重新編譯,Android還是可以進行音量控制。
看起來有點像是通過numid來控制的,《Android音頻HAL移植》一文有提到:“裝置的切換就需要和驅動聯調。例如,目前earpiece的id為10,那麼就可以通過ALSA的amixer設定earpiece的開和關,以及大小。而id的值就需要做驅動的同事提供。”但是還不能就此肯定。目前也沒有找到儲存這些值的指令檔。
繼續以上問題,我在調節音量時,列印Codec寄存器的值,發現volume寄存器的值根本不會發生變化,但是音量確確實實是變化的。那時就在懷疑我們Android的音量大小不是通過硬體來實現的,而是有自身的sw mixer機制。晚上和Vic一起吃飯時,聊起這個,肯定了我的猜測。
今天繼續跟蹤Android音頻系統時,發現無論如何都找不到Android與snd_kcontrol的連接點,無論是name還是numid(alsa_amixer controls列印出來的那個numid,即是核心層snd_kcontrol鏈表元素的numid)都找不到相關關鍵字。但是它確實可以進行調節音量等控制。後來我修改核心的Codec驅動,將音量控制的kcontrol.name換成其他字串,重新編譯,Android還是可以進行音量控制。
看起來有點像是通過numid來控制的,《Android音頻HAL移植》一文有提到:“裝置的切換就需要和驅動聯調。例如,目前earpiece的id為10,那麼就可以通過ALSA的amixer設定earpiece的開和關,以及大小。而id的值就需要做驅動的同事提供。”但是還不能就此肯定。目前也沒有找到儲存這些值的指令檔。
繼續以上問題,我在調節音量時,列印Codec寄存器的值,發現volume寄存器的值根本不會發生變化,但是音量確確實實是變化的。那時就在懷疑我們Android的音量大小不是通過硬體來實現的,而是有自身的sw mixer機制。晚上和Vic一起吃飯時,聊起這個,肯定了我的猜測。
status_t AudioFlinger::setMasterVolume(float value){ // check calling permissions if (!settingsAllowed()) { return PERMISSION_DENIED; } // when hw supports master volume, don't scale in sw mixer AutoMutex lock(mHardwareLock); mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME; if (mAudioHardware->setMasterVolume(value) == NO_ERROR) { value = 1.0f; } mHardwareStatus = AUDIO_HW_IDLE; mMasterVolume = value; for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) mPlaybackThreads.valueAt(i)->setMasterVolume(value); return NO_ERROR;}
今天繼續跟蹤Android音頻系統時,發現無論如何都找不到Android與snd_kcontrol的連接點,無論是name還是numid(alsa_amixer controls列印出來的那個numid,即是核心層snd_kcontrol鏈表元素的numid)都找不到相關關鍵字。但是它確實可以進行調節音量等控制。後來我修改核心的Codec驅動,將音量控制的kcontrol.name換成其他字串,重新編譯,Android還是可以進行音量控制。
看起來有點像是通過numid來控制的,《Android音頻HAL移植》一文有提到:“裝置的切換就需要和驅動聯調。例如,目前earpiece的id為10,那麼就可以通過ALSA的amixer設定earpiece的開和關,以及大小。而id的值就需要做驅動的同事提供。”但是還不能就此肯定。目前也沒有找到儲存這些值的指令檔。
繼續以上問題,我在調節音量時,列印Codec寄存器的值,發現volume寄存器的值根本不會發生變化,但是音量確確實實是變化的。那時就在懷疑我們Android的音量大小不是通過硬體來實現的,而是有自身的sw mixer機制。晚上和Vic一起吃飯時,聊起這個,肯定了我的猜測。
今天繼續跟蹤Android音頻系統時,發現無論如何都找不到Android與snd_kcontrol的連接點,無論是name還是numid(alsa_amixer controls列印出來的那個numid,即是核心層snd_kcontrol鏈表元素的numid)都找不到相關關鍵字。但是它確實可以進行調節音量等控制。後來我修改核心的Codec驅動,將音量控制的kcontrol.name換成其他字串,重新編譯,Android還是可以進行音量控制。
看起來有點像是通過numid來控制的,《Android音頻HAL移植》一文有提到:“裝置的切換就需要和驅動聯調。例如,目前earpiece的id為10,那麼就可以通過ALSA的amixer設定earpiece的開和關,以及大小。而id的值就需要做驅動的同事提供。”但是還不能就此肯定。目前也沒有找到儲存這些值的指令檔。
繼續以上問題,我在調節音量時,列印Codec寄存器的值,發現volume寄存器的值根本不會發生變化,但是音量確確實實是變化的。那時就在懷疑我們Android的音量大小不是通過硬體來實現的,而是有自身的sw mixer機制。晚上和Vic一起吃飯時,聊起這個,肯定了我的猜測。
應該是Android允許開發人員在HAL層實現hw mixer,當AudioFlinger探測到存在hw mixer時,則調用mAudioHardware->setMasterVolume()對volume寄存器進行設定,也不會對volume值進行scale。至於sw mixer如何使用scale值的,我沒有深入探究。
以後實現hw mixer看看(反正到時也要實現EQ)效果,現在這個音量設定不是線性,用硬體控制應該更好一點。
PS:標題就不用管它了,預設下Android根本不去找底層的kcontrol介面,而是使用自身的sw mixer。
今天繼續跟蹤Android音頻系統時,發現無論如何都找不到Android與snd_kcontrol的連接點,無論是name還是numid(alsa_amixer controls列印出來的那個numid,即是核心層snd_kcontrol鏈表元素的numid)都找不到相關關鍵字。但是它確實可以進行調節音量等控制。後來我修改核心的Codec驅動,將音量控制的kcontrol.name換成其他字串,重新編譯,Android還是可以進行音量控制。
看起來有點像是通過numid來控制的,《Android音頻HAL移植》一文有提到:“裝置的切換就需要和驅動聯調。例如,目前earpiece的id為10,那麼就可以通過ALSA的amixer設定earpiece的開和關,以及大小。而id的值就需要做驅動的同事提供。”但是還不能就此肯定。目前也沒有找到儲存這些值的指令檔。
繼續以上問題,我在調節音量時,列印Codec寄存器的值,發現volume寄存器的值根本不會發生變化,但是音量確確實實是變化的。那時就在懷疑我們Android的音量大小不是通過硬體來實現的,而是有自身的sw mixer機制。晚上和Vic一起吃飯時,聊起這個,肯定了我的猜測。
今天繼續跟蹤Android音頻系統時,發現無論如何都找不到Android與snd_kcontrol的連接點,無論是name還是numid(alsa_amixer controls列印出來的那個numid,即是核心層snd_kcontrol鏈表元素的numid)都找不到相關關鍵字。但是它確實可以進行調節音量等控制。後來我修改核心的Codec驅動,將音量控制的kcontrol.name換成其他字串,重新編譯,Android還是可以進行音量控制。
看起來有點像是通過numid來控制的,《Android音頻HAL移植》一文有提到:“裝置的切換就需要和驅動聯調。例如,目前earpiece的id為10,那麼就可以通過ALSA的amixer設定earpiece的開和關,以及大小。而id的值就需要做驅動的同事提供。”但是還不能就此肯定。目前也沒有找到儲存這些值的指令檔。
繼續以上問題,我在調節音量時,列印Codec寄存器的值,發現volume寄存器的值根本不會發生變化,但是音量確確實實是變化的。那時就在懷疑我們Android的音量大小不是通過硬體來實現的,而是有自身的sw mixer機制。晚上和Vic一起吃飯時,聊起這個,肯定了我的猜測。