免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5897 | 回复: 4
打印 上一主题 下一主题

Android如何找到正确的ALSA底层kcontrol接口? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-01-19 16:01 |只看该作者 |倒序浏览
可以认为上层应用是通过名称标识name来遍历底层的snd_kcontrol链表,从而找到相匹配的kcontrol。见snd_ctl_find_id函数
  1. /**
  2. * snd_ctl_find_id - find the control instance with the given id
  3. * @card: the card instance
  4. * @id: the id to search
  5. *
  6. * Finds the control instance with the given id from the card.
  7. *
  8. * Returns the pointer of the instance if found, or NULL if not.
  9. *
  10. * The caller must down card->controls_rwsem before calling this function
  11. * (if the race condition can happen).
  12. */
  13. struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
  14.                                      struct snd_ctl_elem_id *id)
  15. {
  16.         struct snd_kcontrol *kctl;

  17.         if (snd_BUG_ON(!card || !id))
  18.                 return NULL;
  19.         if (id->numid != 0)
  20.                 return snd_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.                 return kctl;
  35.         }
  36.         return NULL;
  37. }
复制代码
今天跟踪Android音频系统时,发现无论如何都找不到Android与snd_kcontrol的联结点,无论是name还是numid(alsa_amixer controls打印出来的那个numid,即是内核层snd_kcontrol链表元素的index号)都找不到相关关键字。但是它确实可以进行调节音量等控制。后来我修改内核的Codec驱动,将音量控制的kcontrol.name换成其他字符串,重新编译,Android还是可以进行音量控制。

看起来有点像是通过numid来控制的,《Android音频HAL移植》一文有提到:“设备的切换就需要和驱动联调。例如,目前earpiece的id为10,那么就可以通过ALSA的amixer设置earpiece的开和关,以及大小。而id的值就需要做驱动的同事提供。”但是还不能就此肯定。目前也没有找到保存这些值的脚本文件。

请问有大侠对android音频系统有研究吗?

论坛徽章:
0
2 [报告]
发表于 2011-01-19 16:07 |只看该作者
研究这个东西为了以后的equalizer,android2.3已有eq接口了。可惜目前我们还在2.2上搞,但总会用到的。

论坛徽章:
0
3 [报告]
发表于 2011-01-19 16:58 |只看该作者
我疯掉了。
我在最大音量和最小音量时打印出codec所有寄存器的值,发现playback volume控制器的值没有改变。可是音量的确是变化的,那么为毛寄存器的值不会改变?
会不会它根本不是通过硬件寄存器来控制的啊?这样的话,倒是很多问题都能说得通。

论坛徽章:
0
4 [报告]
发表于 2011-01-19 18:29 |只看该作者
可以结贴了,真是android软件实现的。。。与技术总管吃饭的时候,聊到这个的时候,确认了这个。

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;
}

论坛徽章:
0
5 [报告]
发表于 2011-02-24 13:08 |只看该作者
记录下~~~~~~~~~~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP