本文以I2S插口为例介绍Linux内核音频相关知识。
一、名词介绍
下边是音频调试中常见的名词缩略语。
1、AEC(AcousticEchoCancellor):回声去除。
2、AGC(AutomaticGainControl):手动增益补偿,调整MIC收音量。
3、ALSA(AdvancedLinuxSoundArchitecture):中级Linux声音构架。
4、ANS(AutomaticNoiseSuppression):背景噪声抑制,ANS可侦测出背景固定频度的响声并去除背景噪声。
5、BCK(BitClockLine):位时钟,对应数字音频的每一位数据。标准称为SCK(SerialClock),串行时钟。SCK=2x取样频度x取样位数
6、DAI(DigitalAudioInterface):数字音频插口。
7、DAPM(DynamicAudioPowerManagement):动态电源管理,DAPM可使基于linux的联通设备上的音频子系统,在任何时侯都工作在最小帧率状态。
8、DRC(DynamicRangeControl):动态压缩,将音频输出控制在一定范围内。
9、EQ(Equaliser):均衡器,通过对声音某一个或多个频段进行增益或衰减,达到调整音准的目的。
10、I2S(Inter-ICSound):IC间传输数字音频资料的一种插口标准,采用序列的形式传输2组(左右声道)资料。
11、LRCK(Left-RightClock):帧时钟,用于切换左右声道数据,0:左声道;1:右声道。标准称为WS(WorldSelect),声道选择;或称为FS(FrameSync),帧同步;LRCK的频度=取样频度。
12、MCLK(MasterClock):主时钟,通常MCLK=256*LRCK。不是I2S标准中的一部份,主要拿来同步模拟/数字转换器的内部操作。
13、Mono:单声道。
14、OSS(OpenSoundSystem):开放声音系统。
15、PCM(PulseCodeModulation):脉冲编码调制,I2S是PCM的子集。
16、ramp:逐渐降低或降低音量等级,防止声音极速变化,用于暂停或恢复音乐。
17、Stereo:双声道
18、TDM(TimeDivisionMultiplexing):时分复用。I2S最多只能传2声道数据,TDM最多支持16通道。
二、I2S插口
I2S是飞利浦定义的数字音频传输标准,用于数字音频数据在系统内部元件之间传输。
I2S是PCM的一个分支,插口定义相同。I2S的取样率通常为44.1/48KHZ,PCM取样频度通常为8/16KHZ等。
I2S插口有4组讯号:SCK(位时钟)、LRCK(帧时钟)、SDI/SDO(数据)。
在I2S总线上linux 查看声卡设备,只能同时存在一个主设备和发送设备,主设备可以是发送设备或接收设备。常见的I2S框图如下:
三、I2S合同
I2S插口常见的合同模式包括:I2S正常模式、I2S左对齐模式和I2S右对齐模式等。
1、I2S正常模式
I2S正常模式属于I2S左对齐中的一种特例,也叫Philips模式。右图是I2S正常模式的波形。
LRCK(i2s_LRCK_rx/i2s_LRCK_tx)讯号变低表示左声道RED HAT LINUX 9.0,变高表示右声道。
SD(i2s_sdo,i2s_sdi)讯号首先传输MSB或LSB,并在LRCK改变后的一个SCLK时钟周期发送第一个bit。
SD讯号长度的范围是从16到32位。
2、I2S左对齐模式
右图是I2S左对齐模式的波形。
LRCK(i2s_LRCK_rx/i2s_LRCK_tx)讯号变高表示左声道,变低表示右声道。
SD(i2s_sdo,i2s_sdi)讯号首先传输MSB或LSB,并在LRCK改变的同时发送第一个bit。
SD讯号长度的范围是从16到32位。
3、I2S右对齐模式
右图是I2S右对齐模式的波形。
LRCK(i2s_LRCK_rx/i2s_LRCK_tx)讯号变高表示左通道,变低表示右通道。
SD(i2s_sdo、i2s_sdi)讯号首先传输MSB或LSB,与I2S正常或左对齐模式不同,其数据与LRCK讯号的边沿处的最后一位对齐。
SD讯号长度范围从16到32位。
其他合同格式还有:PCMearlymode、PCMlate1mode和PCMlate2mode等。
四、ALSA框架
Linux内核2.6以后,ALSA代替了OSS成为了Linux内核音频子系统是一部份。
ALSA系统包括:
1、alsa-driver:alsa系统驱动。
2、alsa-lib:alsa库,用户空间调用,和内核空间交互。
3、alsa-utils:命令行工具。
4、alsa-plugin:alsa插件。
5、alsa-tools:alsa工具。
ALSA框架组成如下:
alsa-driver中相关功能如下(以rockchip4a单板为例):
1、Codec:音频芯片共有的部份,包括codec初始化函数,控制插口,寄存器缓存linux 查看声卡设备,控件,dapm部件,音频路由,偏置电流设置函数等描述信息。
Rockchip4A单板,Codec选用的是ES8316芯片,该芯片的dts配置如下:
2、Codecmai:codec上的音频插口驱动描述,包括:时钟配置,格式配置,能力描述等。
Codecmai相关实现如下:
3、CPUmai:指SoC的I2S、PCM总线控制器,负责把音频数据从I2StxFIFO搬运到codec。
RK3399CPUmai的dts相关配置如下:
4、DAILink:音频数据链路,它指定链路用到的codec、codec_dai、cpu_dai和platform。
Linux4.4内核支持两种方法创建声卡:一种是通用的simple-cardframework;一种是传统的编撰自定义的machinedriver来创建。
Simplecard是简单通用的machinedriver,假如simple-card框架足够满足需求,可优先选择simplecard框架。
maiLink的dts相关配置如下:
maiLink的相关实现如下:
5、DAPM:动态电源管理,是基于kcontrol改进之后的相应框架,降低了相应的电源管理机制,widget是DAPM的基本单位。
Codec(es8316)中kcontrol、dapmwidget和dapmroutes的相关实现如下:
6、DMA:负责把dmabuffer中的音频数据搬运到I2StxFIFO。
五、调试命令
ALSA是Linux处理音频的基本插口,但ALSA只提供基层的插口,操作较为繁复,通常情况下可以直接使用其附送提供的utils工具集,utils工具集是一些封装好了的功能模块,直接以命令的形式提供,用户只须要敲入相关命令和参数即可实现音频操作功能。
1、查看声卡信息
root@xiaotianbsp:~# cat /proc/asound/cards
0 [rockchipes8316c]: rockchip_es8316 - rockchip,es8316-codec
rockchip,es8316-codec
1 [HDMICODEC ]: HDMI-CODEC - HDMI-CODEC
HDMI-CODEC
root@xiaotianbsp:~# ls -l /dev/snd/
total 0
drwxr-xr-x 2 root root 80 Aug 16 14:43 by-path
crw-rw----+ 1 root audio 116, 2 Aug 16 14:43 controlC0
crw-rw----+ 1 root audio 116, 5 Aug 16 14:43 controlC1
crw-rw----+ 1 root audio 116, 4 Aug 16 14:43 pcmC0D0c
crw-rw----+ 1 root audio 116, 3 Aug 16 14:43 pcmC0D0p
crw-rw----+ 1 root audio 116, 6 Aug 16 14:43 pcmC1D0p
crw-rw----+ 1 root audio 116, 1 Aug 16 14:43 seq
crw-rw----+ 1 root audio 116, 33 Aug 16 14:43 timer
controlCx:控制插口,提供灵活的方法管理注册的声卡和对存在的声卡进行查询。
pcmCxDxc:PCM插口,对应录音设备。
pcmCxDxp:PCM插口,对应放音设备。
timer:支持声音的同步风波提供声卡上的定时器。
seq:部首器插口,一个比原始MIDI插口中级的MIDI编程和声音同步高层插口。
2、查看声卡采集、播放PCM信息
root@xiaotianbsp:~# cat /proc/asound/pcm
00-00: ff880000.i2s-ES8316 HiFi ES8316 HiFi-0 : : playback 1 : capture 1
01-00: ff8a0000.i2s-i2s-hifi i2s-hifi-0 : : playback 1
3、查看ALSA驱动版本
root@xiaotianbsp:~# cat /proc/asound/version
Advanced Linux Sound Architecture Driver Version k4.4.154-90-rockchip-ga14f6502e045.
4、查看声卡0的信息
root@xiaotianbsp:~# cat /proc/asound/card0/pcm0p/sub0/status
closed
5、查看寄存器
## regmap名称
root@xiaotianbsp:~# cat /sys/kernel/debug/regmap/1-0011/name
es8316
root@xiaotianbsp:~# cat /sys/kernel/debug/regmap/ff880000.i2s/name
rockchip-i2s
## rk3399 i2s0控制器寄存器
root@xiaotianbsp:~# cat /sys/kernel/debug/regmap/ff880000.i2s/registers
00: 0000000f
04: 0000000f
08: 00033f3f
0c: 00000000
10: 000f0010
14: 01f00000
18: XXXXXXXX
1c: 00000000
20: XXXXXXXX
28: 00000000
## es8316寄存器
root@xiaotianbsp:~# cat /sys/kernel/debug/regmap/1-0011/registers
00: c0
01: f3
02: 08
03: 20
04: 11
05: 00
06: 11
07: 00
08: 00
09: 04
0a: 0c
0b: 0c
0c: ff
0d: 3f
0e: ff
0f: ff
10: 11
11: fc
12: 28
13: 00
14: 00
15: 33
16: 00
17: 00
18: 00
6、查看时钟
## 采样率44.1KHZ,mclk = 256 * sample = 256*44.1*1000 = 11289600 HZ
root@xiaotianbsp:~# cat /sys/kernel/debug/clk/clk_summary | grep i2s0
clk_i2s0_div 1 1 800000000 0 0
clk_i2s0_frac 1 1 11289600 0 0
clk_i2s0_mux 1 1 11289600 0 0
clk_i2s0 1 2 11289600 0 0
hclk_i2s0 1 2 100000000 0 0
7、amixer命令
root@xiaotianbsp:~# amixer -h
Usage: amixer [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
-R,--raw-volume Use the raw value (default)
-M,--mapped-volume Use the mapped volume
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
7.1查看card0内容
root@xiaotianbsp:~# amixer -c 0 contents
numid=16,iface=MIXER,name='ADC Double FS Mode'
; type=BOOLEAN,access=rw------,values=1
: values=off
numid=14,iface=MIXER,name='ADC Soft Ramp'
; type=BOOLEAN,access=rw------,values=1
: values=on
numid=13,iface=MIXER,name='ADC Capture Volume'
; type=INTEGER,access=rw---R--,values=1,min=0,max=192,step=0
: values=192
| dBscale-min=-96.00dB,step=0.50dB,mute=1
numid=15,iface=MIXER,name='Capture Polarity'
; type=ENUMERATED,access=rw------,values=1,items=2
; Item #0 'Normal'
; Item #1 'Invert'
: values=0
7.2查看和配置某个numid命令
## 查看
root@xiaotianbsp:~# amixer -c 0 cget numid=16
numid=16,iface=MIXER,name='ADC Double FS Mode'
; type=BOOLEAN,access=rw------,values=1
: values=off
## 配置
root@xiaotianbsp:~# amixer -c 0 cset numid=16 on
numid=16,iface=MIXER,name='ADC Double FS Mode'
; type=BOOLEAN,access=rw------,values=1
: values=on
8、设备名
root@xiaotianbsp:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: rockchipes8316c [rockchip,es8316-codec], device 0: ff880000.i2s-ES8316 HiFi ES8316 HiFi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: HDMICODEC [HDMI-CODEC], device 0: ff8a0000.i2s-i2s-hifi i2s-hifi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
root@linaro-alip:~# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: rockchipes8316c [rockchip,es8316-codec], device 0: ff880000.i2s-ES8316 HiFi ES8316 HiFi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
9、放音
aplay -D hw:0,0 -r 44100 -c 2 -f s16_le play.wav
10、录音
arecord -D hw:0,0 -r 16000 -c 1 -f s16_le record.wav
-D:播放设备嵌入式linux培训,aplay-l或arecord-l列举的设备名
-r:取样率
-c:音频文件通道
-f:取样格式,常用的有S16_LE,S24_LE,S32_LE,cd(可忽视)
也可参考tinyalsa命令,如:tinymix、tinypcminfo、tinyplay和tinycap的用法。
11、mp3转wav
lame test.mp3 test.wav --decode