3.6 KiB
3.6 KiB
WASAPIBackend
命名空间: XCEngine::Audio::WASAPI
类型: class
头文件: XCEngine/Audio/WindowsAudioBackend.h
描述: 当前内建的 Windows 音频输出后端,实现 IAudioBackend 接口并负责设备打开、输出线程和样本提交。
命名说明
文档目录名和头文件名是 WindowsAudioBackend,但头文件里声明的主要类型名是 WASAPIBackend。
更重要的是,虽然类名带 WASAPI,当前实现实际上使用的是:
<mmsystem.h>waveOutOpenwaveOutWritewaveOutPrepareHeader
也就是更接近 WinMM waveOut 路径,而不是 Core Audio WASAPI COM 接口。文档必须把这一点明确说出来,避免名称误导。
角色概述
WASAPIBackend 是当前唯一已取证到的 IAudioBackend 实现,也是 AudioSystem 默认创建的后端。
它负责:
- 用
AudioConfig初始化 Windows 输出格式 - 枚举 waveOut 设备
- 维护一个后台线程
- 把浮点混音结果转换成
int16输出缓冲
当前实现行为
1. 初始化阶段
Initialize() 会:
- 保存配置
- 填充
WAVEFORMATEX - 调用
InitDevice() - 调用
InitBuffer()
InitDevice() 当前通过 waveOutOpen(..., WAVE_MAPPER, ...) 打开默认设备,并把 m_deviceName 设成 "Default Device"。
2. 设备切换并不完整
SetDevice(const std::string&) 现在只是在枚举到设备名匹配时保存 m_deviceName 并返回 true,但没有重新打开对应设备。
这意味着它更像“记录想使用哪个设备”,而不是已经完成真正的设备热切换。
3. 启停与线程
Start() 会创建后台线程,Stop() 会关闭运行标记并 join() 线程。线程主函数会等待 m_dataReady,然后切换前后缓冲并把当前 front buffer 写给系统。
4. 样本提交
ProcessAudio() 当前会:
- 如果静音或 buffer 为空则直接返回
- 读取
m_masterVolume - 把浮点样本 clamp 到
[-1, 1] - 转成
int16 - 写入 back buffer
- 标记
m_dataReady
当前实现限制
- 类名虽然叫
WASAPIBackend,实际不是 WASAPI COM 后端。 SetDevice()不会真正重建设备句柄。PrepareBackData()当前是空实现。ProcessAudio()把传入的bufferSize按字节数解释,而当前AudioSystem调用方传的是样本数量,这会造成语义不一致。- 内部使用的双缓冲大小固定基于
BufferSize = 8192和int16缓冲数组,和AudioConfig的关系还不完全统一。 - 这是 Windows 专用实现,不适用于跨平台文档语义。
- 没有看到该类型的直接单元测试。
线程语义
- 后端内部确实使用线程、原子变量、互斥量和条件变量。
- 但这不意味着上层可以任意并发调用所有 public 方法;当前文档仍不提供完整并发安全承诺。
相关方法
- Constructor
- Destructor
- Initialize
- Shutdown
- GetDeviceName
- GetAvailableDevices
- SetDevice
- GetMasterVolume
- SetMasterVolume
- IsMuted
- SetMuted
- Start
- Stop
- Suspend
- Resume
- ProcessAudio
- IsRunning
- GetConfig