Msm8960(APQ8064)平台的MSM-AOSP-kitkat编译适配(6):音频
这一篇是全系列文章的重点,故笔者会多啰嗦一些原理,多问几个为什么,请读者见谅。
笔者以android 4.4.2_r1 KOT49H为例的msm-aosp来适配,此文章则需要cm的代码来辅助理解音频的配置
请读者自行下载cm的源代码,最好与自己下载的msm-aosp相近。
例如与笔者这个相近的就是cm11-m4~m7,那么笔者就下载了cm11-m7 KVT49L的代码来参考。
本文用到的仅仅是源码目录下的hardware目录,所以笔者也单独提供了这个目录的压缩文档,以方便读者实践:
http://download.csdn.net/detail/benjaminwan/8452249
一、对比cm与msm-aosp的hardware/qcom目录
记得对比选项里要钩基础规则对比
左边为cm的hardware,右边边为msm-aosp的hardware
首先请读者思考一个问题:
分别把左边的audio与右边的audio文件夹对比,以及左边的audio-caf与右边的audio文件夹对比,这2种情况下,左边哪个文件夹与右边代码最相似。
当然读者会发现左边的audio-caf代码与右边的audio最为相似
如果读者也同步了google-aosp的代码,就会发现cm的audio文件夹与google-aosp的audio文件夹最相似。
从这里我们可以总结得出:cm实际上集成了google以及高通,二者的audio代码
那么就有了第二个问题,cm如何通过配置来选择使用哪种音频代码?
二、对比audio目录
接下来就把cm的qcom/audio-caf与msm-aosp的qcom/audio目录对比
以下文章的内容都默认以cm的audio-caf来讲解了
对比audio/Android.mk
首先可以看出cm比aosp多了这个语句
ifeq ($(TARGET_QCOM_AUDIO_VARIANT),caf)
这个语句作用就是cm用来选择是audio还是audio-caf的
解释一下:如果在BoardConifg.mk里有TARGET_QCOM_AUDIO_VARIANT := caf
那么就选择audio-caf文件夹来编译,相反,如果不配置此项,则默认使用audio文件夹
分析完左边的cm,再来研究右边的msm-aosp
cm11多出来的是一些其它平台的代码,msm8660,msm8610之类的
接下来只看红框中的共通项
ifeq ($(BOARD_USES_LEGACY_ALSA_AUDIO),true)
include $(MY_LOCAL_PATH)/legacy/Android.mk
else
include $(MY_LOCAL_PATH)/hal/Android.mk
endif
这是一个选择语句,那么到底该选择legacy文件夹或者是hal文件夹呢?
接下来要讲一个小知识,音频hw实际上分为2种,如上看到的legacy以及hal
官方rom的话,msm8960平台使用legacy,而msm8974平台使用hal
来讲讲这2种hw驱动在官方rom里可以看到什么区别
legacy驱动,需要在etc里有个snd_soc_msm文件夹,里面放音频配置文件
而hal驱动,则会在etc下有个mixer_patchs.xml
而且legacy的系统lib下没有libaudioroute.so,相反hal驱动则有
举个例子,泛泰A910,msm8974平台
msm8960平台的例子,请读者自己打开官方rom查看一下便知。
接下来第二个提示要点,对比cm与msm-aosp的hal文件夹,可以发现msm-aosp的hal文件夹缺了许多代码并感觉残缺不全,对,因为我们当前同步的msm-aosp代码仅针对msm8960平台,所以实际上hal文件夹代码是缺失的。
如果读者后续也同步了msm8974平台的msm-aosp,那么对比一下就知道怎么回事了。
回答前面提到的问题,从官方rom得到的提示以及对比cm的hal文件夹,我们应该选择legacy文件夹来编译
所以必须在BoardConfig.mk里添加BOARD_USES_LEGACY_ALSA_AUDIO := true
小知识:因为cm集成了全部的音频代码(包括google、高通各个平台),所以编译cm时,即使msm8960平台也可以选择hal来编译。
三、对比legacy文件夹
cm还集成了msm7x30以及msm8660平台的代码,这2个可以不管
只看右边红框的共通项
从逻辑上分析,legacy文件夹下的Android.mk里只有这么一个选择项
那么它就必须要选中,否则上一级选中了legacy文件夹就失去了作用
所以Boardconfig.mk里就必须要有
BOARD_USES_ALSA_AUDIO := true
在原来的Boardconfig.mk里,高通在范例里配置了
BOARD_USES_GENERIC_AUDIO := true
,这行可以删掉了
这是android自带的通用音频驱动,当然无法正确驱动高通平台
四、对比4个文件夹
4个文件夹,有3个不一样,那么从最简单的、相同的那个开始看
audiod文件夹是最简单的,而且与cm11的代码完全一样
五、对比audiod文件夹
截图里面3个红框的部分是一般我们需要注意或者需要看的地方
第一个红框:选择语句就不再解释了
第二个红框:代表依赖的共享lib,也就是说编译这个audio依赖这4个lib
第三个红框:LOCAL_MODULE:= audiod,这句表示此模块编译后生成的文件名为audiod
那么问题来了,这个audiod需要编译吗?
提示:
1.官方rom是我们唯一可以参考的;
2.LOCAL_MODULE代表编译后这个模块最终生成的文件名;
3.笔者也不知道读者的机型是否需要编译audiod模块;
OK,答案揭晓了:
既然知道这个模块编译之后,文件名叫做audiod,那么在官方rom里找一找,有没有叫做audiod的文件,如果没有就是不需要,如果有就是需要
当然,泛泰a870是不需要的,所以这部分就不添加任何语句
六、对比mm-audio文件夹
这个文件夹基本上与cm一样,仅有2处稍有区别,cm11的更改肯定有它的道理,读者只要知道与cm有些许区别就行。
这个文件夹下的Android.mk里,并没有提供选择题
include $(call all-subdir-makefiles)
这个就是全选,不需要我们再手工配置指定
七、对比libalsa-intf文件夹
重点来了
看上下2个截图,左右的区别,重点在于TARGET_USES_QCOM_MM_AUDIO
这个配置项的形式不同。
右边的代码形式是ifeq ($(strip $(TARGET_USES_QCOM_MM_AUDIO)),true)
左边的代码形式是ifneq ($(TARGET_USES_QCOM_COMPRESSED_AUDIO),false)
为何cm与msm-aosp有差异,或者cm为何要从ifeq更改为 ifneq?
读者理解了cm为何要这么改,后面的最后一个文件夹也就能立刻理解了
现在讲解一下:
ifneq (AAA,false)
这种语句,在不配置AAA或AAA不等于false(也就是等于true)时,就满足if条件
换句话来讲也就是cm改成了:即使不配置,也默认启用此项
因为cm代码是面对的所有机型,那么最终就说明这个项目对所有机型都是有用的
除非你在BoardConfig.mk里手工指定了这项为fasle,否则默认都是启用的
ok,回到右边msm-aosp的代码
msm-aosp这个选项与cm语法不一样,它确实要求我们选择是否配置
但因为从cm代码得知,这个项目一般都是需要选中的,所以我们需要在BoardConfig.mk里增加TARGET_USES_QCOM_MM_AUDIO := true
八、对比alsa_sound文件夹
这是音频最后一个文件夹
从截图我们可以看到cm做了许多更改,主要是把ifeq(true)改为ifneq(false)的形式
那么从前一个要点可以知道,这种形式的更改,会导致不配置也默认启用。
ok,进入正题
cm改动的项目,都是aosp必须打开的项目,所以最终还要在BoardConfig.mk里的#Audio节里添加
QCOM_ACDB_ENABLED := true
QCOM_ANC_HEADSET_ENABLED := true
QCOM_AUDIO_FORMAT_ENABLED := true
QCOM_CSDCLIENT_ENABLED := true
QCOM_PROXY_DEVICE_ENABLED := true
QCOM_OUTPUT_FLAGS_ENABLED := true
QCOM_USBAUDIO_ENABLED := true
QCOM_ADSP_SSR_ENABLED := true
QCOM_FLUENCE_ENABLED := true
QCOM_TUNNEL_LPA_ENABLED := true
九、音频部分总结
BOARD_USES_GENERIC_AUDIO := true
,这行删除
添加如下内容
BOARD_USES_LEGACY_ALSA_AUDIO := true
BOARD_USES_ALSA_AUDIO := true
TARGET_USES_QCOM_MM_AUDIO := true
QCOM_ACDB_ENABLED := true
QCOM_ANC_HEADSET_ENABLED := true
QCOM_AUDIO_FORMAT_ENABLED := true
QCOM_CSDCLIENT_ENABLED := true
QCOM_PROXY_DEVICE_ENABLED := true
QCOM_OUTPUT_FLAGS_ENABLED := true
QCOM_USBAUDIO_ENABLED := true
QCOM_ADSP_SSR_ENABLED := true
QCOM_FLUENCE_ENABLED := true
QCOM_TUNNEL_LPA_ENABLED := true
十、关于编译错误的处理
改完BoardConfig.mk就可以开始重新编译了
在编译的过程中可能会碰到几次编译错误
1.缺intermediates错误
需要目标"out/target/product/a870/obj/SHARED_LIBRARIES/libacdbloader_intermediates/export_includes”
对于这种错误,需要在device/pantech/a870/Android.mk里添加
$(shell mkdir -p $(OUT)/obj/SHARED_LIBRARIES/libacdbloader_intermediates/)
$(shell touch $(OUT)/obj/SHARED_LIBRARIES/libacdbloader_intermediates/export_includes)
注意:linux是区分大小写的,OUT必须是大写
这个语句是用来hack的,让编译系统误以为我们有libacdloader源代码(但实际上我们没有,我们只有从官方rom里提取的lib)
然后修改proprietary-blobs.txt添加libacdbloader.so
然后修改setup-makefiles.sh,取消下面语句的注释,用于把proprietary-blobs.txt提取的lib复制到obj目录
PRODUCT_COPY_FILES += \\$OUTDIR/proprietary/lib/libacdbloader.so:obj/lib/libacdbloader.so
然后重新生成vendor,再继续编译。
如果碰到其它音频lib文件提示类似的错误,请读者依葫芦画瓢处理。
2.源码编译错误
编译停下来的地方基本上不是发生错误的地方,在终端里搜索关键字error,选向上搜索,找到真正发生错误的地方。
其中一个是libalsa-intf\alsa_ucm.c,错误提示是fatal error: acdb-loader.h : NO such file or directory
对比cm
之前说过,我们没有libacdbloader的源代码,所以这个acdb-loader.h也就无法提供了
而cm则更改了这句代码,但msm-aosp需要这样改:
右边注释掉,注意,C代码双斜杠是注释//
//#if defined(QC_PROP)
// #include "acdb-loader.h"
//#else
//#endif
最终是这个样子
另一个错误发生在:alsa_sound/AudioHardwareALSA.cpp
‘PROXY_OPEN_RETRY_COUNT’ was not declared in this scope
错误指向这里
参考cm,加上#ifdef QCOM_USBAUDIO_ENABLED和#endif即可
十一、声音配置微调
对于某些有双mic降噪功能的手机,一般会在手机顶部以及底部各有一个mic。
正常底部mic作为主mic,要大声,顶部mic作为降噪mic,要小声。
这个可以用z硬件测试的mic测试功能,分别对着顶部和底部mic讲话,看声音幅度就知道是否有颠倒。
如果颠倒了,我们要调整build.prop里的配置值来修正
persist.audio.handset.mic=digital
改成
persist.audio.handset.mic=analog
或者反之,请读者自行试验
十二、进阶调试
1.耳机插入检测的方式
andoird一共有2种检测方式
方法一:由内核负责检测,设备驱动名为h2w,一般会在/sys/class/switch或/sys/devices/virtual/switch
方法二:由音频系统负责检测,msm8960就属于此种情况,实际由PM8921的GPIO38脚负责
如何知道手机是哪种检测方式?用排除法吧
查看logcat信息:
W/WiredAccessoryObserver( 627): This kernel does not have wired headset support
这样的语句即代表内核不支持耳机检测,所以只能由音频系统来检测了。
2.耳机插入检测GPIO查看
原理图下载:http://download.csdn.net/detail/benjaminwan/8453547
查看原理图第18页
PM8921的GPIO38脚,标签ANC_HS_DET即为耳机检测
开adb shell,取得root权限
cat /sys/kernel/debug/gpio
可以看到分成好几段,这是按功能把芯片引脚区分成几个段而已
GPIOs 0-151, platform/msmgpio, msmgpio:
GPIOs 152-195, platform/pm8xxx-gpio, pm-gpio:
GPIOs 196-207, platform/pm8xxx-mpp.0, pm8xxx-mpp:
GPIOs 208-211, platform/pm8xxx-mpp.1, pm8xxx-mpp:
我们要查看原理图里的PM8921的GPIO38脚,在debug信息里如何换算成第几个GPIO呢?
看上面的分段信息,第一段即MSM8960为GPIOs 0-151,共有151脚,第二段就是PM8921,我们要PM8921的第38脚,那么就是151+38= 189脚
查看GPIOs 152-195, platform/pm8xxx-gpio, pm-gpio:这一段
当耳机插入时为高电平
gpio-189 (-- ) in hi 0x05 0x10 0x2a 0x30 0x40 0x58
当耳机未插入时为低电平
gpio-189 (-- ) in lo 0x05 0x10 0x2a 0x30 0x40 0x58
3.输入设备事件查看
开adb shell,取得root权限
cat /proc/bus/input/devices
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="apq8064-tabla-snd-card Button Jack"
P: Phys=ALSA
S: Sysfs=/devices/platform/soc-audio.0/sound/card0/input2
U: Uniq=
H: Handlers=kbd event2 cpufreq
B: PROP=0
B: EV=3
B: KEY=f8 4 0 0 0 c0000 0 0 0I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="apq8064-tabla-snd-card Headset Jack"
P: Phys=ALSA
S: Sysfs=/devices/platform/soc-audio.0/sound/card0/input3
U: Uniq=
H: Handlers=event3 cpufreq
B: PROP=0
B: EV=21
B: SW=1c054
可以找到如上类似的信息,可能因手机不一样而不一样
其中Headset Jack即为耳机插入检测
Button Jack是耳机线控按钮检测
从信息得知
耳机检测设备路径/devices/platform/soc-audio.0/sound/card0/input3
对应的Handlers为event3
我们来测试一下:
cat /dev/input/event3
执行完命令后就放着,然后插入或拔出耳机,命令行会输出一些调试信息,但我们没有专用的查看工具所以无法查看具体信息,ctrl+C结束
耳机线控按钮检测设备路径/devices/platform/soc-audio.0/sound/card0/input2
对应的Handlers为event2
cat /dev/input/event2
同样地,按下耳机线控按钮,命令行会输出一些调试信息
Msm8960(APQ8064)平台的MSM-AOSP-kitkat编译适配(6):音频相关推荐
- 鸿蒙系统研究之五:替换 AOSP 预编译库,关闭 SELinux
这是我的鸿蒙系统研究系列文章的第五篇,有兴趣还可以看看前面的文章: 鸿蒙系统研究第一步:从源码构建系统镜像 鸿蒙系统研究之二:内核编译 鸿蒙系统研究之三:迈出平台移植第一步 鸿蒙系统研究之四:根文件系 ...
- linux+4.4+android,Ubuntu 14.04 x64配置Android 4.4 kitkat编译环境的方法
Ubuntu 14.04 x64配置Android 4.4 kitkat编译环境的方法跟Ubuntu 12.04 - 13.10 以及jellybean编译环境配置没多大区别, 顺便记录下而已: 64 ...
- 如何编译各平台使用的库-以编译tolua为例
转载注明出处: https://www.jianshu.com/p/5a35602adef8?appinstall=0 做U3D手机游戏,最热门的技术组合是c#+lua,使用lua是因为可以热更新,而 ...
- 在arm64平台kkfileview和LibreOffice的编译使用
在arm64平台kkfileview和LibreOffice的编译使用 1.手动编译LibreOffice 1.1在arm64的机器上启动一个docker镜像 2.开始编译kkfileview的doc ...
- 树莓派3 Android Pie 编译适配
树莓派3 Android Pie 编译适配 1准备工作 2.下载源代码以及配置依赖项 2.1 配置Git与Repo 2.2 下载源代码 2.3 配置依赖项 3. 编译 3.1 编译内核 3.2 打补丁 ...
- Android Studio 编译适配-NDK issue 解决
旧项目Android Studio 编译适配-NDK issue 问题点记录 旧的项目 在Android Studio新版本编译中遇到以下问题. 流水式总结记录一下 NDK getPlatformVe ...
- Android AOSP 单独编译某一模块
由于AOSP 项目太大,我只修改了一个模块,比如设置. 那么只需要单独编译设置这个模块就可以了. 首先执行Source: source build/envsetup.sh 执行之后,就会有一些额外的命 ...
- 【Android 逆向】Android 逆向通用工具开发 ( Windows 平台静态库程序类型 | 编译逆向工具依赖的 Windows 平台静态库程序 )
文章目录 一.Windows 平台静态库程序类型 二.编译逆向工具依赖的 Windows 平台静态库程序 一.Windows 平台静态库程序类型 在 Android 逆向通用工具 MobileGame ...
- ffmpeg编译gb28181_国标GB28181协议视频推流平台EasyGBD在Linux下编译报“UINT64_C在此作用领域中尚未声明”错误...
上一篇我们讲了国标GB28181协议视频推流平台EasyGBD正在重新编译,在编译中难免遇到不同的报错,比如"UINT64_C在此作用领域中尚未声明"错误就是其中一个. 出现该问题 ...
- 在Linux平台上搭建EasyDarwin,编译代码并简单部署
测试环境: Ubuntu gcc / g++ 从https://github.com/EasyDarwin/EasyDarwin下载代码 1.编译 第一步:进入源代码目录下 cd ./Easy ...
最新文章
- 【项目展示】自己用C语言编写的汉诺塔小游戏
- 【Paper】2012_Distributed Average Tracking of Multiple Time-Varying Reference Signals With Bounded
- python弹球小游戏程序_Python基于Tkinter模块实现的弹球小游戏
- nginx 带宽_谈谈Nginx和LVS各自的优缺点以及使用
- mysql数据库集群架构图_搭建MySQL-Cluster集群架构
- Hive的伴奏_Position Music顶级背景音乐合集243CD
- Springboot启动报错Error handling failed
- rocketmq概念
- CocoStudio1.3 场景编辑器使用
- 数学分析教程(科大)——6.3笔记+习题
- 谷歌邮箱的注册以及GEE的注册使用教程
- linux 脚本含参,linux shell脚本文件的入参
- Python实现猫捉老鼠小游戏!虽然简陋但是童真永在!
- 关于产品的一些思考——腾讯之微信
- Debut of Hyper-V, departure of Gates usher[引导,展示,招待员] in new era for Microsoft
- python实现cma—se算法_CMA算法的仿真结果
- 微信小程序抓包与逆向+微信小程序反编译教程+解包教程+解包工具
- 多租户与多用户的区别
- 记一次golang模拟登录淘宝
- 产品经理|产品设计理念