AudioDeviceModule (简称 ADM) 是 WebRTC 中负责与操作系统底层音频硬件进行交互的核心抽象类。
它的主要作用是屏蔽不同平台(Windows, macOS, Linux, Android, iOS)音频 API 的差异,为上层的音频引擎(如 AudioState, WebRtcVoiceEngine)提供统一的接口,用于音频数据的采集(录音)和播放(放音)。
一, AudioLayer 枚举介绍
AudioLayer 定义了 ADM 可以使用的底层音频后端。开发者可以在创建 ADM 实例时指定使用哪种后端:
1 , kPlatformDefaultAudio: 让 WebRTC 自动选择当前平台推荐的最佳音频后端。这是生产环境中最常用的选项。
2, kWindowsCoreAudio / kWindowsCoreAudio2: Windows 平台专用的 WASAPI/Core Audio 实现。
3, kLinuxAlsaAudio: Linux 平台的 ALSA (Advanced Linux Sound Architecture) 后端。
4, kLinuxPulseAudio: Linux 平台的 PulseAudio 后端(常用于桌面发行版)。
5, kAndroidJavaAudio: 通过 JNI 调用 Android Java 层的 AudioRecord 和 AudioTrack。兼容性最好,但延迟可能较高。
6, kAndroidOpenSLESAudio: 使用 Android 的 OpenSL ES C++ API,通常能提供比 Java 层更低的延迟。
7, kAndroidAAudio: 使用 Android NDK 中的 AAudio API,旨在提供低延迟和高性能,是现代 Android 版本的首选。
8, kDummyAudio: 虚拟音频设备。不连接真实硬件,通常用于单元测试或服务器端运行 WebRTC 时无需音频设备的场景。
9, 混合模式 (如 kAndroidJavaInputAndAAudioOutputAudio): 允许输入和输出使用不同的后端,以解决某些特定设备上的兼容性问题。
二, 关键接口介绍
2.1 生命周期管理
• Create(...): 静态工厂方法,根据指定的 AudioLayer 创建 ADM 实例。
• Init() / Terminate(): 初始化内部资源(如线程、缓冲区)和释放资源。
• RegisterAudioCallback(AudioTransport*): 注册一个回调接口。ADM 会通过这个接口请求发送音频数据(播放时)或交付采集到的音频数据(录音时)。这是 ADM 与上层音频处理模块连接的纽带。
2.2. 设备枚举与选择
• PlayoutDevices() / RecordingDevices(): 获取可用输出/输入设备的数量。
• PlayoutDeviceName(...) / RecordingDeviceName(...): 获取指定索引设备的名称和 GUID。
• SetPlayoutDevice(...) / SetRecordingDevice(...): 选择特定的设备进行录音或播放。可以通过索引或 Windows 特有的默认设备类型(如默认通信设备)来选择。
2.3 播放传输与控制
• InitPlayout() / InitRecording(): 准备音频流,分配缓冲区等。
• StartPlayout() / StopPlayout(): 开始或停止向扬声器发送数据。
• StartRecording() / StopRecording(): 开始或停止从麦克风采集数据。
• Playing() / Recording(): 查询当前状态。
2.4 音量与静音控制
• Speaker/Microphone Volume: 设置和获取扬声器/麦克风的音量级别 (SetSpeakerVolume, MicrophoneVolume 等)。
• Mute: 控制扬声器或麦克风的静音状态 (SetSpeakerMute, SetMicrophoneMute)。
2.5 平台特化功能
• Android: 支持启用系统内置的回声消除 (AEC)、自动增益 (AGC) 和噪声抑制 (NS) (EnableBuiltInAEC 等)。这通常比 WebRTC 软件算法更高效,但灵活性较低。
• iOS: 获取音频参数 (GetPlayoutAudioParameters)。
三,工作流程
-
创建: auto adm = AudioDeviceModule::Create(kPlatformDefaultAudio, task_queue_factory);
-
初始化: adm->Init();
-
注册回调: adm->RegisterAudioCallback(audio_transport_impl); (audio_transport_impl 通常由 AudioState 提供,负责将数据传给 Mixer 或 APM)。
-
选择设备: adm->SetPlayoutDevice(0); adm->SetRecordingDevice(0);
-
启动:
• adm->InitPlayout(); adm->StartPlayout();
• adm->InitRecording(); adm->StartRecording();
- 数据流动:
• 播放: ADM 内部线程定期调用 AudioTransport::NeedMorePlayData,上层填充 PCM 数据,ADM 将其写入硬件缓冲区。
• 录音: 硬件产生中断,ADM 读取 PCM 数据,调用 AudioTransport::RecordedDataIsAvailable 将数据传递给上层。