Files
XCEngine/docs/api/XCEngine/Audio/WindowsAudioBackend/WindowsAudioBackend.md

3.6 KiB
Raw Blame History

WASAPIBackend

命名空间: XCEngine::Audio::WASAPI

类型: class

头文件: XCEngine/Audio/WindowsAudioBackend.h

描述: 当前内建的 Windows 音频输出后端,实现 IAudioBackend 接口并负责设备打开、输出线程和样本提交。

命名说明

文档目录名和头文件名是 WindowsAudioBackend,但头文件里声明的主要类型名是 WASAPIBackend

更重要的是,虽然类名带 WASAPI,当前实现实际上使用的是:

  • <mmsystem.h>
  • waveOutOpen
  • waveOutWrite
  • waveOutPrepareHeader

也就是更接近 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 = 8192int16 缓冲数组,和 AudioConfig 的关系还不完全统一。
  • 这是 Windows 专用实现,不适用于跨平台文档语义。
  • 没有看到该类型的直接单元测试。

线程语义

  • 后端内部确实使用线程、原子变量、互斥量和条件变量。
  • 但这不意味着上层可以任意并发调用所有 public 方法;当前文档仍不提供完整并发安全承诺。

相关方法

相关文档