Linux音频子系统 - ALSA ASoC

Posted 四季帆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux音频子系统 - ALSA ASoC相关的知识,希望对你有一定的参考价值。

1. linux音频子系统介绍

        Linux音频系统比较复杂,各层间有很多交叉,可能是最无序的子系统。

1.1 ALSA

        ALSA 是 Advanced Linux Sound Architecture 的缩写,即高级Linux声音架构,在 Linux 操作系统上提供了对音频和 MIDI(Musical InstrumentDigital Interface,音乐设备数字化接口)的支持。在Linux2.6 版本内核以后,ALSA 已经成为默认的声音子系统,用来替换 2.4 版本内核中的OSS(Open Sound System,开放声音系统)。

        ALSA 是一个完全开放源码的音频驱动程序集,是由志愿者维护的开源项目,而 OSS 则是由公司提供的商业产品。ALSA 系统包括驱动包alsa-driver(集成在内核源码),开发包 alsa-libs,开发包插件 alsalibplugins,设置管理工具包 alsa-utils,其他声音相关处理小程序包alsa-tools,特殊音频固件支持包 alsa-firmware。

1.2 ASoC

        ASoC 是Alsa System on Chip的缩写,用于实现那些集成声音控制器的CPU,它的设计目标如下:

解耦codec,codec的驱动不依赖具体的平台;
简单易用的I2S/PCM配置接口,让soc和codec的配置相匹配;
动态的电源管理DAPM,实现对用户空间透明的电源管理,各个widget按需供电,实现功耗最小化;
消除pop音,控制各个widget上下电的顺序消除pop音;
添加平台相关的控制,如earphone, speaker。

1.3 总结

        在嵌入式开发中,SoC一般都会集成音频相关的控制器,所以嵌入式开发中基本上就是使用ASoC架构,后面也是以ASoC 架构来分析。

2. ASoC架构

        为了解决复用性问题, 内核才引入了ASoC架构,在底层ASoC抽象了如下三个模块:Platform、Codec 和 Machine。

2.1 Platform

        指某款soc平台的音频模块,该模块负责DMA的控制和I2S的控制, 由CPU厂商负责编写此部分代码。platform又可细分为二个部分:

        cpu dai:在嵌入式系统里面通常指soc的i2s,pcm总线控制器,负责把音频数据从I2S tx FIFO搬运到codec(playback,capture则相反)。cpu_dai通过 snd_soc_register_dai()来注册。注:DAI是Digital Audio Interface的简称,分为cpu_dai和codec_dai,这两者通过i2s/pcm总线连接;AIF是Audio Interface母的简称,嵌入式系统中一般是I2S和PCM接口。

        PCM dma:负责把dma buffer中的音频数据搬运到i2s tx fifo。值得留意的是:某些情形下是不需要dma操作的,比如modem和codec直连,因为modem本身已经把数据送到fifo了,这时只需要启动codec_dai接收数据即可;该情形下,machine驱动dai_link中需要设定.platform_name = “snd_soc_dummy”,这是虚拟dma驱动,实现见sound/soc/soc-utils.c。音频dma驱动通过 snd_soc_register_platform()来注册,故也常用platform来指代音频dma驱动(这里的platform需要与soc platfrom区分开)。

2.2 Codec

        该模块负责AFIx的控制和DAC部分的控制(也可以说是芯片自身的功能的控制), 由Codec厂商负责编写此部分代码。codec部分主要就是codec dai。

        对于回放来说,userspace送过来的音频数据是经过采样量化的数字信号,在codec经过DAC转换成模拟信号然后输出到外放或耳机,这样你就可以听到声音了,codec字面意思是编解码器,但芯片(codec)里面的功能部件很多,常见的有AIF,DAC,ADC,Mixer,PGA,line-in,line-out,有些高端的codec芯片还有EQ,DSP,SRC,DRC,AGC,Echo-Canceller,Noise-Suppression等部件。

2.3 Machine

        用于描述一块电路板, 它指明此块电路板上用的是哪个Platform和哪个Codec, 由电路板商负责编写此部分代码。

        通过配置dai_link把cpu_dai,codec_dai,modem_dai各个音频接口给链结成一条条音频链路,然后注册snd_soc_card.和上面两个不一样,platform和codec驱动一般是可以重用的,而machine有它特定的硬件特性,几乎是不可重用的。所谓的硬件特性指:Soc Platform与Codec的差异;DAIs之间的链结方式;通过某个GPIO打开Amplifier;通过某个GPIO检测耳机插拔;使用某个时钟如MCLK/External-OSC作为i2s,CODEC的时钟源等等。

2.4 举例

        以播放为例, 流程如下:

DMA : 负责把用户空间的音频数据从系统内存搬移至I2S的FIFO.
I2S : 负责以某个采样频率、采样深度、通道数发送音频数据, 也叫dai (Digital Audio Interface).
AFIx : 负责以某个采样频率、采样深度、通道数接收音频数据, 也称作dai.
DAC : 并把数据通过DAC转换后送给耳机等播放.

3. 用户接口

3.1 dev/snd

controlC0 :用于声卡的控制,例如通道选择,混音,麦克风的控制等
midiC0D0:	用于播放midi音频,C0D0代表的是声卡0中的设备0
pcmC0D0c:	用于录音的pcm设备,c表示capture
pcmC0D0p:	用于播放的pcm设备,p表示playback
seq :		音序器
timer :	定时器

3.2 proc/asound

cards : 	可显示系统中存在多少个声卡
card0 : 	代表某个声卡
devices : 	可显示系统中存在多少个逻辑设备

4. PCM中间层

        PCM中间层(pcm.c)主要完成一些公共性的事情, 这些事情一般与具体的硬件无关(例如存储音频数据时, 肯定需要一个Buffer, 这个Buffer很显然用环形缓冲区描述比较好, 怎么管理这个环形缓冲区的读写指针?

        另外, 用户空间设置的音频参数要检查其合法性. 还有, 用户空间可能启停音频播放/录制, 这意味着我们最好实现一个状态机, 来管理用户空间的切换操作. 等等). 对于与具体硬件相关的操作,PCM中间层会pass给底层驱动去处理(这就意味着PCM中间层要定义interface, 让底层驱动去实现这些interface);

        底层驱动(具体的platform或codec)则处理与具体硬件相关的事情, 例如I2S控制器的配置, Codec芯片的配置, 时钟的初始化等等。

以上是关于Linux音频子系统 - ALSA ASoC的主要内容,如果未能解决你的问题,请参考以下文章

Linux ALSA声卡驱动之五:移动设备中的ALSA(ASoC)

linux 音频子系统代码分析

音频ALSA架构简介

Linux ALSA驱动之五:Linux ALSA驱动之Platform源码分析(基于Linux 5.18)

Linux ALSA驱动之Platform源码分析(wm8350.c)

Linux ALSA驱动之Platform源码分析(wm8350.c)