将下面的 PCM 配置作为例子:
c
config.channels = 2; // 立体声(2 个通道)
config.rate = 48000; // 采样率 48000 Hz,即每秒 48000 帧
config.period_size = 1024; // 每个周期包含 1024 帧
config.period_count= 4; // 总周期数 4 → 整个缓冲区包含 1024 * 4 = 4096 帧
config.format = PCM_FORMAT_S16_LE; // 16 位小端格式,即每个采样占 16 位(2 字节)
1. 单帧的构成
-
定义帧 :
在 PCM 数据中,每一帧包含了所有通道对应的一个采样数据。
- 例如对于立体声(2 通道),每帧包含 2 个采样。
-
采样大小与每帧字节数:
- 格式 PCM_FORMAT_S16_LE 表示每个采样为 16 位(2 字节)。
- 因此,每帧字节数 = 通道数 × 每样本字节数
= 2 × 2 = 4 字节。
2. 采样率与帧率
- 采样率定义 :
采样率 48000 Hz 表示每秒钟采集 48000 帧数据。- 不论是 2 个通道还是 4 个通道,每秒始终采集 48000 帧。
- 这意味着:
- 在 2 通道下,每个通道的采样频率同样为 48000 Hz,总采样点数为 48000 × 2 = 96000 个。
- 在 4 通道下,每个通道也是 48000 Hz,总采样点数为 48000 × 4 = 192000 个。
注意:采样率表示的是整体帧率,并不会因通道数改变而"分摊"到每个通道。
3. 周期(Period)和缓冲区
-
Period Size (1024 帧):
代表每次数据读写时处理的最小单位。
- 时间长度 = period_size / 采样率
= 1024 / 48000 ≈ 0.02133 秒 ≈ 21.33 毫秒。
- 时间长度 = period_size / 采样率
-
Period Count (4 个周期):
有助于形成一个环形缓冲区,整个缓冲区的帧数为
- 总帧数 = period_size × period_count = 1024 × 4 = 4096 帧.
- 总缓冲区字节数 = 总帧数 × 每帧字节数 = 4096 × 4 = 16384 字节.
4. 音频时长的计算
假设只处理(或读取)一个周期的数据(1024 帧),则其时长为:
换算成毫秒即为:
如果处理整个缓冲区(4096 帧),时长则是:
5. 多通道情况下的解释
-
统一的采样率 :
采样率表示的是每秒钟采集的帧数,与通道数无关。
- 无论配置 2 个通道还是 4 个通道,每秒都采集 48000 帧,只不过每帧内包含 2 或 4 个采样数据。
- 因此,每个通道的采样频率始终为 48000 Hz,而不会因为通道数不同而分别变成 24000 Hz 或 12000 Hz。
-
总采样点数:
- 2 通道配置:总采样点数 = 48000 × 2 = 96000
- 4 通道配置:总采样点数 = 48000 × 4 = 192000
总结
- 采样率(rate):定义每秒处理的帧数(48000 Hz),与通道数无关。
- 帧(Frame):是一个包含所有通道采样的最小数据单位,每帧字节数由 channel 数×(每个采样的字节数)决定。
- Period Size:单次数据传输的帧数(1024 帧),也意味着单个周期的时长为 1024/48000 秒(约 21.33 毫秒)。
- Period Count:缓冲区中周期的总数(4),影响整个缓冲区的大小和抗系统调度抖动的能力(总帧数 4096)。
- 数据大小 :通过
pcm_frames_to_bytes()
可把帧数转换为字节数,方便内存分配和数据传输;反之pcm_bytes_to_frames()
则可将读取或写入的字节数转换回帧数以便计算时长等。