CFSection9's Studio.

Linux_ALSA_Audio_Info

字数统计: 1.6k阅读时长: 7 min
2020/03/25 Share

/dev/snd

这里放着应用程序可以使用的所有ALSA Hardware sound device file。这些设备文件供应用程序执行声音操作,例如录音,播放,更改音量,获取定时信息等。通常,设备文件的格式为aaaCxDy,aaa是服务名称,x是声卡编号,y是设备编号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ECHO_PC:~$ ls -l /dev/snd/
total 0
drwxr-xr-x 2 root root 80 3月 1 11:11 by-path
crw-rw----+ 1 root audio 116, 2 3月 1 11:11 controlC0
crw-rw----+ 1 root audio 116, 7 3月 1 11:11 controlC1
crw-rw----+ 1 root audio 116, 6 3月 1 11:11 hwC0D0
crw-rw----+ 1 root audio 116, 12 3月 1 11:11 hwC1D0
crw-rw----+ 1 root audio 116, 4 3月 1 11:58 pcmC0D0c
crw-rw----+ 1 root audio 116, 3 3月 1 11:58 pcmC0D0p
crw-rw----+ 1 root audio 116, 5 3月 1 11:11 pcmC0D2c
crw-rw----+ 1 root audio 116, 8 3月 1 11:58 pcmC1D3p
crw-rw----+ 1 root audio 116, 9 3月 1 11:58 pcmC1D7p
crw-rw----+ 1 root audio 116, 10 3月 1 11:58 pcmC1D8p
crw-rw----+ 1 root audio 116, 11 3月 1 11:58 pcmC1D9p
crw-rw----+ 1 root audio 116, 1 3月 1 11:11 seq
crw-rw----+ 1 root audio 116, 33 3月 1 11:11 timer

/dev/snd/controlCx

control devices (i.e. mixer, etc.)

/dev/snd/pcmCxDyp or /dev/snd/pcmCxDyc

如上面所讲,x代表sound_card_number,y代表device_number,p代表playback,c代表capture,同一声卡的不同device可以被独立地使用。PCM设备(内核level)可以简单地分为”输出(playback)”和”输入(capture)”两类。其中的方向是站在ALSA应用的角度而言,举几个例子:
pcmC0D0c代表:sound_card_number=0的device_number=0的cpature设备文件。
pcmC0D0p代表:sound_card_number=0的device_number=0的playback设备文件。
pcmC0D1p代表:sound_card_number=0的device_number=1的playback设备文件。
PCM输出设备接收从ALSA应用传入的数据,再到mixer(CTL设备),然后路由至输出socket,外接的物理声卡设备(或者路由到别的PCM输入设备)
PCM输入设备将数据通过socket从物理声卡设备(或者经由mixer从别的PCM输出设备)读入,传入ALSA应用。

/dev/snd/seq

sequencer device

/dev/snd/timer

timer device

/proc/asound

/proc信息一般用来记录kernel driver的运行状态。在asound下面暴露了ASLA driver所提供出来的重要信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
ECHO_PC:~$ tree /proc/asound/
/proc/asound/
├── card0 ->声卡0的信息
│   ├── codec#0
│   ├── id
│   ├── pcm0c
│   │   ├── info
│   │   └── sub0
│   │   ├── hw_params
│   │   ├── info
│   │   ├── prealloc
│   │   ├── prealloc_max
│   │   ├── status
│   │   └── sw_params
│   ├── pcm0p
│   │   ├── info
│   │   └── sub0
│   │   ├── hw_params
│   │   ├── info
│   │   ├── prealloc
│   │   ├── prealloc_max
│   │   ├── status
│   │   └── sw_params
│   └── pcm2c
│   ├── info
│   └── sub0
│   ├── hw_params
│   ├── info
│   ├── prealloc
│   ├── prealloc_max
│   ├── status
│   └── sw_params
├── card1 ->声卡1的信息
│   ├── codec#0
│   ├── eld#0.0
│   ├── eld#0.1
│   ├── eld#0.2
│   ├── eld#0.3
│   ├── id
│   ├── pcm3p
│   │   ├── info
│   │   └── sub0
│   │   ├── hw_params
│   │   ├── info
│   │   ├── prealloc
│   │   ├── prealloc_max
│   │   ├── status
│   │   └── sw_params
│   ├── pcm7p
│   │   ├── info
│   │   └── sub0
│   │   ├── hw_params
│   │   ├── info
│   │   ├── prealloc
│   │   ├── prealloc_max
│   │   ├── status
│   │   └── sw_params
│   ├── pcm8p
│   │   ├── info
│   │   └── sub0
│   │   ├── hw_params
│   │   ├── info
│   │   ├── prealloc
│   │   ├── prealloc_max
│   │   ├── status
│   │   └── sw_params
│   └── pcm9p
│   ├── info
│   └── sub0
│   ├── hw_params
│   ├── info
│   ├── prealloc
│   ├── prealloc_max
│   ├── status
│   └── sw_params
├── cards ->保存了所有可用的声卡信息
├── devices ->保存了所有可用的设备信息
├── hwdep ->保存了所有可用的hwdep设备信息
├── modules ->
├── NVidia -> card1
├── oss
│   ├── devices ->保存了所有可用的OSS设备信息
│   └── sndstat
├── PCH -> card0
├── pcm ->保存了所有可用的pcm设备信息
├── seq
│   ├── clients
│   ├── drivers
│   ├── queues
│   └── timer
├── timers
└── version ->ALSA driver的版本和编译日期

ALSA世界中,物理的声卡设备由card, device, subdevice指定。

/proc/asound/cards

保存了所有注册的声卡信息。格式为:
index [the id string]: short and long descriptions.

1
2
3
4
5
ECHO_PC:/proc/asound$ cat cards
0 [PCH ]: HDA-Intel - HDA Intel PCH
HDA Intel PCH at 0x43ffff30000 irq 59
1 [NVidia ]: HDA-Intel - HDA NVidia
HDA NVidia at 0xb8080000 irq 60

我们可以看到一张声卡设备它可以由字符串或者从0开始的整数表示。

/proc/asound/devices

保存了所有注册的设备信息,和/dev/snd/下面的设备是同一个内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ECHO_PC:/proc/asound$ cat devices
1: : sequencer
2: [ 0] : control
3: [ 0- 0]: digital audio playback
4: [ 0- 0]: digital audio capture
5: [ 0- 2]: digital audio capture
6: [ 0- 0]: hardware dependent
7: [ 1] : control
8: [ 1- 3]: digital audio playback
9: [ 1- 7]: digital audio playback
10: [ 1- 8]: digital audio playback
11: [ 1- 9]: digital audio playback
12: [ 1- 0]: hardware dependent
33: : timer

/proc/asound/hwdep

保存了目前所有可以使用的hwdep设备信息,格式为:
<card>-<device>: <name>

1
2
3
ECHO_PC:/proc/asound$ cat hwdep
00-00: HDA Codec 0
01-00: HDA Codec 0

/proc/asound/modules

注意前面的编号,这里决定了modules的优先级。

1
2
3
dowang@cocmedia-ThinkStation-P720:/proc/asound$ cat modules
0 snd_hda_intel
1 snd_hda_intel

/proc/asound/pcm

保存了目前所有可以使用的pcm设备信息,格式为:
<card>-<device>: <id>: <name> : <sub-streams>

1
2
3
4
5
6
7
dowang@cocmedia-ThinkStation-P720:/proc/asound$ cat pcm
00-00: ALC662 rev3 Analog : ALC662 rev3 Analog : playback 1 : capture 1
00-02: ALC662 rev3 Alt Analog : ALC662 rev3 Alt Analog : capture 1
01-03: HDMI 0 : HDMI 0 : playback 1
01-07: HDMI 1 : HDMI 1 : playback 1
01-08: HDMI 2 : HDMI 2 : playback 1
01-09: HDMI 3 : HDMI 3 : playback 1

/proc/asound/timers

保存了目前所有可以使用的timer设备信息.

1
2
3
4
5
6
7
8
9
dowang@cocmedia-ThinkStation-P720:/proc/asound$ cat timers
G0: system timer : 4000.000us (10000000 ticks)
P0-0-0: PCM playback 0-0-0 : SLAVE
P0-0-1: PCM capture 0-0-1 : SLAVE
P0-2-1: PCM capture 0-2-1 : SLAVE
P1-3-0: PCM playback 1-3-0 : SLAVE
P1-7-0: PCM playback 1-7-0 : SLAVE
P1-8-0: PCM playback 1-8-0 : SLAVE
P1-9-0: PCM playback 1-9-0 : SLAVE

/proc/asound/cardx/pcmxx/info

此PCM设备的一般信息.

1
2
3
4
5
6
7
8
9
10
11
12
one@ubuntu:/proc/asound$ cat card0/pcm0c/info
card: 0
device: 0
subdevice: 0
stream: CAPTURE
id: ALC662 rev3 Analog
name: ALC662 rev3 Analog
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 1

/proc/asound/cardx/pcmxx/sub0/sw_params

为此子流设置的软件参数.

1
2
3
4
5
6
7
8
tstamp_mode: ENABLE
period_step: 1
avail_min: 1024
start_threshold: 2048
stop_threshold: 2048
silence_threshold: 0
silence_size: 0
boundary: 4611686018427387904

软件参数可以在任意时刻修改,包括RUNNING状态.
avail_min:默认值一般为period size, 用于snd_pcm_wait, 当available的值大于avail_min时,snd_pcm_wait函数才会返回。
start threshold:PCM设备状态自动进入RUNNING的事件。注意:
只对readi/writei有效,对于 direct access 无效

/proc/asound/cardx/pcmxx/sub0/hw_params

为此子流设置的硬件参数.

1
2
3
4
5
6
7
access: MMAP_INTERLEAVED
format: S32_LE
subformat: STD
channels: 8
rate: 48000 (48000/1)
period_size: 1024
buffer_size: 2048

ALSA PCM设备对于硬件参数,使用了一种”逐步限制”的机制(refinement system) - snd_pcm_hw_params_t. 应用程序在一开始设定所有支持的HW参数空间,然后通过设置其中的某几个参数为定值,直到其他参数都被限定为止。最后,将设定好了的参数空间install给该设备(snd_pcm_hw_params)。之后,HW参数就不得再改变了。

/proc/asound/cardx/pcmxx/sub0/status

该PCM子流的当前状态.

1
2
3
4
5
6
7
8
9
10
state: RUNNING
owner_pid : 2882 ->占用当前pcm设备的pid号,可以用 "ps -A|grep 2282"来查看进程的名字。
trigger_time: 4.894258624 ->It is the kernel time when the pcm device is opened
tstamp : 107.766229168 ->is the kernel time when cat this status
delay : 96
avail : 96
avail_max : 96
-----
hw_ptr : 4937824 ->If it is a playback node, it is a hardware read point.
appl_ptr : 4937728 ->If it is a playback node, it is a application write point.

PCM的state状态机如下图示:

CATALOG
  1. 1. /dev/snd
    1. 1.1. /dev/snd/controlCx
    2. 1.2. /dev/snd/pcmCxDyp or /dev/snd/pcmCxDyc
    3. 1.3. /dev/snd/seq
    4. 1.4. /dev/snd/timer
  2. 2. /proc/asound
    1. 2.1. /proc/asound/cards
    2. 2.2. /proc/asound/devices
    3. 2.3. /proc/asound/hwdep
    4. 2.4. /proc/asound/modules
    5. 2.5. /proc/asound/pcm
    6. 2.6. /proc/asound/timers
    7. 2.7. /proc/asound/cardx/pcmxx/info
    8. 2.8. /proc/asound/cardx/pcmxx/sub0/sw_params
    9. 2.9. /proc/asound/cardx/pcmxx/sub0/hw_params
    10. 2.10. /proc/asound/cardx/pcmxx/sub0/status