
本文以Qualcomm平台为例,介绍android下的音频结构. Android使用tinyALSA作为音频系统,其使用方法和基本框架与Linux中常用的ALSA音频子系统一致.
ALSA音频框架
ALSA(高级Linux声音体系结构)是一个开源项目(),在正式版的Kernel 2.6中引入. 它提供了一套完整的音频解决方案,涵盖了音频设备的用户界面和内核空间操作界面.
在传统的Linux平台上,用户空间可以调用alsa-lib提供的应用程序,以调用内核空间中的alsa-soc接口来控制底层音频设备.

android平台的音频框架如下:

Android平台音频系统使用tinyALSA. 主要变化是用户空间音频接口不依赖于alsa-lib库,并且使用了简化的libtinyalsa库,但内核中仍使用ALSA框架驱动程序框架. android中HAL层的相关模块的用法如下:

声卡的主要功能:
1,播放声音(播放)
2,记录(捕获)
3,声音控制(控制)
音频设备节点
音频设备节点位于/ dev / snd目录中,分为三类:
1,以“ p”结尾的pcmC0D0p的形式表示回放节点,回放
2,以“ c”结尾的pcmC0D0c形式表示记录节点,捕获
3. ControlC0以“ control”开头以指示控制节点,控制量等.
其中pcmC0D0p和pcmC0D0c构成一个pcm设备,其中C0代表0号声卡,D0代表0号声卡. 声卡可以有多个设备,每个设备代表声卡的音频路径.
生成pcmC0D0p的代码分析如下,分析每个pcm节点的含义,例如pcmC0D1c:
pcmC0D0p字符串组织在kernel / sound / core / pcm.c中,其中D0的数字0来自pcm-> device,pcm由参数传递.

以高通公司的msm8952平台为例:
D后面的数字是msm8952_dai结构成员的数量
/kernel/sound/soc/msm/msm8952.c

Android平台HAL层音频框架
音频数据流的框图如下


HAL层音频帧接口
1)audio.primary.msm8952.so
此文件是Qualcomm平台音频HAL层代码库,负责与框架交换音频数据和控制参数.
代码路径: hardware / qcom / audio / hal
LOCAL_SRC_FILES: = \
audio_hw.c \
voice.c \
platform_info.c \
$(AUDIO_PLATFORM)/platform.c
2)libtinyalsa.so
此文件是tinyALSA的应用程序库,该文件库由HAL层调用,并负责连接内核的ALSA驱动程序接口.
代码路径: 外部/ tinyalsa
LOCAL_SRC_FILES: = mixer.c pcm.c
3)libaudioroute.so
此文件用于解析用户空间音频通道配置文件(mixer_path_XXX.xml),而ALSA配置音频通道.
代码路径: system / media / audio_route
LOCAL_SRC_FILES: = audio_route.c
内核层ASoC框架
在内核中,ALSA依赖于ASoC(ALS上系统)驱动器模型. ASoC是嵌入式系统使用的音频框架. 从硬件架构的角度将其划分为相对独立的硬件单元,并分为三个模块: 机器,平台/ CPU和驱动设备上的CODEC.

可以理解为: 一组嵌入式硬件平台(机器)包括平台AP(平台)和音频CODEC芯片(编),分别对应于ASoC的三个设备驱动程序. 这三个设备使用各自的功能注册dev设备,但是它们都是使用内核平台设备模型创建的. ASoC的主要代码位于内核/声音/ soc下. 让我分别介绍一下:
机器设备驱动程序
机器设备可视为嵌入式主板(Board)或声卡. 机器设备驱动程序是ASoC驱动程序框架的入口. 它的主要功能是负责平台/ cpu和编之间的连接和控制,或者响应独立于平台和编功能的特殊音频事件,例如平台GPIO控制外部功率放大器等. 这些特定的操作代码属于机器本身将被放入机器驱动程序中.
机器设备驱动程序的主要功能是定义各种DAI(数字音频接口)链接. 它的作用是连接平台/ cpu和编设备驱动程序,以形成完整的音频路径.
在内核设备树中,平台定义了声卡设备. 例如,MSM8976平台在msm8976.dtsi中定义了一个名为“ msm8976-tasha-snd-card”的声卡,它是ASoC框架中的机器设备. 机器设备的初始化是整个ASoC驱动程序的入口. 机器设备的probe()将调用snd_soc_register_card()来注册声卡,然后在snd_soc_instantiate_card()中实例化声卡设备时,分别调用Platform和Codec设备的probe()以完成对声卡的初始化. 两个设备. 如果没有错误,声卡将成功注册,并且我们可以在/ dev / snd下看到多个音频设备.
Qualcomm平台机器设备驱动程序位于以下路径:
内核/声音/ soc / msm / <芯片组>

msm8976.dtsi的定义如下:

在msm9952-slimbus.c的代码中是机器的探针:

平台设备驱动程序
平台设备可视为平台AP(SoC主控制或CPU). 它负责在嵌入式平台上提供音频功能,例如播放,录制和语音呼叫.
平台设备驱动程序具有两个主要功能:
(1)传输: 负责平台AP的音频/语音数据流(流)与DSP之间的传输;
(2)路由: 根据特定路由将流数据流映射到其他音频模块.
ASoC将注册多个平台设备,以负责具有不同功能的音频模块:
(1)msm-pcm-dsp: 负责音频的播放/记录
代码路径: kernel / sound / msm / msm-pcm-q6.c
(2)msm-pcm-voice: 负责语音通话
代码路径: kernel / sound / msm / msm-pcm-voice-v2.c
(3)msm-voip-dsp: 负责VoIP通话
代码路径: kernel / sound / msm / msm-pcm-voip-v2.c
(4)msm-compress-dsp: 负责以压缩格式播放音频
代码路径: kernel / sound / msm / msm-compressed-q6-v2.c
(5)msm-pcm-routing: 负责流数据流的路由
代码路径: kernel / sound / msm / msm-pcm-routing-v2.c
msm-pcm-routing-v2.dtsi的定义如下:

在msm-pcm-routing-v2.c中定义了许多kcontrol,小部件和路由.
(1)struct snd_kcontrol_new
kcontrol表示控制单元,并描述了控件本身的属性和功能. 例如混频器多路复用器,复用器多路复用器,增益设置android 音频播放框架,静音开关等.
(2)struct snd_soc_dapm_widget
小部件是kcontrol的程序包,可以将多个小部件与path连接起来以形成音频路径.
(3)struct snd_soc_dapm_route

route用于描述互连的小部件.

CPU设备驱动程序
Qualcomm平台将CPU设备与平台设备分开. 实际上,它们是紧密集成的. CPU设备驱动程序定义了平台可以支持的各种流.
Qualcomm平台使用一个单独的文件来定义CPU设备.
(1)FE CPU DAI在msm-dai-fe.c中定义

(2)BE CPU DAI在msm-dai-q6-v2.c中定义

CODEC设备驱动程序
对于嵌入式设备的主板,通常会集成音频CODEC芯片. ASoC架构下的CODEC器件功能对应于物理CODEC. 它在机器的控制下连接到平台设备,并负责音频的实际处理,例如声音播放(D / A),声音收集(A / D)和各种音频控制. 控制设置.
该平台通常将集成一个编单元,还将添加一个外部独立的编芯片,从而获得了更好的音质. 例如沃尔夫森的WM8998芯片,它是一个独立的编,基于I2S接口从平台获取音频数据,通过其内部DAC输出到耳机或扬声器. 高通公司有自己的外部编芯片,例如WCD9326 / 9335等,平台AP的音频数据接口称为Slimbus,实际上是与I2S多路复用的GPIO端口.
CODEC芯片可能需要I2C或SPI控制.
COCEC设备支持耳机的插入和拔出以及按键检测.
CODEC设备驱动程序为各种开关以及DAPM使用的小部件和路由定义了大量混合器,mux和kswitch.
内核/声音/ soc /编/wcd9335.c

示例: 打开MIC录音
CODEC设备驱动程序为各种开关以及DAPM使用的小部件和路由定义了大量混合器,mux和kswitch.


音频模块调试
对于使用平台内置编或高通公司外部编的常规项目,无需太多修改音频功能. 如果添加了其他SmartPA,CODEC或DAC芯片,将更加麻烦. 我们可能在项目中进行以下工作:
(1)主要和辅助麦克风调试
某些Qualcomm平台的原始代码使用DMIC,而我们的项目通常使用AMIC. 这需要修改DTSI声卡节点中的“ qcom,音频路由”值.
某些平台代码的机器驱动程序缺少辅助麦克风的控制,需要手动添加.
在模具中,您需要分别测试辅助麦克风,但默认情况下,高通公司没有单独使用麦克风的用例. 我们需要在音频Hal层中修改输入设备的选择.
(2)耳机按钮

机器驱动程序中有一系列的耳机按钮阈值. 我们需要根据Qualcomm文档计算不同按钮阻抗的阈值并填写数组.
(3)普通音频PA
现在将在大多数项目中添加扬声器PA. 如果它是带有单个gpio端口控制开关的通用PA,则需要在机器驱动程序中添加控制逻辑.
(4)第三方CODEC调试
第三方编通过I2S接口与AP传输音频数据,然后控制扬声器或耳机发声. 通常,需要I2C或SPI来控制芯片. 我们需要调整I2C或SPI以获得CODEC芯片的寄存器数据. 在平台侧调整主I2S输出;全面的调试.
(5)SmartPA调试
SmartPA包括CODEC和PA. 芯片寄存器配置比CODEC简单,但硬件接口仍为I2S和I2C. 我们要做的与第三方CODEC相似.
(6)第三方音效移植
从第三方获取迁移软件包并导入. 根据声音算法的运行位置,我们需要在平台上配置音乐播放模式. 如果该算法在AP端运行,则需要关闭平台卸载回放模式,并仍然使用传统的deep_buffer模式.
(7)音频环回测试
Qualcomm平台在audioFT中提供了环回模式功能. 我们需要针对不同的项目修改ftm_loopback_config配置文件,以满足工厂的测试要求.
(8)更新音频参数
调试过程中遇到的问题
在实际项目中,存在许多类型的音频问题. 音频几乎涉及Android的所有层. 当我们遇到声音问题时,我们需要清楚地定义问题的位置.
(1)沉默的问题
如果在新项目的早期阶段遇到静默问题,请首先检查声卡驱动程序是否已成功安装. 如果没有挂起声卡,请检查驱动程序;如果声卡正常,则使用QXDM获取音频数据以检查DSP是否静音. 如果DSP处于静默状态,则需要转到框架上的转储数据以查找原因;如果DSP正常,则一般问题出在内核,我们首先尝试检查耳机是否有声音. 如果耳机没有声音,则将焦点放在扬声器上,新添加的扩音器是否有问题;如果耳机没有声音,则转储CODEC寄存器,或检查mixer_paths配置是否不正确. 还有很多.
(2)播放噪音的问题
可能有很多噪音原因. 驱动器中PA的切换时序不正确会引起POP声音;上层框架性能问题将导致间歇性音频流,这还将导致POP声音;如果音频参数调整不当,将会导致音质变差,等等.
(3)其他问题
调试工具
(1)QXDM + QCAT
QXDM工具用于捕获日志的DSP部分(包括音频数据),然后使用QCAT解析日志,从而可以恢复DSP中每个节点的音频数据. 我们可以使用它来确定声音是否异常,然后再从AP进入DSP并从DSP退出DSP.

(2)使用QACT确认音频参数和称为输入/输出设备的设备

(3)打开logcat和kmsg的各种日志
对于上层,在音频相关文件的开头打开#define LOG_NDEBUG 0

对于内核,如果内核的dynamic_debug可用,我们可以直接打开相关文件的调试信息;如果不可用,我们需要在文件开头添加#define DEBUG

(4)使用tinymix确认音频控制开关
在外壳中,您可以使用tinymix导出所有ASoC控件android 音频播放框架,并且我们可以检查控件是否存在异常开关.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-268669-1.html
解救股灾被套资金