修改Android开机声音从耳机通道输出

文档说明

本文档以SC826(MSM8953平台,Android 7)为例,说明如何修改开机声音从耳机通道输出。

不想看分析过程的,直接看 patch文件 章节。

 

应用背景

默认代码,在不插入耳机时,声音从SPEAKER输出。 插入耳机,声音则从耳机通道输出。

客户在硬件设计时,用耳机通道+功放作为声音输出的唯一通道。

发现一个问题,在Android开机动画时应该播放的开机声音,无法从耳机通道输出,还是从SPEAKER通道输出。但系统开机完成之后,声音就能从耳机通道输出了。

 

音频文件

开机声音对应的音频文件所在位置:

系统:

/system/media/boot.wav

 

源代码:

vendor/qcom/proprietary/qrdplus/Extension/apps/BootAnimation/boot.wav

 

耳机中断

最初怀疑开机阶段没有检测到耳机,下面是耳机中断处理函数:

 kernel/sound/soc/codecs/wcd-mbhc-v2.c -> wcd_mbhc_swch_irq_handler()

 

增加调试打印

修改Android开机声音从耳机通道输出_第1张图片

 

经测试,开机阶段能够触发耳机中断,但是声音仍然从SPEAKER输出。

 

耳机事件驱动

上层UI或应用层,是通过事件(event)与底层驱动沟通。

可以通过发送事件模拟耳机插入拔出,可以看到界面上耳机图标的变化:

耳机插入:

adb shell

sendevent /dev/input/event5 5 2 1

sendevent /dev/input/event5 0 0 0

 

耳机拔出

sendevent /dev/input/event5 5 2 0

sendevent /dev/input/event5 0 0 0

 

也可以事件监控实际的耳机插入拔出动作,见下图:

修改Android开机声音从耳机通道输出_第2张图片

 

在播放开机声音之前,耳机插入的事件已经产生,但是仍然从SPEAKER播放。说明上层UI并没有处理该事件。

 

xml文件

从音频配置的xml文件入手, SC826对应的是:

源码路径:

hardware/qcom/audio/configs/msm8953/mixer_paths_mtp.xml

 

系统路径:

/system/etc/mixer_paths_mtp.xml

 

SPEAKER通道输出对应:

 

耳机通道输出对应:

修改Android开机声音从耳机通道输出_第3张图片

 

这里所使用的耳机是headphones,和headset有区别。

 

尝试把SPEAKER通道强制配成耳机通道:

修改Android开机声音从耳机通道输出_第4张图片

 

更新xml文件:

adb root

adb remount

adb push d:\mixer_paths_mtp.xml /system/etc/

重启系统,很不幸,开机声音仍然从SPEAKER通道输出。

 

Audio-routing

上面尝试了各种方法,开机声音仍然不为所动,坚持不懈的从SPEAKER通道输出。

 

音频驱动的HAL相关代码路径如下:

hardware/qcom/audio/hal/audio_hw.c

在该文件中增加调试信息,可以确定,播放开机声音时并没有走到这里。 说明HAL层没有初始化。

 

回过头来,再看看播放开机声音的源码是如何实现的。

播放开机声音的源码路径如下:

frameworks/base/cmds/bootanimation/audioplay.c

 

调用底层驱动播放音频文件的函数如下:

修改Android开机声音从耳机通道输出_第5张图片

 

这里选择了一个pcm device进行音频播放。 这部分代码是照抄tinyplay的实现,相当于tinyplay命令。tinyplay属于alsa驱动的一部分,相关路径如下:

external/tinyalsa/tinyplay.c

 

audioplay.c只是选择了pcm device,但是并没有配置audio-routing,所以开机声音还是按照默认的routing通道输出。

正常系统起来之后,可以通过以下命令切换routing到耳机通道,并播放开机声音:

adb shell
tinymix 'PRI_MI2S_RX Audio Mixer MultiMedia1' '1'
tinymix 'MI2S_RX Channels' 'Two'
tinymix 'RX1 MIX1 INP1' 'RX1'
tinymix 'RX2 MIX1 INP1' 'RX2'
tinymix 'RX HPH Mode' 'HD2'
tinymix 'COMP0 RX1' '1'
tinymix 'COMP0 RX2' '1'
tinymix 'RDAC2 MUX' 'RX2'
tinymix 'HPHL' 'Switch'
tinymix 'HPHR' 'Switch'


tinyplay /system/media/boot.wav

我们只要在audioplay.c里面增加 tinymix的这部分实现即可。

参考 external/tinyalsa/tinymix.c, 增加 fibo_config_path函数,切换audio-routing为耳机通道。

修改Android开机声音从耳机通道输出_第6张图片

 

测试方法:

  1. 先source / lunch
  2. 在 frameworks/base/cmds/bootanimation/ 路径下执行: mm
  3. 把编译生成的 out\target\product\msm8953_64\system\bin\bootanimation   拷出来。 
  4. adb push d:\bootanimation /system/bin
  5. 重启系统

 

这样就能听到开机声音从耳机通道输出了。

 

patch文件

修改路径 frameworks/base/cmds/bootanimation/audioplay.c

https://uploader.shimo.im/f/eOPGL2mvxowRc68B.patch?attname=audioplay.patch&download

 

参考文档

附一遍CSDN大神文章链接,对理解高通音频架构很有帮助:

https://blog.csdn.net/LoongEmbedded/article/details/80404839

你可能感兴趣的:(Android驱动)