转:http://blog.csdn.net/sepnic/article/details/6152792

昨天分析了一把snd_kcontrol,可以认为上层应用的确是通过名称标识name来遍历底层的snd_kcontrol链表,从而找到相匹配的kcontrol。见snd_ctl_find_id函数

[cpp] view plain copy
  1. /**
  2. *snd_ctl_find_id-findthecontrolinstancewiththegivenid
  3. *@card:thecardinstance
  4. *@id:theidtosearch
  5. *
  6. *Findsthecontrolinstancewiththegivenidfromthecard.
  7. *
  8. *Returnsthepointeroftheinstanceiffound,orNULLifnot.
  9. *
  10. *Thecallermustdowncard->controls_rwsembeforecallingthisfunction
  11. *(iftheraceconditioncanhappen).
  12. */
  13. structsnd_kcontrol*snd_ctl_find_id(structsnd_card*card,
  14. structsnd_ctl_elem_id*id)
  15. {
  16. structsnd_kcontrol*kctl;
  17. if(snd_BUG_ON(!card||!id))
  18. returnNULL;
  19. if(id->numid!=0)
  20. returnsnd_ctl_find_numid(card,id->numid);
  21. list_for_each_entry(kctl,&card->controls,list){
  22. if(kctl->id.iface!=id->iface)
  23. continue;
  24. if(kctl->id.device!=id->device)
  25. continue;
  26. if(kctl->id.subdevice!=id->subdevice)
  27. continue;
  28. if(strncmp(kctl->id.name,id->name,sizeof(kctl->id.name)))
  29. continue;
  30. if(kctl->id.index>id->index)
  31. continue;
  32. if(kctl->id.index+kctl->count<=id->index)
  33. continue;
  34. returnkctl;
  35. }
  36. returnNULL;
  37. }


今天继续跟踪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一起吃饭时,聊起这个,肯定了我的猜测。

[cpp] view plain copy
  1. status_tAudioFlinger::setMasterVolume(floatvalue)
  2. {
  3. //checkcallingpermissions
  4. if(!settingsAllowed()){
  5. returnPERMISSION_DENIED;
  6. }
  7. //whenhwsupportsmastervolume,don'tscaleinswmixer
  8. AutoMutexlock(mHardwareLock);
  9. mHardwareStatus=AUDIO_HW_SET_MASTER_VOLUME;
  10. if(mAudioHardware->setMasterVolume(value)==NO_ERROR){
  11. value=1.0f;
  12. }
  13. mHardwareStatus=AUDIO_HW_IDLE;
  14. mMasterVolume=value;
  15. for(uint32_ti=0;i<mPlaybackThreads.size();i++)
  16. mPlaybackThreads.valueAt(i)->setMasterVolume(value);
  17. returnNO_ERROR;
  18. }
应该是Android允许开发者在HAL层实现hw mixer,当AudioFlinger探测到存在hw mixer时,则调用mAudioHardware->setMasterVolume()对volume寄存器进行设置,也不会对volume值进行scale。至于sw mixer如何使用scale值的,我没有深入探究。

以后实现hw mixer看看(反正到时也要实现EQ)效果,现在这个音量设置不是线性的,用硬件控制应该更好一点。


PS:标题就不用管它了,默认下Android根本不去找底层的kcontrol接口,而是使用自身的sw mixer。

更多相关文章

  1. Robolectric进行Android单元测试
  2. ubuntu10.04 android编译问题
  3. android led_misc驱动 + 测试应用程序(ndk-build)
  4. Android(安卓)Camera Architecture
  5. Android培训班(103)内核入口汇编3
  6. 【Android话题-2.5系统服务】ServiceManager启动和工作原理是怎
  7. Android(安卓)Q WiFi Enable
  8. Farsight(华清远见) s5pc100-a(A8) 开发板Android驱动开发环境搭建
  9. 非常好看的android音量旋钮

随机推荐

  1. 浅谈android的selector,背景选择器
  2. Android(安卓)Manifest - permission
  3. JNI基础实验一:调用.so文件--友善之臂Tiny
  4. Android多屏幕适配
  5. Android(安卓)studio assets error:前言中
  6. android 4中新增的日历处理相关API
  7. Ubuntu下android源码下载
  8. Android仿今日头条首页的顶部标签栏和底
  9. Android(安卓)关于动画设置问题。
  10. Android(安卓)说说亮屏锁和键盘锁