高通 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 ...
随机推荐
- python-布尔值的加法运算
在python中,可以对布尔值进行加减法运算. True会被看做 1 , False会被看做 0 : a = True b = False
- Android 编程下将 Bitmap 转为 InputStream
某些情况下会用到这种非主流的转换方式,最近项目中用到,记录下. ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compres ...
- delphi 学习笔记的例子
由于360改变了共享策略,导致之前的共享连接不能使用 重新共享了下. http://yunpan.cn/cgS2DBRT572jy (提取码:1eda)
- 【C/C++】嵌入式程序员应该知道的0X10个C语言问题
一.预处理器(Preprocessor) 1 . 用预处理指令#define 声明一个常数,用以表明 1 年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 6 ...
- vs2015配置OpenGL开发环境
先吐槽下,不知道微软怎么整的,从win7开始,OpenGL的头文件更改到windows SDK中,不安装就不能用. 更搞笑的是,在win10下,vs2015安装还报win sdk安装失败,这典型的自己 ...
- TNS-12518,TNS-12536,TNS-00506,Linux Error: 11: Resource temporarily unavailable
TNS-12518: TNS:listener could not hand off client connection TNS-12536: TNS:operation would block T ...
- javascript检测浏览器的缩放状态实现代码 是指浏览器网页内容的百分比缩放(按Ctrl和+号键或者-号键的缩放)
这里所说的缩放不是指浏览器大小的缩放,而是指浏览器网页内容的百分比缩放(按Ctrl和+号键或者-号键的缩放).检测这种缩放有很种方法,QQ空间都通过flash来检测浏览器是否处于缩放.这里提供java ...
- 使用jQuery清空file文件域的解决方案
使用jQuery清空file文件域的解决方案 var file = $("#file") file.after(file.clone().val("")); f ...
- spring 过滤器
Spring的web包中中有很多过滤器,这些过滤器位于org.springframework.web.filter并且理所当然地实现了javax.servlet.Filter,不过实现的方式有以下几类 ...
- VS2013代码调试:[7]如何避免调试时加载符号
调试的时候不小心点了个东西,然后就花很长时间加在各种dll 解决办法: 1.点 调试2.然后 选项和设置3.右边勾上 启用源服务器支持4.左边点 符号5.把微软符号服务器勾6.运行的时候等一下 莫慌! ...