转自:http://blog.youkuaiyun.com/droidphone
一、 概述
ALSA是Advanced Linux Sound Architecture的缩写,目前已经成为linux的主流音频体系结构。ALSA开源项目网址:http://www.alsa-project.org/
在内核设备驱动层,ALSA提供了alsa-driver,同时在应用层,ALSA为我们提供了alsa-lib,应用程序只要调用alsa-lib提供的API,即可以完成对底层音频硬件的控制。
由上图可以看出,用户空间的alsa-lib对应用程序提供统一的API接口,这样可以隐藏驱动层的实现细节,简化
了应用程序的实现难度,内核空间中,alsa-soc其实是对alsa-driver的进一步封装,他针对嵌入式设备提供了一些增强的功能。
二、ALSA设备文件结构
在linux设备中看看alsa驱动的设备文件
root@AD700A:/dev/snd # ll
crw-rw---- system audio 116, 0 2015-01-01 15:42 controlC0
crw-rw---- system audio 116, 24 2015-01-01 15:42 pcmC0D0c
crw-rw---- system audio 116, 16 2015-01-01 15:42 pcmC0D0p
crw-rw---- system audio 116, 17 2015-01-01 15:42 pcmC0D1p
crw-rw---- system audio 116, 26 2015-01-01 15:42 pcmC0D2c
crw-rw---- system audio 116, 18 2015-01-01 15:42 pcmC0D2p
crw-rw---- system audio 116, 33 2015-01-01 15:42 timer
可以看到以下设备文件:
controlC0 用于声卡的控制,例如通道的选择,混音,麦克风的控制等
pcmC0D0c 用于录音的PCM设备0
pcmC0D0p 用于播放的PCM设备0
pcmC0D1p 用于播放的PCM设备1
pcmC0D2c 用于录音的PCM设备2
pcmC0D2p 用于播放的PCM设备2
timer 定时器
其中C0D0代表的是声卡0中的设备0,pcmC0D0c最后一个c代表capture,pcmC0D0p最后一个p代表playback,这些都是alsa-driver的命名规则。从上面的列表可以看出,我的设备下挂载了7个设备,驱动实际上可以挂上更多的设备,在include/sound/core.h中,定义了以下设备类型:
typedef int __bitwise snd_device_type_t;
#define SNDRV_DEV_TOPLEVEL ((__force snd_device_type_t) 0)
#define SNDRV_DEV_CONTROL ((__force snd_device_type_t) 1)
#define SNDRV_DEV_LOWLEVEL_PRE ((__force snd_device_type_t) 2)
#define SNDRV_DEV_LOWLEVEL_NORMAL ((__force snd_device_type_t) 0x1000)
#define SNDRV_DEV_PCM ((__force snd_device_type_t) 0x1001)
#define SNDRV_DEV_RAWMIDI ((__force snd_device_type_t) 0x1002)
#define SNDRV_DEV_TIMER ((__force snd_device_type_t) 0x1003)
#define SNDRV_DEV_SEQUENCER ((__force snd_device_type_t) 0x1004)
#define SNDRV_DEV_HWDEP ((__force snd_device_type_t) 0x1005)
#define SNDRV_DEV_INFO ((__force snd_device_type_t) 0x1006)
#define SNDRV_DEV_BUS ((__force snd_device_type_t) 0x1007)
#define SNDRV_DEV_CODEC ((__force snd_device_type_t) 0x1008)
#define SNDRV_DEV_JACK ((__force snd_device_type_t) 0x1009)
#define SNDRV_DEV_COMPRESS ((__force snd_device_type_t) 0x100A)
#define SNDRV_DEV_LOWLEVEL ((__force snd_device_type_t) 0x2000)
一般的,我们更关心pcm和control这两种设备。
三、驱动的代码文件结构
在linux2.6代码树中,ALSA的代码文件结构如下:
songchong@srv-artek-pad:~/700E/android/kernel/sound$ ls
ac97_bus.c arm core firewire isa last.c mips parisc pcmcia sh sound_core.c sparc synth
aoa atmel drivers i2c Kconfig Makefile oss pci ppc soc sound_firmware.c spi usb
core:该目录包含了LASA驱动的中间层,它是整个ALSA驱动的核心部分。
core/oss: 包含了模拟旧的OSS架构的PCM和Mixer模块
core/seq :有关音序器相关的代码
include:ALSA驱动的公共头文件目录,该目录的头文件需要导出给用户空间的应用程序。
drivers :放置一些与GPU、BUS架构无关的公用代码
i2c:ALSA自己的I2C控制代码
PCI:PCI声卡的顶层目录,子目录包含各种pci声卡代码
isa:isa声卡的顶层目录,子目录包含各种isa声卡代码
soc:针对system-on-chip体系的中间层代码
soc/codecs:针对soc体系的各种codec代码,与平台无关。