alsa概述
alsa(Advanced Linux Sound Architecture )是目前linux的主流音频体系结构,在 Linux 内核设备驱动层,ALSA 提供了 alsa-driver,在应用层,ALSA 为我们提供了 alsa-lib,故在其支持下,Linux 应用程序只需要调用 alsa-lib 提供的 API,即可完成对底层音频硬件的控制。
alsa驱动的代码文件结构
在Linux2.6代码树中,Alsa的代码文件结构如下:
sound
/core
/oss
/seq
/ioctl32
/include
/drivers
/i2c
/synth
/emux
/pci
/(cards)
/isa
/(cards)
/arm
/ppc
/sparc
/usb
/pcmcia /(cards)
/oss
/soc
/codecs
core 该目录包含了ALSA驱动的中间层,它是整个ALSA驱动的核心部分
core/oss 包含模拟旧的OSS架构的PCM和Mixer模块
core/seq 有关音序器相关的代码
include ALSA驱动的公共头文件目录,该目录的头文件需要导出给用户空间的应用程序使用,通常,驱动模块私有的头文件不应放置在这里
drivers 放置一些与CPU、BUS架构无关的公用代码
i2c ALSA自己的I2C控制代码
pci pci声卡的顶层目录,子目录包含各种pci声卡的代码
isa isa声卡的顶层目录,子目录包含各种isa声卡的代码
soc 针对system-on-chip体系的中间层代码
soc/codecs 针对soc体系的各种codec的代码,与平台无关
alsa常用命令
主要有两个角度一个是控制系统实现录音和播音功能(比如aplay和mplayer等播放器),另一个是amixer cset控件(相当于OSS驱动中的/dev/mixer设备节点的操作,可以调节录放音的音量,静音,录放音通道切换等)。下面介绍几个常用的接口操作方法,更详细的alsa接口查询可以看这篇文章:
1、snd_pcm_open(&handle, pcm_name, stream, open_mode);
&handle,是static snd_pcm_t *handle;该结构体指针,在后面的所有操作中,都要用到。
pcm_name,是打开的pcm设备节点,可以是“default” ,也可以是“hw:0,0”。具体有何区别,可网上查询。
stream,对应放音与录音操作,SND_PCM_STREAM_PLAYBACK,SND_PCM_STREAM_CAPTURE。
open_mode,是一些相关功能设置,比如:是否阻塞,是否重采样,是否软件调音量等。
2、snd_pcm_info(handle, info);
一般用来获取录放音 声卡与设备等相关信息。不是必须的接口。
3、snd_pcm_hw_params_alloca(¶ms);
申请一段snd_pcm_hw_params_t *params;结构体空间。使用该结构体,来配置底层ALSA的相关硬件参数,比如:声道,采样率,位宽,buffer大小等。
stream == SND_PCM_STREAM_PLAYBACK
playback(argv[optind++])—>playback_go(fd, 0, pbrec_count, FORMAT_AU, name)—>set_params()–>snd_pcm_hw_params_alloca
4、snd_pcm_hw_params_set_format(handle, params, hwparams.format);设置采样位宽格式。
5、snd_pcm_hw_params_set_channels(handle, params, hwparams.channels);设置声道数。
6、snd_pcm_hw_params_set_rate_near(handle, params, &hwparams.rate, 0);设置采样率,之所以是rate_near,是因为上层设置的采样率&hwparams.rate,底层很可能不支持,因此,会返回上层一个底层支持的相近的采样率。
7、snd_pcm_sw_params(handle, swparams);将上面的软件参数,加载到底层。
完成上面的各种参数的设置后就可以开始从声卡中读取或者写入音频文件了。
8、snd_pcm_writei(snd_pcm_t *pcm, const void buffer, snd_pcm_uframes_t size);播放交错格式的音频数据。snd_pcm_t pcm为snd_pcm_open时得到的。size,这里不是字节数,不是采样点数。而是采样帧数。双声道,一帧采样,有两个采样点。ALSA上层接口,一般都是以采样帧数为单位的,
snd_pcm_readi(snd_pcm_t pcm, void buffer, snd_pcm_uframes_t size);录制交错格式的音频数据。参数与上相同。
snd_pcm_writen与snd_pcm_readn,与上面两个函数,基本相同,只是录放音数据的格式是非交错的。既一帧数据,只包含一个声道数据,交错格式指,一帧数据中,包含了多个声道的数据。比如:双声道一帧数据中,包含了左声道与右声道,各一个采样点。 交错指的是:同一时间采的一帧数据中,包含左右两个声道或多声道的采样点。非交错指的是:同一时间采的一帧数据中,只包含一个声道。
ALSA中的 amixer cset控件接口操作,可参考alsa utils源码中的amixer.c:上层amixer程序,调用ALSA lib中的标准接口函数,操作/dev/controlC0设备(主要使用了ioctl接口),来完成对底层codec_.c中kcontrol的一些操作。在内核kernel /sound /core /control.c中,定义了struct file_operations snd_ctl_f_ops,该operation会注册/dev/controlC设备的file operations。
查看声卡命令:
cat /proc/asound/cards
录音:
arecord -D hw:0,0 -c 2 -r 44100 -f S16_LE test.wav
播放:
aplay -Dplughw:0,0 test.wav
打开耳机功能:
amixer cset numid=1,iface=MIXER,name=‘Playback Path’ 3
音频信息介绍
PCM(Pulse Code Modulation),即脉冲编码调制技术。PCM技术就是把声音从模拟信号转化为数字信号的技术,即对声音进行采样、量化的过程,经过PCM处理后的数据,是最原始的音频数据,即未对音频数据进行任何的编码和压缩处理。
采样频率:单位时间内对模拟信号的采样次数,它用赫兹(Hz)来表示。采样频率越高,声音的还原就越真实越自然,当然数据量就越大。采样频率一般共分为22.05KHz、44.1KHz、48KHz三个等级。
采样位数(Sample Bits):又称为采样精度,量化级,也相当于每个采样点所能被表示的数据范围。采样位数通常有8bits或16bits两种,采样位数越大,所能记录声音的变化度就越细腻,相应的数据量就越大。8bits为低品质,16bits为高品质,16bits最为常见。
声道数(Channels):又称为通道数,指的是:能支持不同发声的音响个数,它是衡量音响设备的重要指标之一。
帧(Frame):一个声音的基本数据单元,其长度为采样位数和通道数的乘积。
周期(Period Size):音频设备一次处理所需要的帧数,对于音频设备的数据访问以及音频数据的存储,都是以此为单位。硬件缓冲传输单位,即完成这么多采样帧的传输,就会回馈一个中断。
编码:一个完整的音频,经过采样和量化后的信号,需要将它转化为数字编码脉冲,这一过程称为编码。编码简单来说,就是按一定格式记录采样和量化后的数字数据。