3. PCM设备参数详解:采样率、位深、通道数、缓冲区大小、周期大小
好,咱们今天来聊聊PCM设备的几个核心参数。说实话,我刚开始接触ALSA的时候,被这些参数搞得一头雾水。什么采样率、位深、周期大小,听起来都挺唬人的。但说白了,它们就是描述音频数据怎么流动、怎么存储的几个数字。搞懂了它们,你就能跟声卡顺畅对话了。
3.1 采样率(Sample Rate)
采样率,简单讲就是声卡每秒钟从模拟信号里“抓”多少个样本点。单位是Hz。比如44100 Hz,就是一秒抓44100次。
常见的采样率有这些:
| 采样率 | 常见用途 |
|---|---|
| 8000 Hz | 电话语音,VoIP |
| 16000 Hz | 宽带语音,很多语音识别用这个 |
| 44100 Hz | CD音质,MP3文件的标准 |
| 48000 Hz | DVD、电影、专业音频设备 |
| 96000 Hz | 高解析度音频,录音棚常用 |
我个人习惯,调试的时候先用44100 Hz。为什么?因为几乎所有声卡都支持这个值,不容易出幺蛾子。等基本通路通了,再换别的采样率去验证。
3.2 位深(Bit Depth)
位深,也叫采样精度。它决定了每个样本点用多少比特来表示。说白了,就是描述声音“细腻程度”的指标。
常见的位深:
- 8位:老式游戏机、低质量语音。动态范围只有48dB,噪声很明显。
- 16位:CD标准。动态范围96dB,日常听歌足够了。
- 24位:录音棚标准。动态范围144dB,给后期处理留了很大空间。
- 32位浮点:专业DAW内部处理格式。理论上动态范围无穷大,不会出现削波。
我在项目中遇到过一个问题:用16位录音,结果音量稍微大一点就破音了。后来换成24位,同样的输入电平,波形就干净多了。嗯,这里要注意,位深越大,数据量也越大。一个24位48kHz的立体声流,每秒的数据量是 48k × 3字节 × 2通道 = 288 kB/s。算算你的嵌入式设备扛不扛得住。
3.3 通道数(Channels)
通道数,就是同时播放或录制几个独立的音频流。
- 1(Mono):单声道。一个喇叭出声。
- 2(Stereo):立体声。左声道+右声道。
- 4(Quad):四声道。前左、前右、后左、后右。
- 6(5.1):前左、前右、中置、低音炮、后左、后右。
- 8(7.1):在5.1基础上再加两个侧环绕。
调试的时候,我建议先从立体声开始。因为大部分消费级声卡默认就是2通道。如果你一上来就配6通道,声卡可能直接报错,或者静音。我曾经被这个坑过——配了5.1通道,结果speaker-test只听到前面两个喇叭响,后面四个没声音。后来才发现是通道映射没搞对。
3.4 缓冲区大小(Buffer Size)
缓冲区,是声卡和应用程序之间的一块内存区域。应用程序把音频数据写进去,声卡从里面读出来播放。或者反过来,声卡把采集到的数据写进去,应用程序从里面读。
缓冲区大小,通常用帧数(frames)来表示。一帧等于所有通道的一个样本点。比如立体声16位,一帧就是4字节(左2字节+右2字节)。
缓冲区越大,延迟越高,但越不容易出现Xrun(欠载或过载)。缓冲区越小,延迟越低,但对系统实时性要求越高。
常见的缓冲区大小:
- 1024帧:保守设置,延迟约23ms(48kHz下)。适合桌面播放,不容易卡顿。
- 512帧:中等设置,延迟约10ms。很多音频应用默认值。
- 256帧:低延迟,延迟约5ms。适合实时监听、乐器演奏。
- 128帧:极低延迟,延迟约2.6ms。对系统要求很高,容易出Xrun。
3.5 周期大小(Period Size)
周期大小,这个概念很多人搞混。它跟缓冲区大小是两回事,但关系密切。
简单说,周期是声卡硬件中断的频率。声卡每播放完一个周期的数据,就会触发一次中断,通知应用程序“我这边又空出一块地方了,赶紧填数据”。
周期大小和缓冲区大小的关系是:
缓冲区大小 = 周期大小 × 周期数
通常周期数(period count)是2或3。所以如果缓冲区是1024帧,周期数设为2,那么周期大小就是512帧。
为什么要有周期?你想想看,如果没有周期,声卡得等到整个缓冲区都播完了才通知应用程序。那延迟就太大了。把缓冲区切成几个周期,应用程序就能更频繁地得到反馈,延迟自然就降下来了。
3.6 使用speaker-test进行基础测试
理论讲完了,咱们来点实战。speaker-test是ALSA自带的一个小工具,用来测试PCM播放是否正常。它简单、直接,是我调试音频时的首选。
最基本的用法:
speaker-test -t sine -f 440 -l 1
这条命令的意思是:播放一个440Hz的正弦波,只播一次(-l 1)。你会听到一声“嘟”。如果听到了,说明PCM播放通路基本没问题。
更全面的测试:
speaker-test -D hw:0,0 -c 2 -r 44100 -f S16_LE -t sine -l 3
参数解释:
-D hw:0,0:指定设备。hw:0,0表示第一张声卡的第一个设备。-c 2:通道数,这里是立体声。-r 44100:采样率,44.1kHz。-f S16_LE:样本格式,16位有符号小端序。-t sine:测试信号类型,正弦波。-l 3:重复3次。
如果你想测试多通道,比如5.1声道:
speaker-test -D hw:0,0 -c 6 -r 48000 -f S16_LE -t sine -l 1
它会依次在每个通道上播放测试音,并告诉你当前是哪个通道在响。这样你就能检查每个喇叭是否都正常工作了。
fuser -v /dev/snd/* 看看是谁在用,或者直接 pulseaudio -k 杀掉PulseAudio(如果它占着设备)。
嗯,这里还要提一句。speaker-test默认用的是plughw插件,它会自动处理格式转换。但如果你想测试硬件原生参数,记得用hw设备。我遇到过有人用plughw测试一切正常,换成hw就报错——那是因为声卡硬件根本不支持那个参数组合。所以,用hw设备测试,才能暴露真正的硬件限制。
好了,这一章的内容就到这儿。采样率、位深、通道数、缓冲区大小、周期大小,这几个参数你搞清楚了,PCM设备配置这块就拿下了一大半。下一章咱们聊聊更具体的PCM硬件参数配置,以及如何用代码去设置它们。