记录一下高通音频配置文件mixer_paths.xml初始化过程。参考代码基于Android O。

hardware/qcom/audio/hal/audio_hw.c

struct audio_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = AUDIO_MODULE_API_VERSION_0_1,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = AUDIO_HARDWARE_MODULE_ID,
.name = "QCOM Audio HAL",
.author = "The Linux Foundation",
.methods = &hal_module_methods,
},
}; 对应操作方法
static struct hw_module_methods_t hal_module_methods = {
.open = adev_open,
}; static int adev_open(const hw_module_t *module, const char *name,
hw_device_t **device)
{
......
adev->platform = platform_init(adev); // 平台初始化函数
if (!adev->platform) {
free(adev->snd_dev_ref_cnt);
free(adev);
ALOGE("%s: Failed to init platform data, aborting.", __func__);
*device = NULL;
pthread_mutex_unlock(&adev_init_lock);
pthread_mutex_destroy(&adev->lock);
return -EINVAL;
}
......
}

根据不同的芯片找到对应的文件

hardware/qcom/audio/hal/msm8916/platform.c

void *platform_init(struct audio_device *adev)
{
char value[PROPERTY_VALUE_MAX];
struct platform_data *my_data = NULL;
int snd_card_num = 0;
const char *snd_card_name;
char mixer_xml_path[MAX_MIXER_XML_PATH],ffspEnable[PROPERTY_VALUE_MAX];
const char *mixer_ctl_name = "Set HPX ActiveBe";
struct mixer_ctl *ctl = NULL;
int idx;
int wsaCount =0;
bool is_wsa_combo_supported = false; snd_card_num = audio_extn_utils_get_snd_card_num(); //获取声卡的的编号
if(snd_card_num < 0) {
ALOGE("%s: Unable to find correct sound card", __func__);
return NULL;
} adev->snd_card = snd_card_num;
ALOGD("%s: Opened sound card:%d", __func__, snd_card_num); adev->mixer = mixer_open(snd_card_num);
if (!adev->mixer) {
ALOGE("%s: Unable to open the mixer card: %d", __func__,
snd_card_num);
return NULL;
} snd_card_name = mixer_get_name(adev->mixer);
ALOGD("%s: snd_card_name: %s", __func__, snd_card_name); my_data = calloc(1, sizeof(struct platform_data)); if (!my_data) {
ALOGE("failed to allocate platform data");
return NULL;
} my_data->hw_info = hw_info_init(snd_card_name); //初始化hw_info结构体
if (!my_data->hw_info) {
ALOGE("%s: Failed to init hardware info", __func__);
free(my_data);
return NULL;
} query_platform(snd_card_name, mixer_xml_path); //query_platform,根据设备名称找到xml文件的路径
ALOGD("%s: mixer path file is %s", __func__,
mixer_xml_path);
if (audio_extn_read_xml(adev, snd_card_num, mixer_xml_path,
MIXER_XML_PATH_AUXPCM) == -ENOSYS) {
adev->audio_route = audio_route_init(snd_card_num, // 解析xml文件
mixer_xml_path);
}
if (!adev->audio_route) {
ALOGE("%s: Failed to init audio route controls, aborting.",
__func__);
free(my_data);
mixer_close(adev->mixer);
return NULL;
}
update_codec_type(snd_card_name);
update_interface(snd_card_name);
...... }

query_platform定义如下

static void query_platform(const char *snd_card_name,
char *mixer_xml_path)
{
if (!strncmp(snd_card_name, "msm8x16-snd-card-mtp",
sizeof("msm8x16-snd-card-mtp"))) {
strlcpy(mixer_xml_path, MIXER_XML_PATH_MTP,
sizeof(MIXER_XML_PATH_MTP)); msm_device_to_be_id = msm_device_to_be_id_internal_codec;
msm_be_id_array_len =
sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]); ...... } else if (!strncmp(snd_card_name, "msm8953-snd-card-mtp", // 根据设备名称使用不同的xml文件
sizeof("msm8953-snd-card-mtp"))) {
strlcpy(mixer_xml_path, MIXER_XML_PATH_MTP,
sizeof(MIXER_XML_PATH_MTP));
msm_device_to_be_id = msm_device_to_be_id_internal_codec;
msm_be_id_array_len =
sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]); ......
}

设备名称通过可以在adb中查看cat /proc/asound/cards,如下:

Tony:/ # cat /proc/asound/cards
cat /proc/asound/cards
0 [msm8953sndcardm]: msm8953-snd-car - msm8953-snd-card-mtp
msm8953-snd-card-mtp

因此可以知道选取的文件

#define MIXER_XML_PATH_MTP "/etc/mixer_paths_mtp.xml"

xml文件解析函数位于system/media/audio_route/audio_route.c

struct audio_route *audio_route_init(unsigned int card, const char *xml_path)
{
struct config_parse_state state;
XML_Parser parser;
FILE *file;
int bytes_read;
void *buf;
struct audio_route *ar; ar = calloc(1, sizeof(struct audio_route));
if (!ar)
goto err_calloc; ar->mixer = mixer_open(card);
if (!ar->mixer) {
ALOGE("Unable to open the mixer, aborting.");
goto err_mixer_open;
} ar->mixer_path = NULL;
ar->mixer_path_size = 0;
ar->num_mixer_paths = 0; /* allocate space for and read current mixer settings */
if (alloc_mixer_state(ar) < 0)
goto err_mixer_state; /* use the default XML path if none is provided */
if (xml_path == NULL)
xml_path = MIXER_XML_PATH; file = fopen(xml_path, "r"); if (!file) {
ALOGE("Failed to open %s: %s", xml_path, strerror(errno));
parser = XML_ParserCreate(NULL);
if (!parser) {
ALOGE("Failed to create XML parser");
goto err_parser_create;
} memset(&state, 0, sizeof(state));
state.ar = ar;
XML_SetUserData(parser, &state);
XML_SetElementHandler(parser, start_tag, end_tag); for (;;) {
buf = XML_GetBuffer(parser, BUF_SIZE);
if (buf == NULL)
goto err_parse; bytes_read = fread(buf, 1, BUF_SIZE, file);
if (bytes_read < 0)
goto err_parse; if (XML_ParseBuffer(parser, bytes_read,
bytes_read == 0) == XML_STATUS_ERROR) {
ALOGE("Error in mixer xml (%s)", MIXER_XML_PATH);
goto err_parse;
} if (bytes_read == 0)
break;
} /* apply the initial mixer values, and save them so we can reset the
mixer to the original values */
audio_route_update_mixer(ar);
save_mixer_state(ar); XML_ParserFree(parser);
fclose(file);
return ar;
......
}

xml位于源码位置hardware/qcom/audio/configs/msm8953/

xml文件存放的路径更改了,android O的路径位于/vendor/etc/下面,android N位于/system/etc/

mixer_paths_mtp.xml分析,可参考http://bbs.gfan.com/android-7626545-1-1.html

文件的开头会写一些默认的参数,也就是里面的内容,就是默认的参数。

然后不同的设备,也就是不同的标签里面的内容,标签中的值表示不同的设备。

<?xml version="1.0" encoding="ISO-8859-1"?>
<mixer>
<!-- These are the initial mixer settings -->
<ctl name="Voice Rx Device Mute" id="0" value="0" />
<ctl name="Voice Rx Device Mute" id="1" value="-1" />
<ctl name="Voice Rx Device Mute" id="2" value="20" />
<ctl name="Voice Tx Mute" id="0" value="0" />
<ctl name="Voice Tx Mute" id="1" value="-1" />
<ctl name="Voice Tx Mute" id="2" value="500" />
<ctl name="Voice Rx Gain" id="0" value="0" />
<ctl name="Voice Rx Gain" id="1" value="-1" />
<ctl name="Voice Rx Gain" id="2" value="20" />
......
<path name="handset"> <!-- 电话听筒 -->
<ctl name="RX1 MIX1 INP1" value="RX1" />
<ctl name="RDAC2 MUX" value="RX1" />
<ctl name="RX1 Digital Volume" value="84" />
<ctl name="EAR PA Gain" value="POS_6_DB" />
<ctl name="EAR_S" value="Switch" />
</path> <path name="handset-mic">
<path name="adc1" />
<ctl name="IIR1 INP1 MUX" value="DEC1" />
</path> <path name="headphones"> <!-- 耳机 -->
<ctl name="MI2S_RX Channels" value="Two" />
<ctl name="RX1 MIX1 INP1" value="RX1" />
<ctl name="RX2 MIX1 INP1" value="RX2" />
<ctl name="RX HPH Mode" value="HD2" />
<ctl name="COMP0 RX1" value="1" />
<ctl name="COMP0 RX2" value="1" />
<ctl name="RDAC2 MUX" value="RX2" />
<ctl name="HPHL" value="Switch" />
<ctl name="HPHR" value="Switch" />
</path> <path name="headset-mic">
<path name="adc2" />
<ctl name="ADC2 MUX" value="INP2" />
<ctl name="IIR1 INP1 MUX" value="DEC1" />
</path>
......

Tony Liu

2018-1-29

高通 mixer_paths.xml 音频配置文件 初始化过程的更多相关文章

  1. javaweb的web.xml配置说明,初始化过程

    [重点]初始化过程可知容器对于web.xml的加载过程是context-param >> listener  >> fileter  >> servlet 首先了解 ...

  2. go源码分析(一) 通过调试看go程序初始化过程

    参考资料:Go 1.5 源码剖析 (书签版).pdf 编写go语言test.go package main import ( "fmt" ) func main(){ fmt.Pr ...

  3. linux驱动由浅入深系列:PBL-SBL1-(bootloader)LK-Android启动过程详解之一(高通MSM8953启动实例)

    转自:http://blog.csdn.net/radianceblau/article/details/73229005 http://www.aiuxian.com/article/p-14142 ...

  4. web.xml文件初始化过程

    在使用各种框架后,有时会发现不了了错误处在哪里,了解Servlet的初始化过程(也可以说是web.xml的初始化吧),也许对你对于框架的理解与报错的原因理解会有帮助 context-param > ...

  5. 高通AR和友盟SDK的AndroidManifest.xml合并

    高通AR和友盟SDK的AndroidManifest.xml合并 因为高通的AR在android中一开始就要启动,所有主Activity要设置为高通的Activity,即android:name=&q ...

  6. Linux加载DTS设备节点的过程(以高通8974平台为例)

    DTS是Device Tree Source的缩写,用来描述设备的硬件细节.在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码, ...

  7. 高通平台的bootloader过程【转】

    ====================基本知识=======================LK是(L)ittle (K)ernel的缩写.高通平台android普遍采用LK作为其bootloade ...

  8. 高通移植mipi LCD的过程LK代码

    lk部分:(实现LCD兼容) 1. 函数定位 aboot_init()来到target_display_init(): 这就是高通原生lk LCD 兼容的关键所在.至于你需要兼容多少LCD 就在whi ...

  9. 高通音频 媒体喇叭增益隐藏参数(一个QACT无法修改的参数)

    源文件位置:modem_proc\multimedia\audio\avs\src\sndhwg2.c sndhw_init()函数,2520行左右:pm_set_speaker_gain(PM_SP ...

随机推荐

  1. 网摘Android调用WebService

    这边特别注意调用的.net WCF 接口的绑定方式.以前一直用的wxHttpbinding,一直连不上.改成BasicHTTPbinding就能连上了 上篇文章已经对Web Service及其相关知识 ...

  2. 转webstorm的快捷键

    止 静 java android 转-webstorm快捷键 默认配置-Eclipse的常用快捷键对照表 查找/代替 Webstorm快捷键 Eclipse快捷键 说明 ctrl+shift+N ct ...

  3. HTTP Basic Authentication认证

    http://smalltalllong.iteye.com/blog/912046 ******************************************** 什么是HTTP Basi ...

  4. Zabbix之Python发送邮件

    前言:继前篇zabbix邮件乱码问题解决,转码后,问题是解决了,但是又发现问题,有时候告警邮件没有邮件内容,只有标题,一直没找出原因,所以就换了Python脚本发送邮件,代码如下. 使用前当然是要先安 ...

  5. java 多线程 24 : 线程组

    线程组 可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的组织结构有点类似于树的形式,如图所示: 线程组的作用是:可以批量管理线程或线程组对象,有效地对线 ...

  6. model number

    // test.cpp : Defines the entry point for the console application. // #include "stdafx.h" ...

  7. 7. 集成学习(Ensemble Learning)Stacking

    1. 集成学习(Ensemble Learning)原理 2. 集成学习(Ensemble Learning)Bagging 3. 集成学习(Ensemble Learning)随机森林(Random ...

  8. 4. 支持向量机(SVM)原理

    1. 感知机原理(Perceptron) 2. 感知机(Perceptron)基本形式和对偶形式实现 3. 支持向量机(SVM)拉格朗日对偶性(KKT) 4. 支持向量机(SVM)原理 5. 支持向量 ...

  9. [转]BigDecimal不整除异常

    通过BigDecimal的divide方法进行除法时当不整除,出现无限循环小数时,就会抛异常的 异   常 :java.lang.ArithmeticException: Non-terminatin ...

  10. mac OS X中升级php5.5至php5.6 or php7

    在做php项目中,提示“Warning. PHP 5.6 or newer is required. Please, upgrade your local PHP installation.” 通过p ...