一.ALSA框架简介
ALSA表示先进linux声音架构(Advanced Linux Sound Archiecture),它由一系列的内核驱动、应用程序编程接口(API)以及支持linux下声音的应用程序组成、
ALSA项目发起的原有是linux下的声卡驱动(OSS)没有获得积极的维护,而且落后于新的声卡技术。Jaroslav Kysela早先写了一个声卡驱动,并由此开始了ALSA项目,随后,更多的开发者加入到开发队伍中,更多的声卡获得支持,API的结构也获得了重组。目前已经成为了linux的主流音频体系结构。
音频设备接口包括PCM、I2S、AC97等,分别适用于不用的应用场合。针对音频设备,linux内核中包含了两类音频设备驱动框架;
OSS:开放声音系统,包含dsp和mixer字符设备接口,应用访问底层硬件是直接通过sound设备节点实现的;
ALSA:先进linux声音架构,以card和组件(PCM、mixer等)为组件,应用是通过ALSA提供的alsa-lib库访问底层硬件的操作,不再访问sound设备节点了;本篇博客以ALSA为例,来介绍音频驱动;
二.音频硬件设备
在ALSA子系统中:
使用Platform来描述RKSOC;
使用Codec来描述解码芯片;
使用Machine来描述RKSOC与解码芯片之间的关系。
接下来我们会从硬件和软件的角度来阐述Platform、Codec、Machine。
Machine:
是指某一款机器,可以是某款设备、某款开发板、又或者是某款智能手机,由此可以看出Machine几乎是不可重用的。
每个Machine上的硬件实现可能不一样,SoC不一样、Codec不一样、音频的输入,输出设备也不一样,Machine为CPU、Codec、输入输出设备提供一个载体。
Platform:
一般是指某一个SoC平台,比如RK3399、S3C2440等等,与音频相关的通常包括SoC中的时钟、DMA、I2S、PCN、I2C等等,只要指定了SoC,那么我们可以认为他会有一个对应的Platform,它只与SoC相关,这样我们就可以把Platform抽象出来,使得同一款SoC不用做任何的改动,就可以用在不同的Machine中。实际上,把Platform当做SoC更容易理解。
Codec:
字面上的意思就是编解码器,Codec里面包含了D/A、A/D、AIF、Mixer、PA、Line-in、Line-out等,通常包含多种输入(Microphone input、Line-in、I2S、PCM等)和多个输出(Line-out、耳机等),Codec和Platform一样,是一个可以被多个Machine使用,嵌入式Codec通常通过I2C/SPI对内部的寄存器进行控制。实际上、把Codec当做声卡芯片更容易理解;
A/D:把麦克风拾取的模拟信号转换为数字信号;
D/A:把音频I2S/PCM接口传送过来的数字信号转换为模拟信号;
AIF:音频数字接口,用于Codec与SoC之间的数据传输;
Mixer:混音器,把多路输入信号混合成单路输出;
DRC:动态分为调节;
LHPF:高低通滤波;
PA:功率放大器;
三.ALSA框架
ALSA框架从上到下依次为应用程序、ALSA Library API、ALSA CORE、ASoC CORE、硬件驱动程序、硬件设备;
应用程序:tinyplay/tinycap/tinymix,这些用户程序直接调用alsa用户库接口来实现放音、录音、控制;
ALSA Library API:alsa用户库接口,对应用程序提供统一的API接口,这样可以隐藏了驱动层的实现细节,简化了应用程序的实现难度;常见有tinyalsa、alsa-lib;
ALSA CORE:alsa核心层,向上提供逻辑设备(PCM/CTL/MIDI/TIMER/…)系统调用,向下驱动硬件设备(Machine/I2S/DMA/CODEC);
ASoC CORE:建立在标准ALSA CORE基础上,为了更好支持嵌入式系统和应用于移动设备的音频Codec的一套软件体系,它将音频硬件设备驱动划分为Codec、Platform 和 Machine;
Hardware Driver:音频硬件设备驱动,由三大部分组成,分别是 Machine、Platform、Codec;
以前我们总提到,写上层应用程序的人,不应该关系硬件的实现,所以我们会给硬件写一个驱动,然后写应用程序的人直接调用驱动就可以访问硬件了,具体如下:
简单的应用程序是没有问题的,但是一些复杂的硬件还是不行,应用程序需要了解很多驱动的接口,于是就进行了改进。
在驱动和APP之间添加一些库,APP去访问那些库,进而访问驱动。这些库封装了声卡复杂的使用方法,对于音频系统,库lib有两种选择,一种是alsa-lib,以及alsa-lib的简化版本tinyalsa。
ALSA驱动源码:
其中:
i2c:存放的是ALSA自己的I2C控制代码;
core:是ALSA驱动的中间层,它是整个ALSA驱动的核心层;
drivers:存放一些与CPU、BUS架构无关的公共代码;
pci:pci声卡的顶层目录,子目录包含各种pci声卡的代码;
isa:isa声卡的顶层目录,子目录包含各种isa声卡的代码;
soc:针对ASoC体系的中间层代码;