高通 mixer_paths.xml 音频配置文件 初始化过程
记录一下高通音频配置文件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 音频配置文件 初始化过程的更多相关文章
- javaweb的web.xml配置说明,初始化过程
[重点]初始化过程可知容器对于web.xml的加载过程是context-param >> listener >> fileter >> servlet 首先了解 ...
- go源码分析(一) 通过调试看go程序初始化过程
参考资料:Go 1.5 源码剖析 (书签版).pdf 编写go语言test.go package main import ( "fmt" ) func main(){ fmt.Pr ...
- linux驱动由浅入深系列:PBL-SBL1-(bootloader)LK-Android启动过程详解之一(高通MSM8953启动实例)
转自:http://blog.csdn.net/radianceblau/article/details/73229005 http://www.aiuxian.com/article/p-14142 ...
- web.xml文件初始化过程
在使用各种框架后,有时会发现不了了错误处在哪里,了解Servlet的初始化过程(也可以说是web.xml的初始化吧),也许对你对于框架的理解与报错的原因理解会有帮助 context-param > ...
- 高通AR和友盟SDK的AndroidManifest.xml合并
高通AR和友盟SDK的AndroidManifest.xml合并 因为高通的AR在android中一开始就要启动,所有主Activity要设置为高通的Activity,即android:name=&q ...
- Linux加载DTS设备节点的过程(以高通8974平台为例)
DTS是Device Tree Source的缩写,用来描述设备的硬件细节.在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码, ...
- 高通平台的bootloader过程【转】
====================基本知识=======================LK是(L)ittle (K)ernel的缩写.高通平台android普遍采用LK作为其bootloade ...
- 高通移植mipi LCD的过程LK代码
lk部分:(实现LCD兼容) 1. 函数定位 aboot_init()来到target_display_init(): 这就是高通原生lk LCD 兼容的关键所在.至于你需要兼容多少LCD 就在whi ...
- 高通音频 媒体喇叭增益隐藏参数(一个QACT无法修改的参数)
源文件位置:modem_proc\multimedia\audio\avs\src\sndhwg2.c sndhw_init()函数,2520行左右:pm_set_speaker_gain(PM_SP ...
随机推荐
- Session的clear方法和flush方法
Session Clear()与 Flush() 解释 1.Clear 方法 无论是Load 还是 Get 都会首先查找缓存(一级缓存) 如果没有,才会去数据库查找,调用Clear() 方法,可以强 ...
- angular学习笔记(三十)-指令(2)-restrice,replace,template
本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: ...
- 【转】Unity3D中脚本的执行顺序和编译顺序
支持原文,原文请戳: Unity3D中脚本的执行顺序和编译顺序 在Unity中可以同时创建很多脚本,并且可以分别绑定到不同的游戏对象上,它们各自都在自己的生命周期中运行.与脚本有关的也就是编译和执行啦 ...
- pip升级Python程序包
列出当前安装的包: pip list 列出可升级的包: pip list --outdate 升级一个包: pip install --upgrade requests // mac,linux,un ...
- spring IOC 模拟实现
IOC即inverse of control 控制反转 以前对象之间的引用是通过new来调用实现,有了Spring IOC,我们可以把对象之间的引用交给他来管理,这样就把控制权交给了Spring,所以 ...
- ajaxfileupload.js ajax上传文件(含application/json)
jQuery.extend({ createUploadIframe: function(id, uri) { //create frame var frameId = 'jUploadFrame' ...
- pandas的学习总结
pandas的学习总结 作者:csj更新时间:2017.12.31 email:59888745@qq.com 说明:因内容较多,会不断更新 xxx学习总结: 回主目录:2017 年学习记录和总结 1 ...
- [转]bootstrap table本地数据使用方法
原文地址:http://www.giserdqy.com/language/h5/bootstrap/1136 data对应columns进行组合 var columns = [ { field: ' ...
- MySQL——SQL Mode详解
简介 MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式.这样,应用程序就能对服务器操作进行量身定制以满足自己的需求.这类模式定义了MySQL应支持的SQL语法 ...
- TP v5中Request取值方式变化
到目前为止的5.0.7版本中,route里相关参数不会再压入$_GET与$_REQUEST变量中,比如 index.php/user/blog/id/123 里我们想用 $_GET['id']是取不到 ...