1、概述
ALSA是Advanced Linux Sound Architecture 的缩写,目前已经成为了linux的主流音频体系结构,想了解更多的关于ALSA的这一开源项目的信息和知识,请查看以下网址:http://www.alsa-project.org/。
在内核设备驱动层,ALSA提供了alsa-driver,同时在应用层,ALSA为我们提供了alsa-lib,应用程序只要调用alsa-lib提供的API,即可以完成对底层音频硬件的控制。
图 1.1 alsa的软件体系结构
由图1.1可以看出,用户空间的alsa-lib对应用程序提供统一的API接口,这样可以隐藏了驱动层的实现细节,简化了应用程序的实现难度。内核空间中,alsa-soc其实是对alsa-driver的进一步封装,它针对嵌入式设备提供了一些列增强的功能。本系列博文仅对嵌入式系统中的alsa-driver和alsa-soc进行讨论。
下图为更详细的alsa软件体系结构图:
- ALSA Library API: alsa 用户库接口,常见有 tinyalsa、alsa-lib;
- ALSA CORE: alsa 核心层,向上提供逻辑设备(PCM/CTL/MIDI/TIMER/…)系统调用,向下驱动硬件设备(Machine/I2S/DMA/CODEC);
- ASoC CORE: asoc 是建立在标准 alsa core 基础上,为了更好支持嵌入式系统和应用于移动设备的音频 codec 的一套软件体系;
- Hardware Driver: 音频硬件设备驱动,由三大部分组成,分别是 Machine、Platform、Codec。
ALSA 标准是一个先进的 linux 声音体系。它包含内核驱动集合, API 库和工具对 Linux 声音进行支持。 ALSA 包含一系列内核驱动对不同的声卡进行支持,还提供了 libasound 的 API 库。用这些进行写程序不需要打开设备等操作,所以编程人员在写程序的时候不会被底层的东西困扰。与此相反 OSS/Free 驱动在内核层次调用,需要指定设备名和调用 ioctl 。为提供向后兼容, ALSA 提供内核模块模仿 OSS/Free 驱动,所以大多数的程序不需要改动。 ALSA 拥有调用插件的能力对新设备提供扩展,包括那些用软件模拟出来的虚拟设备。 ALSA 还提供一组命令行工具包括 mixer, sound file player 和工具控制一些特别的声卡的特别的作用。
2、分层及特点
ALSA体系主要分为三层,按照调用关系依次是,app、alsa-lib、kernel driver。
ALSA的主要特点如下:
- 支持多种声卡设备。
- 模块化的内核驱动程序。
- 支持SMP和多线程。
- 提供应用开发函数库以简化应用程序开发。
- 支持OSS API,兼容OSS应用程序。
ALSA具有更加友好的编程接口,并且完全兼容于OSS,对应用程序来讲无疑是一个更佳地选择。ALSA系统包括驱动包alsa-driver
,开发包alsa-libs
,开发包插件alsa-libplugins
,设置管理工具包alsa-utils
,其他声音相关处理小程序包alsa-tools
,特殊音频固件支持包alsa-firmware
,OSS接口兼容模拟层工具alsa-oss
共7个子项目,其中只有驱动包是必须的。
alsa-driver
指内核驱动程序,包括硬件相关的代码和一些公共代码,非常庞大。
alsa-libs
指用户空间的函数库,提供给应用程序使用,应用程序应包括头文件asoundlib.h。并使用共享库libasound.so。
alsa-utils
包含一些基于ALSA的用于控制声卡的应用程序,如alsaconf(侦测系统中声卡并写一个适合的ALSA配置文件),aplay(基于命令行的声音文件播放),arecord(基于命令行的声音文件录制)等。
3、 Kernel Driver层
Kernel driver 层,为内核驱动代码,主要在内核源码中的sound
目录下,负责对硬件进行控制与操作。驱动创建的设备文件,在文件系统中的/dev/snd/
目录下。注意,应用层使用alsa-API中打开的设备文件,并不是/dev/snd/目录下的文件,而是alsa-lib对设备的再一次封装的产物,叫做plugins
,如plughw:0,0 ,后面详细解释。
3.1 ALSA驱动的设备文件结构—字符设备
下面是我的电脑中alsa驱动的设备文件结构:
我们可以看到以下设备文件:
controlC0 --> 用于声卡的控制,例如通道选择,混音,麦克风的控制等
midiC0D0 --> 用于播放midi音频
pcmC0D0c --> 用于录音的pcm设备
pcmC0D0p --> 用于播放的pcm设备
seq --> 音序器
timer --> 定时器
其中,pcmC0D0p与pcmC0D0c组成一个pcm设备,C0代表0号声卡Card,D0代表0号设备device。C0D0代表的是声卡0中的设备0,pcmC0D0c最后一个c代表capture
,pcmC0D0p最后一个p代表playback
,这些都是alsa-driver中的命名规则。从上面的列表可以看出,我的声卡下挂了14个设备,根据声卡的实际能力,驱动实际上可以挂上更多种类的设备,在include/sound/core.h中,定义了以下设备类型:
#define SNDRV_DEV_TOPLEVEL ((__force snd_device_type_t) 0)
#define SNDRV_DEV_CONTROL ((__force snd_device_typ