一、ALSA音频架构简单介绍
ALSA是Advanced Linux Sound Architecture,高级Linux声音架构的简称,它在Linux操作系统上提供了音频和MIDI(Musical Instrument Digital Interface,音乐设备数字化接口)的支持。在2.6系列内核中,ALSA已经成为默认的声音子系统,用来替换2.4系列内核中的OSS(Open Sound System。开放声音系统)。ALSA的主要特性包含:高效地支持从消费类入门级声卡到专业级音频设备全部类型的音频接口,全然模块化的设计。 支持对称多处理(SMP)和线程安全。对OSS的向后兼容,以及提供了用户空间的alsa-lib库来简化应用程序的开发。
ALSA是一个全然开放源码的音频驱动程序集,除了像OSS那样提供了一组内核驱动程序模块之外,ALSA还专门为简化应用程序的编写提供了对应的函数库,与OSS提供的基于ioctl的原始编程接口相比。ALSA函数库使用起来要更加方便一些。利用该函数库,开发人员能够方便快捷的开发出自己的应用程序,细节则留给函数库内部处理。当然 ALSA也提供了类似于OSS的系统接口,只是ALSA的开发人员建议应用程序开发人员使用音频函数库而不是驱动程序的API。
二、Alsa-Lib 移植
1、下载地址:
2、编译
(1)使用tar -jxvf alsa-lib-1.2.2.tar.bz2解压,生成alsa-lib-1.2.2文件夹;
#tar -jxvf alsa-lib-1.2.2.tar.bz2
(2)alsa-lib-1.2.2目录下执行
# ./configure --host=aarch64-linux-gnu-gcc --prefix=$PWD/_install
--host=aarch64-linux-gnu-gcc为交叉编译工具;
---prefix=$PWD/_install为交叉编译完成目标库文件生成的目录,包括库文件和头文件;
(3)编译
#make
(4)安装
#make install
(5)编译完成在alsa-lib-1.2.2/_install目录下生成库文件lib,头文件include;
3、注意
上面编译出来的只有动态库,软件需要静态库,可以把第二步修改为:
./configure --host=aarch64-linux-gnu-gcc --prefix=$PWD/_install --enable-static=yes --enable-shared=no
重新编译就行。
三、Alsa-Utils工具移植
1、下载地址:
2、编译
(1)使用tar -jxvf alsa-utils-1.2.2.tar.bz2解压,生成alsa-utils-1.2.2文件夹;
#tar -jxvf alsa-utils-1.2.2.tar.bz2
(2)alsa-utils-1.2.2目录下执行
#./configure --host=aarch64-linux-gnu-gcc
CPPFLAGS=-I$(pwd)/../alsa-lib-1.2.2/_install/include/
LDFLAGS=-L$(pwd)/../alsa-lib-1.2.2/_install/lib
--prefix=$(pwd)/_install --disable-alsamixer --disable-xmlto
--host=aarch64-linux-gnu-gcc为交叉编译工具;
CPPFLAGS和LDFLAGS为上面编译alsa-lib的头文件和库路径
---prefix=$PWD/_install为交叉编译完成目标库文件生成的目录,包括库文件和头文件;
(3)编译
#make
(4)安装
#make install
(5)编译完成在alsa-utils-1.2.2/_install目录下生成bin sbin share;
bin目录下包含一些基于ALSA的用于控制声卡的应用程序:
alsaconf - 侦测系统中声卡并写一个适合的ALSA配置文件
alsactl - 控制ALSA声卡驱动的高级设置
alsamixer - 基于窗口菜单ncurses的混音器程序
amidi - 用于读写ALSA RawMIDI
amixer - ALSA声卡混音器的命令行控制
aplay - 基于命令行的声音文件播放
arecord - 基于命令行的声音文件录制
四、ALsa在嵌入式设备的应用
1、把上面编译出来的库文件、配置环境文件、控制声卡的应用程序拷贝到嵌入式设备中;
2、arecord 录音
1)查看录音设备
# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: xxsndcard [xx-snd-card], device 1: TDM_Capture (*) []
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: xxsndcard [xx-snd-card], device 2: DMIC_Capture (*) []
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: xxsndcard [xx-snd-card], device 3: AWB_Record (*) []
Subdevices: 1/1
Subdevice #0: subdevice #0
通过如上命令可以得到可用于录音的设备,比如card x device x
2)录音
根据上面的信息,如果我们要用TDM_Capture 录音,可以输入如下命令
arecord -Dhw:0,1 -d 10 -f cd -r 44100 -c 2 -t wav test.wav
参数解析
-D 指定了录音设备,0,1 是card 0 device 1的意思,也就是TDM_Capture
-d 指定录音的时长,单位时秒
-f 指定录音格式,通过上面的信息知道只支持 cd cdr dat
-r 指定了采样率,单位时Hz
-c 指定channel 个数
-t 指定生成的文件格式
2、aplay 播放
1)查看播放音频设备
/# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: xxsndcard [xx-snd-card], device 0: I2S8CH Playback (*) []
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: xxsndcard [xx-snd-card], device 6: DL1_Playback (*) []
Subdevices: 1/1
Subdevice #0: subdevice #0
通过如上命令可以得到可用于播放声音的设备,比如card x device x
2)播放音频
# aplay test.wav
Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
直接输入aplay test.wav 就可以播放wav音频文件了,不需要指定太多的参数,因为wav文件的头部会保存一些声音格式信息,比如pcm格式 ,采样率,channel个数等,所以不指定这些参数也能播放。
如果是直接播放pcm数据,则需要指定pcm格式 、采样率、channel个数等。
3) arecord -Dhw:0,2 -r48000 -f S32_LE -c 2 | aplay -Dhw:0,1 -r48000//一边采集一边播放
3、amixer 配置
# amixer --help
Usage: amixer <options> [command]
Available options:
-h,--help this help
-c,--card N select the card
-D,--device N select the device, default 'default'
-d,--debug debug mode
-n,--nocheck do not perform range checking
-v,--version print version of this program
-q,--quiet be quiet
-i,--inactive show also inactive controls
-a,--abstract L select abstraction level (none or basic)
-s,--stdin Read and execute commands from stdin sequentially
Available commands:
scontrols show all mixer simple controls
scontents show contents of all mixer simple controls (default command)
sset sID P set contents for one mixer simple control
sget sID get contents for one mixer simple control
controls show all controls for given card
contents show contents of all controls for given card
cset cID P set control contents for one control
cget cID get control contents for one control
1).再看看当前你的音频系统(不同的音频驱动对应不同的内容和操作接口)提供了那些供你使用的接口去操作
关于驱动里面已经提供了多少接口可以去操作,可以用命令:
# amixer controls
numid=3,iface=MIXER,name='Master Mode Switch'
numid=29,iface=MIXER,name='Master Mux'
numid=4,iface=MIXER,name='Master Quality Switch'
numid=2,iface=MIXER,name='Master Switch'
numid=1,iface=MIXER,name='Master Volume'
numid=7,iface=MIXER,name='PCM Mode Switch'
numid=6,iface=MIXER,name='PCM Switch'
numid=5,iface=MIXER,name='PCM Volume'
numid=21,iface=MIXER,name='Line Input Switch'
numid=16,iface=MIXER,name='Line Mode Switch'
numid=27,iface=MIXER,name='Line Mux'
。。。。。
numid=9,iface=MIXER,name='Mic Switch'
numid=8,iface=MIXER,name='Mic Volume'
numid=19,iface=MIXER,name='ADC Mode Switch'
numid=28,iface=MIXER,name='ADC Mux'
。。。。。。。。
去查看,当然你的Linux内核支持哪些配置参数,如上,一共有20多个参数可供你配置。
而对于所有的当然的配置的值,可以通过这个查看:
# amixer contents
numid=3,iface=MIXER,name='Master Mode Switch'
; type=ENUMERATED,access=rw------,values=1,items=2
; Item #0 'Common Buffer Off'
; Item #1 'Common Buffer On'
: values=0
。。。。。。。。。。
numid=5,iface=MIXER,name='PCM Volume'
; type=INTEGER,access=rw---R--,values=2,min=0,max=27,step=0
: values=27,27
| dBscale-min=-40.50dB,step=1.50dB,mute=0
numid=24,iface=MIXER,name='Mixer ADC Mix Switch'
; type=BOOLEAN,access=rw------,values=1
: values=off
numid=26,iface=MIXER,name='Mixer DAC Mix Switch'
; type=BOOLEAN,access=rw------,values=1
: values=on
numid=25,iface=MIXER,name='Mixer Line Mix Switch'
; type=BOOLEAN,access=rw------,values=1
: values=on
numid=23,iface=MIXER,name='Mixer Mic Mix Switch'
; type=BOOLEAN,access=rw------,values=1
: values=on
2).搞懂如何去设置某个参数
总结起来就是,先要用get系列命令去看懂有哪些接口,然后再去用set系列的命令,去设置对应你所要设置的值。
想要针对某项设置,比如想要设置上面的的主音量,master volume,即controls中显示的:
numid=5,iface=MIXER,name='PCM Volume'
那么,可以先看看当前的值:
# amixer cget numid=5,iface=MIXER,name='PCM Volume'
numid=5,iface=MIXER,name='PCM Volume'
; type=INTEGER,access=rw---R--,values=2,min=0,max=27,step=0
: values=27,27
| dBscale-min=-40.50dB,step=1.50dB,mute=0
显示的是最大的27,假设想要设置为25,那么就用cset去设置:
# amixer cset numid=5,iface=MIXER,name='PCM Volume' 25
numid=5,iface=MIXER,name='PCM Volume'
; type=INTEGER,access=rw---R--,values=2,min=0,max=27,step=0
: values=25,25
| dBscale-min=-40.50dB,step=1.50dB,mute=0
再比如,去将'Mic Supply 的switch关闭:
# amixer cset numid=12,iface=MIXER,name='Mic Supply Switch'Off
numid=12,iface=MIXER,name='Mic Supply Switch'
; type=ENUMERATED,access=rw------,values=1,items=2
; Item #0 'On'
; Item #1 'Off'
: values=1
总结一下用法,就是:
amixer cget controls中所输出的某个参数
amixer cset controls中所输出的某个参数 具体的值(比如,0,1,On,Off等)
【提示】
同上面介绍的的cget/cset系列命令:
controls show all controls for given card
contents show contents of all controls for given card
cset cID P set control contents for one control
cget cID get control contents for one control
类似的,还有另外一套sget/sset系列的命令:
scontrols show all mixer simple controls
scontents show contents of all mixer simple controls (default command)
sset sID P set contents for one mixer simple control
sget sID get contents for one mixer simple control
也是同样做法,比如:
通过查看当然有哪些选择可以控制:
# amixer scontrols
Simple mixer control 'Master',0
Simple mixer control 'Master Mode',0
Simple mixer control 'Master Mux',0
Simple mixer control 'Master Quality',0
。。。
同理,amixer scontents,可以查看当前所有的值,具体就不在这列举了。
另外,去查看或者配置用sget,比如:
# amixer sget 'Microphone Input',0
Simple mixer control 'Microphone Input',0
Capabilities: pswitch pswitch-joined
Playback channels: Mono
Mono: Playback [off]
如果想要修改对应设置,用amixer sset ,具体用法是:
amixer sset sID(控制字符串) P(支持的某个值)
其中sID,就是上面的Simple mixer control后面的那个字符串,比如'Master Mux',0
而对其设置就是,先看看其提供了哪些供你设置的值:
# amixer sget 'Master Mux',0
Simple mixer control 'Master Mux',0
Capabilities: enum
Items: 'Sum' 'DAC' 'Line' 'Mic'
Item0: 'DAC'
然后比如要设置成Line的,就可以这样:
# amixer sset 'Master Mux',0Line
Simple mixer control 'Master Mux',0
Capabilities: enum
Items: 'Sum' 'DAC' 'Line' 'Mic'
Item0: 'Line'