关于audio的古老的笔记2
参数物理意义DMA 每消耗 period_size frames,就触发一次 IRQring buffer 中 period 的个数,用于双缓冲或多缓冲ring buffer 总容量示例:period_size = 240 frames period_count = 2 buffer_size = 480 frames sample_rate = 48000 Hz latency = 480 /
一、period_size 的物理意义
period_size = 每次 DMA 从 ring buffer 中消耗(或填充)多少 frames,完成后触发一次硬件中断 IRQ。
换句话说:
DMA 写/读到 period_size 的数据量,就触发一次 IRQ,让 AP 处理一次。
在 PCM 播放场景中:
-
AP(AudioFlinger → HAL)将数据写到 ALSA ring buffer
-
DMA 从 ring buffer 读数据送到 DAC
-
每当 DMA 消耗完一个 period,DMA 产生 IRQ
-
IRQ 通知 AP:
“我又消费完了一个 period,你可以再写数据了”
period_size 越小 → IRQ 越频繁 → latency 越低,但 AP 负载越高。
二、period_count 的物理意义
period_count = ring buffer 里包含几个 period。
所以:
总 buffer size = period_size × period_count
举例:
period_size = 240 frames period_count = 2
则:
缓冲区总容量 = 240 × 2 = 480 frames
这样 ring buffer 内部结构是:
[ period0: 240 frames ][ period1: 240 frames ]
DMA 从缓冲区循环播放
AP 往空出来的 period 写数据。
三、为什么需要 period_count?
主要原因:保证 DMA 不会饿死(underrun)。
如果只有 1 个 period:
-
AP 写完 240 frames
-
DMA 播放完 240 frames(这过程 AP 不能再写,因为 DMA 正在读同一块)
-
DMA 播完 → AP 才能再写
-
非常容易 underrun
(因为 AP 写数据/调度有 jitter)
有了 2 个 period:
DMA 播放 period0 → AP 可以同时写 period1 DMA 播放 period1 → AP 可以同时写 period0
实际音频系统常用 period_count = 2 或 3。
四、“Low-latency 240 / 2 / 480 / 10ms” 的含义
这 4 个数字典型表示:
period_size = 240 frames period_count = 2 buffer_size = 480 frames (= 240 * 2) latency = 10 ms
🔍 五、10 ms 是怎么计算的?
先判断采样率:
low-latency 输出路径通常是:
48000 Hz
计算 latency:
计算方式 1:以 ring buffer size 为准
这是 系统音频 latency 的主要来源之一:
latency_ms = buffer_size / sample_rate * 1000
代入:
480 frames / 48000 Hz × 1000 = 0.01 秒 = 10 ms
这就是你看到 10ms 的来源
也就是说,这个配置的总音频硬件队列导致:
硬件播放延迟约 10ms
对 Android low_latency track 来说这符合预期
(普通 track 的 latency 要高得多,比如 20~40 ms)。
六、另外两个重要延迟(补充)
注意:10ms 只代表 driver 的 ring buffer。
Android 还包含:
-
AudioFlinger Mixer → 1~2ms
-
Resampler → 几 ms(取决于 CPU)
-
HAL path → 0.5~1ms
-
音频 codec → 1~3ms
-
Speaker 机械 → 1~3ms(耳机更低)
所以系统 total latency 可能是:
15~25 ms 之间
Low-latency track 主要优化:减小 ring buffer。
总结(最清晰版本)
| 参数 | 物理意义 |
|---|---|
| period_size | DMA 每消耗 period_size frames,就触发一次 IRQ |
| period_count | ring buffer 中 period 的个数,用于双缓冲或多缓冲 |
| buffer_size = period_size × period_count | ring buffer 总容量 |
| latency(10ms) | buffer_size / sample_rate |
示例:
period_size = 240 frames period_count = 2 buffer_size = 480 frames sample_rate = 48000 Hz latency = 480 / 48000 = 0.01 秒 = 10ms
==========================另一个版本======================================
下面我把 period_size、period_count 的物理意义 以及 为什么 Low-latency 的 10 ms 是这么算出来的 全部讲清楚。
这些概念在 Android / ALSA / Qualcomm ASoC 中完全一致。
✅ 1. period_size 的物理意义:触发中断(IRQ)的单位
period_size = 每写完这么多帧后,DMA 触发一次中断 (IRQ)。
例如:
-
period_size = 240 frames
-
采样率 = 48 kHz
那么写满这一段数据需要:
240/48000=5ms240 / 48000 = 5ms240/48000=5ms
→ 每 5ms 硬件对 AP(Audio DSP → CPU 或 DSP → AHAL)发起 一次中断。
这是 Audio 中断的最小粒度,也称 interrupt interval。
因此:
✔ period_size 决定中断频率
✔ period_size 越小 → 中断越频繁 → 延迟更低但 CPU 负载更高
✅ 2. period_count 的物理意义:环形 buffer 的长度
period_count = 环形 DMA buffer 中 period 的个数。
整个 buffer 的总大小是:
buffer_size=period_size×period_countbuffer\_size = period\_size \times period\_countbuffer_size=period_size×period_count
这个 buffer 位于:
-
Playback:AHAL → DSP(PCM 环形 buffer)
-
Capture:DSP → AHAL(PCM 环形 buffer)
buffer 的作用:
🟦 period_count 是“提前准备的数据量”= 用于防止 underrun
如果只用 1 个 period,那么系统必须每 5ms 喂一次数据,稍有抖动就会 underrun。
因此:
-
period_count 通常 ≥ 2
-
值越大 → 系统越稳 → 延迟越高
Qualcomm Low-latency:
| 参数 | 值 | 解释 |
|---|---|---|
| period_size | 240 frames | 5ms |
| period_count | 2 | 总 buffer 10ms |
| total buffer | 480 frames | 10ms |
✅ 3. 10 ms 是怎么来的?
Low-latency 的表中有一行:
Low-latency period_size = 240 period_count = 2 buffer = 480 frames approx latency ≈ 10ms
它的计算方式非常直接:
latency=period_size×period_countsample_ratelatency = \frac{period\_size \times period\_count}{sample\_rate}latency=sample_rateperiod_size×period_count
代入:
=240×248000=0.01=10ms= \frac{240 \times 2}{48000} = 0.01 = 10ms=48000240×2=0.01=10ms
这就是 Qualcomm 文档中写的 10ms 低延迟模式。
⚠️ 但是请注意:真实最终的“用户听到的延迟”不是 10ms
10ms 只是 DSP DMA buffer 的基础延迟。
完整路径还有:
-
AudioTrack 侧 buffer(AAudio/Java/Native)
-
MixerThread / FastMixer processing 时间
-
DSP processing(effects / resampler)
-
AFE → Codec → I2S 的 pipeline 延迟
-
Codec 架构的 FIR latency
最终到耳机一般是:
25–60ms(wired)
100–200ms(Bluetooth SBC)
🟩 4. 总结(非常关键)
period_size = IRQ 粒度
-
意味中断周期(interrupt interval)
-
决定 CPU 负载和实时性
-
小 period → 低延迟 → 高 CPU
period_count = DMA 环形 buffer 大小
-
用于防 underrun
-
期间 DSP 在消费数据
-
越大越稳定但延迟越高
total_latency = period_size × period_count / sample_rate
Low-latency = 240 × 2 / 48000 = 10ms
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)