本文以高通平台为例,介绍一下android下的音频结构。android使用的是tinyALSA作为音频系统,使用方法和基本框架与linux中常用的ALSA音频子系统是一致的。

ALSA音频框架

ALSA(Advanced Linux Sound Architecture)是一个开源项目(http://www.alsa-project.org/) ,在Kernel 2.6正式版本被引入,它提供了一整套音频解决方案,涵盖了用户空间和内核空间对音频设备的操作接口。

在传统的Linux平台,用户空间可以调用alsa-lib提供的应用来调用内核空间的alsa-soc接口, 实现对底层音频设备的控制。

android平台的音频框架如下:

Android平台音频系统使用的是tinyALSA,主要的改变在于用户空间的音频接口不依赖alsa-lib库, 改用精简的libtinyalsa库,但是在内核中仍然使用ALSA框架的驱动框架。android中HAL层相关模块使用如下图所示:

声卡的主要功能:

1,播放声音(playback)

2,录音(capture)

3,声音控制(control)

音频设备节点

音频设备节点位于/dev/snd目录下,分为三类:

1,形如 pcmC0D0p   以‘p’结尾的表示播放节点,playback

2,形如 pcmC0D0c   以‘c’结尾的表示录音节点,capture

3,形如controlC0      以“control”开头的表示控制节点,控制音量等

其中pcmC0D0p与pcmC0D0c组成一个pcm设备,其中C0代表0号声卡Card,D0代表0号设备device。一个声卡可以有多个设备,每个设备代表该声卡的一个音频通路。

生成pcmC0D0p的代码分析如下,分析一下各个pcm节点的含义,如pcmC0D1c:

在kernel/sound/core/pcm.c中组织了pcmC0D0p字符串,其中D0的数字0来自于pcm->device,pcm由参数传递而来。

以高通msm8952平台为例:

D后面的数字为msm8952_dai结构体成员的个数

/kernel/sound/soc/msm/msm8952.c

android平台HAL层音频框架

音频数据流框图如下

HAL层音频框架接口

1) audio.primary.msm8952.so

该文件是高通平台音频HAL层代码库,负责与framework交换音频数据和控制参数。

代码路径: hardware/qcom/audio/hal

LOCAL_SRC_FILES := \

audio_hw.c \

voice.c \

platform_info.c \

$(AUDIO_PLATFORM)/platform.c

2) libtinyalsa.so

该文件是tinyALSA的应用库,由HAL层调用,负责对接kernel的ALSA驱动接口。

代码路径: external/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

kernel层ASoC框架

在内核中, ALSA依赖ASoC(ALSA System on Chip)驱动模型。ASoC是嵌入式系统使用的音频框架,它从硬件架构的角度来将功能相对独立的硬件单元细分出来,在驱动设备上分为machine、 platform/CPU和CODEC三个模块。

可以这么理解:一套嵌入式硬件平台(Machine)包含了平台AP(Platform)和音频CODEC芯片(Codec),对应ASoC的三个设备驱动。这三个设备分别注册各自功能的dev设备,但都是以内核platform设备模型来创建。 ASoC主要代码位于kernel/sound/soc下。 下面分别来介绍一下:

MAchine设备驱动

Machine设备可以看成是一块嵌入式主板(Board) 或者一块声卡。machine设备驱动是ASoC驱动框架的入口, 主要功能是负责platform/cpu和codec之间的连接和控制,或者响应独立于Platform功能和Codec功能之外的特殊音频事件,如平台GPIO控制外置功放等,这些属于machine本身的特定操作代码,都会放到machine驱动里。

Machine设备驱动的主要功能是定义各种DAI(Digital Audio Interface) links,它的作用是把platform/cpu和codec设备驱动连接起来,形成完整的音频通路。

在内核设备树中,平台会定义一个声卡设备,如MSM8976平台在msm8976.dtsi中定义了一个名为“msm8976-tasha-snd-card” 的声卡,它就是ASoC框架里的machine设备。 machine设备的初始化是整个ASoC驱动的入口。 machine设备的probe()会调用snd_soc_register_card()去注册声卡,然后在snd_soc_instantiate_card()里实例化声卡设备的时候,调用Platform和Codec设备各自的probe(),完成这两个设备的初始化。如果没有错误,那么声卡会注册成功,我们在/dev/snd下可以看到多个音频设备。

高通平台的machine设备驱动放在如下路径:

kernel/sound/soc/msm/

msm8976.dtsi定义如下:

msm9952-slimbus.c中代码中是machine的probe:

platform设备驱动

Platform设备可看作是平台AP(SoC主控,或CPU)。 它负责提供嵌入式平台端的音频功能, 如播放、录音、 Voice通话等。

Platform设备驱动主要有两个作用:

(1) transfer:负责平台AP端的audio/voice数据流(stream)和DSP之间的传输;

(2) routing:将stream数据流按照特定的路线对应到其他音频模块中。

ASoC会注册多个Platform设备来负责不同功能的音频模块:

(1) msm-pcm-dsp: 负责audio回放/录音

代码路径: kernel/sound/msm/msm-pcm-q6.c

(2) msm-pcm-voice: 负责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: 负责压缩格式的audio播放

代码路径: kernel/sound/msm/msm-compressed-q6-v2.c

(5) msm-pcm-routing:负责stream数据流的路线指定

代码路径: kernel/sound/msm/msm-pcm-routing-v2.c

msm-pcm-routing-v2.dtsi定义如下:

在msm-pcm-routing-v2.c里定义了很多kcontrol、 widget和route。

(1) struct snd_kcontrol_new

kcontrol代表一个控制单元, 描述了控件自身的属性和功能。 如mixer多路混合器、 mux多路选择器、 gain增益设置、 mute开关等。

(2) struct snd_soc_dapm_widget

widget是kcontrol的封装,能够用path来连接多widget,形成一条音频路径。

(3) struct snd_soc_dapm_route

route用来描述相互连接的widget。

CPU设备驱动

高通平台将CPU设备独立于Platform设备,其实他们是紧密结合的关系, CPU设备驱动定义了平台能够支持的各种stream。

高通平台用单独的文件来定义CPU设备。

(1)在msm-dai-fe.c里定义了FE CPU DAI

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

CODEC设备驱动

对于一块嵌入式设备的主板来说,一般会集成一颗音频CODEC芯片。 ASoC架构下的CODEC设备功能和物理CODEC对应, 其在machine的控制下和platform设备连接,负责音频的实际处理,如声音播放(D/A)、声音采集(A/D) 和各种音频control控件的设置。平台一般会集成一个CODEC单元,也会有添加外部独立CODEC芯片,已达到更好的音质。如Wolfson的WM8998芯片,它是一颗独立的CODEC,基于I2S接口从平台获取音频数据,在其内部经过DAC输出到耳机或speaker。高通有自己的外置CODEC芯片,如WCD9326/9335等,和平台AP的音频数据接口叫Slimbus,其实是和I2S复用的GPIO口。

CODEC芯片可能需要I2C或SPI控制。

COCEC设备支持耳机插拔及按键检测功能。 CODEC设备驱动中定义了大量的mixer、 mux和各种开关的kcontrol,以及DAPM使用的widget和route。

kernel/sound/soc/codec/wcd9335.c

实例:打开MIC录音

CODEC设备驱动中定义了大量的mixer、 mux和各种开关的kcontrol,以及DAPM使用的widget和route。

音频模块调试

对于使用平台内置CODEC或者高通外部CODEC的常规项目,把audio功能调通所需要修改的内容不多,如果是添加额外的SmartPA、 CODEC或者DAC芯片,那么会比较麻烦。我们在项目中可能会有以下工作:

(1)主、副mic调试

部分高通平台的原始代码使用的是DMIC,而我们项目通常使用AMIC,这个需要修改DTSI的声卡节点中“qcom,audio-routing” 值。

部分平台代码的machine driver中缺少副mic的control,需要手动添加。

工模中需要对副mic单独测试,但是高通默认没有这样的usecase来单独使用mic,我们需要在audio hal层修改input设备的选择。

(2)耳机按键

在machine driver里有一个耳机按键阀值的数组,我们需要根据高通文档计算出不同按键阻抗的阀值,填进数组。

(3)普通音频PA

现在多数项目都会添加speaker PA,如果是单个gpio口控制开关的普通的PA,则需要在machine driver里添加控制逻辑。

(4)第三方CODEC调试

第三方CODEC通过I2S接口和AP传输音频数据,然后控制speaker或headphone发声,一般需要I2C或者SPI来控制芯片。我们需要把I2C或SPI调通,获得CODEC芯片的寄存器数据;调通平台端的master I2S输出;综合调试。

(5) SmartPA调试

SmartPA包含了CODEC和PA,芯片寄存器配置上比CODEC简单,但是硬件接口仍然会是I2S和I2C,我们要做的事情和第三方CODEC差不多。

(6)第三方音效移植

从第三方获取移植包,导入即可。依据音效算法运行的位置,我们需要配置平台端的音乐播放模式。如果算法跑在AP侧,我们需要关闭平台端offload播放模式,仍采用传统的deep_buffer模式。

(7)音频loopback测试

高通平台在audioFT里提供了loopback模式功能,我们需要针对不同的项目,修改ftm_loopback_config配置文件,满足工厂的测试要求。

(8)更新音频参数

调试中遇到的问题

在实际项目中, audio的问题种类会很多。 Audio涉及Android几乎所有的层,遇到声音问题时我们需要明确界定问题所处的位置。

(1) 无声问题

一个新项目前期如果遇到无声问题,首先检查声卡驱动是否挂载成功。如果声卡没挂上,那么检查驱动;如果声卡OK,那么用QXDM抓取音频数据检查DSP是否无声。如果DSP无声,需要往framework上面dump数据找原因;如果DSP正常,一般问题出在kernel里,我们先试一下耳机是否有声音。如果耳机有声音speaker无声音,那就重点检查speaker这块,是否新加的PA有问题;如果耳机无声音,那么dump一下CODEC的寄存器,或者检查mixer_paths是否配置错误。等等。。

(2)播放杂音问题

杂音可能有多种原因。驱动里PA的开关时序不合适会造成POP音;上层framework性能问题会造成音频流断续,也会导致POP音;音频参数没调好也会导致音质差,等等。。

(3)其他问题

调试工具

(1) QXDM + QCAT

QXDM工具用来抓取DSP部分的log,包含音频数据,然后用QCAT解析log,能够还原出DSP内部各个节点的音频数据。我们借此可以判断声音从AP进入DSP和从DSP出来前是否异常。

(2)使用QACT确认音频参数和调用的input/output设备的Device

(3)打开logcat和kmsg的各种log

对于上层,在音频相关文件的开头打开#define LOG_NDEBUG 0

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

(4)使用tinymix确认音频控件开关

在shell里可以使用tinymix把ASoC所有的control导出来,我们可以检查开关异常的control。

linux查看录音驱动程序,linux驱动由浅入深系列:ALSA框架详解 音频子系统之二相关推荐

  1. linux驱动由浅入深系列:tinyalsa(tinymix/tinycap/tinyplay/tinypcminfo)音频子系统之一

    linux驱动由浅入深系列:tinyalsa(tinymix/tinycap/tinyplay/tinypcminfo)音频子系统之一 linux驱动由浅入深系列:ALSA框架详解 音频子系统之二 目 ...

  2. linux驱动由浅入深系列:高通sensor架构实例分析之一

    点击打开链接 本系列导航: linux驱动由浅入深系列:高通sensor架构实例分析之一(整体概览+AP侧代码分析) linux驱动由浅入深系列:高通sensor架构实例分析之二(adsp驱动代码结构 ...

  3. linux驱动由浅入深系列:基于高通平台分析触摸屏(TP)、虚拟按键驱动

    触摸屏的触摸板(touch panel简称TP)驱动的基本架构和普通按键驱动基本一致,可以参考文章: linux驱动由浅入深系列:输入子系统之二(编写一个gpio_key驱动).只是其功能稍稍复杂些, ...

  4. linux驱动由浅入深系列:高通sensor架构实例分析之三(adsp上报数据详解、校准流程详解)

    本系列导航: linux驱动由浅入深系列:高通sensor架构实例分析之一(整体概览+AP侧代码分析) linux驱动由浅入深系列:高通sensor架构实例分析之二(adsp驱动代码结构)

  5. linux如何查看硬件驱动,linux查看硬件信息及驱动设备相关整理

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 联系我登录 首页 业界新闻 技术文章 资源分享 微语 linux查看硬件信息及驱动设备相关整理[转] 蓝猫 发布于:2014-5-30 17:48 分类: ...

  6. linux检测硬件驱动,linux查看硬件信息及驱动设备相关整理

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 联系我登录 首页 业界新闻 技术文章 资源分享 微语 linux查看硬件信息及驱动设备相关整理[转] 蓝猫 发布于:2014-5-30 17:48 分类: ...

  7. linux查看设备硬件,linux查看硬件信息及驱动设备相关整理

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 联系我登录 首页 业界新闻 技术文章 资源分享 微语 linux查看硬件信息及驱动设备相关整理[转] 蓝猫 发布于:2014-5-30 17:48 分类: ...

  8. linux 查看usb驱动,linux查看硬件信息及驱动设备相关整理

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 联系我登录 首页 业界新闻 技术文章 资源分享 微语 linux查看硬件信息及驱动设备相关整理[转] 蓝猫 发布于:2014-5-30 17:48 分类: ...

  9. linux查看硬盘驱动,linux查看硬件信息及驱动设备相关整理

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 联系我登录 首页 业界新闻 技术文章 资源分享 微语 linux查看硬件信息及驱动设备相关整理[转] 蓝猫 发布于:2014-5-30 17:48 分类: ...

最新文章

  1. 在参数上使用@Param(“paramName”)注解”解决了传多个参数的问题
  2. 面向对象编程03—封装、继承、重写、MRO、多态
  3. 华为机试——字符串最后一个单词的长度
  4. Mapreduce 进阶
  5. Linux 命令(12)—— wc 命令
  6. 设计模式——设计模式三大分类以及六大原则
  7. 通用PHM集成开发环境PIDE
  8. 在Linux下用sopcast/qsopcast收看网络电视
  9. python sklearn包中的主成分分析_sklearn主成分分析 NBA球队数据PCA降维可视化
  10. 其实嵌入式编程还是很难很复杂的
  11. 安卓手机真的不行了,搞不定卡顿问题,只能抄袭苹果iOS系统,然而各怀鬼胎的它们终究画虎不成反类犬...
  12. 文档服务器备份策略,服务器备份策略
  13. 坑爹的MediaPlayer.isPlaying()
  14. 微信公众号开发教程(一)
  15. 给大家推荐一款代替Visio的在线作图工具ProcessOn
  16. (附源码)SSM学衡国学堂围棋社管理系统JAVA计算机毕业设计项目
  17. 水库雨水情自动测报 水库雨水情安全监测数据采集终端
  18. 【idea错误】open matching files in associated application
  19. VF01/VF02/VF03销售发票屏幕增强实例
  20. mutt配置文件_CentOS 下配置以 smtp 方式(msmtp)使用 mutt

热门文章

  1. SCA思考:“人脸”数据被滥用,谁来负责?
  2. python编程图形_Python编程与几何图形
  3. oracle 与mysql查询_oracle与mysql分页查询语句sql
  4. 所付出的努力终不会被辜负~江南大学计算机初试考研经验分享
  5. 实况球员综合能力大比拼
  6. openGL之API学习(六十九)水平同步 垂直同步
  7. iOS app崩溃率,如何解决线上闪退
  8. incam板层的层别前缀名解释及软件快捷键
  9. shell实现根据输入分数判断等级
  10. 2.机器学习基础(五)