# 音频设备与混音 · ADM 与 AudioMixer

> 音频的两头是硬件：采集靠麦克风、播放靠扬声器。ADM 抽象各平台的音频设备，AudioMixer 把会议里多路远端音频混成一路播放。这一章讲清这两个「两头」组件，收尾第 7 部分。

- 作者：David（道雾轩）
- 专栏：音视频与 WebRTC 详解（https://daiw.org/manual/webrtc.md）
- 最后更新：2026-07-14
- 原文：https://daiw.org/manual/webrtc/audio-device-mixer
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 音频设备与混音 · ADM 与 AudioMixer

音频管线的**两头**是硬件：发送侧的起点是**麦克风采集**，接收侧的终点是**扬声器播放**。抽象这些设备的是 **ADM**；而多人会议里，多路远端音频要**混成一路**才能播，靠 **AudioMixer**。这一章讲这两头，收尾第 7 部分。

## ADM：音频设备的抽象

**ADM（Audio Device Module，`modules/audio_device/`）** 是各平台音频硬件的**统一抽象**：

<Callout type="info">
  **ADM 把“各平台五花八门的音频 API”（Windows 的 WASAPI/Core Audio、macOS 的 CoreAudio、Android 的 AAudio/OpenSL、iOS 的 AudioUnit、Linux 的 ALSA/PulseAudio）收敛成统一接口——上层[音频管线](https://daiw.org/manual/webrtc/audio-pipeline-overview)不关心底下是哪个平台。** 它负责两件事：

  - **采集（capture）** —— 从麦克风读音频，喂给[APM 处理](https://daiw.org/manual/webrtc/apm-overview)、[编码](https://daiw.org/manual/webrtc/audio-codecs)。
  - **播放（render）** —— 把[NetEq 出的音频](https://daiw.org/manual/webrtc/neteq-overview)送到扬声器。

  ADM 还有个关键角色：它的**播放回调**是驱动 [NetEq `GetAudio` 的节拍源](https://daiw.org/manual/webrtc/neteq-overview)——声卡每隔固定时间（如 10ms）回调“给我下一段音频播”，这个回调就[触发 NetEq 产出一段音频](https://daiw.org/manual/webrtc/neteq-overview)。所以 ADM 的播放时钟，是[整个接收侧音频节奏](https://daiw.org/manual/webrtc/neteq-buffer-delay)的心跳。此外，有些平台的 ADM 能[用硬件的回声消除 / 降噪](https://daiw.org/manual/webrtc/aec3-echo-problem)，WebRTC 会视情况选择用平台的还是[自带的 APM](https://daiw.org/manual/webrtc/apm-overview)。ADM 是[平台集成](https://daiw.org/manual/webrtc/source-map)（[第 12 部分](https://daiw.org/manual/webrtc/source-map)）的重要一环。
</Callout>

## AudioMixer：多路混成一路

多人会议里，你**同时**收到好几个人的音频（[多条接收流](https://daiw.org/manual/webrtc/transceivers)）。但你只有**一对扬声器**——得把这几路**混成一路**再播。这是 **`AudioMixer`**（`modules/audio_mixer/`）的活：

<Callout type="info">
  **`AudioMixer` 把会议里多路[远端音频](https://daiw.org/manual/webrtc/neteq-overview)**混合（相加）**成一路，送去[播放](https://daiw.org/manual/webrtc/audio-device-mixer)——就像调音台把多个声源合成一路输出。** 混音不是简单相加了事，有讲究：

  - **谁参与混音** —— 几十人的大会，不必把每个人都混进去（大多数人在静音）。AudioMixer 通常**只混最响的几路**（[靠 VAD / 能量](https://daiw.org/manual/webrtc/ns-vad)挑出“正在说话”的），忽略静音者——省 CPU、也让主讲更清晰。
  - **防削顶** —— 多路相加可能[超出幅度上限（削顶失真）](https://daiw.org/manual/webrtc/agc)，混音要做限幅 / 归一。
  - **每个接收流各有[自己的 NetEq](https://daiw.org/manual/webrtc/neteq-overview)** —— 混音前，每路先各自[过 NetEq](https://daiw.org/manual/webrtc/neteq-overview)（各有各的[抖动 / 丢包](https://daiw.org/manual/webrtc/neteq-buffer-delay)），出来对齐后再混。

  **在纯 P2P 两人通话里，AudioMixer 作用不大（就一路远端）；它在多人会议（尤其[本地混音](https://daiw.org/manual/webrtc/simulcast-svc)的场景）才吃重。** 大型会议更常用 [SFU](https://daiw.org/manual/webrtc/sframe) 转发多路让客户端各自混，或用 MCU 在服务器混——但客户端的 AudioMixer 始终是把“我收到的这几路”合成“我听到的一路”的最后一步。
</Callout>

## 小结与第 7 部分回顾

**ADM（音频设备模块）** 抽象各平台音频硬件（采集 + 播放），其播放回调是[驱动 NetEq 的节拍心跳](https://daiw.org/manual/webrtc/neteq-overview)，也是[平台集成](https://daiw.org/manual/webrtc/source-map)一环。**`AudioMixer`** 把会议多路[远端音频](https://daiw.org/manual/webrtc/neteq-overview)**混成一路**播放（只混最响几路、防削顶，各路先过[各自 NetEq](https://daiw.org/manual/webrtc/neteq-overview)），多人会议才吃重。

**第 7 部分「音频管线」到此完整**：[总览](https://daiw.org/manual/webrtc/audio-pipeline-overview) → [编解码 Opus](https://daiw.org/manual/webrtc/audio-codecs) → [ACM](https://daiw.org/manual/webrtc/acm) → **NetEq**（[总览](https://daiw.org/manual/webrtc/neteq-overview)/[缓冲延迟](https://daiw.org/manual/webrtc/neteq-buffer-delay)/[六操作](https://daiw.org/manual/webrtc/neteq-operations)/[丢包隐藏](https://daiw.org/manual/webrtc/neteq-plc)/[时间伸缩](https://daiw.org/manual/webrtc/neteq-timestretch)） → **APM**（[总览](https://daiw.org/manual/webrtc/apm-overview)/[回声问题](https://daiw.org/manual/webrtc/aec3-echo-problem)/[AEC3](https://daiw.org/manual/webrtc/aec3-internals)/[AGC](https://daiw.org/manual/webrtc/agc)/[NS+VAD](https://daiw.org/manual/webrtc/ns-vad)） → 设备与混音。音频从麦克风到扬声器、以及它两颗明珠 NetEq 与 AEC3，已经拆透。

音视频都讲完了。还剩**数据通道**——传任意数据的那条路，底下是从零实现的 SCTP。第 8 部分进入 `net/dcsctp/`。👉 第 8 部分即将展开。

## 参考资料

- [1] libwebrtc 源码.`modules/audio_device/`（ADM，各平台实现）、`modules/audio_mixer/`（`AudioMixerImpl`、`frame_combiner.h`）。
- [2] libwebrtc 源码.`modules/audio_device/g3doc/`。
- [3] 关联[NetEq](https://daiw.org/manual/webrtc/neteq-overview)（被 ADM 播放回调驱动）、[平台集成第 12 部分](https://daiw.org/manual/webrtc/source-map)。
