Wave 和 DirectSound 组件

应用程序程序依赖于用户模式和内核模式组件的组合来捕获(输入)和呈现(输出)波次流。 波次流是数字音频流,其数据格式由 WAVEFORMATEXWAVEFORMATEXTENSIBLE 结构描述。

应用程序可以使用以下任一软件接口进行波次呈现和捕获:

  • Microsoft Windows 多媒体 waveOutXxx 和 waveInXxx 函数

  • DirectSound 和 DirectSoundCapture API

waveOutXxx 和 waveInXxx 函数的行为基于旧版波次驱动程序和设备的功能。 从 Windows 98 开始,WDMAud 系统驱动程序会将对这些函数的调用转换为 WDM 音频驱动程序的命令。 但是,通过模拟旧软件和硬件的行为,waveOutXxx 函数会牺牲现在通过 DirectSound API 提供的 3-D 声音效果和硬件加速。 有关 DirectSound 和 Windows 多媒体波次函数的详细信息,请参阅 Microsoft Windows SDK 文档。

DirectSound 和 Windows 多媒体波次函数是 SysAudio 系统驱动程序的客户端,该驱动程序会生成处理波次和 DirectSound 流的音频筛选器图。 图形生成对于使用这些软件接口的应用程序是透明的。

波次组件

下图显示了波次应用程序用于呈现或捕获由波次 PCM 数据组成的数字音频流的用户模式和内核模式组件。

Diagram illustrating user-mode and kernel-mode components for wave rendering and capture.

呈现组件显示在上图左侧,捕获组件显示在右侧。 表示波次微型端口驱动程序的框会变暗,以指示这些是供应商提供的组件。 图中的其他组件由系统提供。

在图的左上角,通过 waveOutXxx 函数(在用户模式 WinMM 系统组件 Winmm.dll 中实现),向 WDM 音频驱动程序提供波次呈现(或“波次输出”)应用程序接口。 应用程序从文件中读取波次音频样本块,并调用 waveOutWrite 函数来呈现这些块。

WDMAud 由用户模式和内核模式组件(Wdmaud.drv 和 Wdmaud.sys)组成,可用于缓冲来自 waveOutWrite 调用的波次数据,并将波次流输出到 KMixer 系统驱动程序,该驱动程序显示在图中的 WDMAud 下方。

KMixer 是一个系统组件,可接收来自一个或多个源的波次 PCM 流,并将它们混合在一起,形成单个输出流,该流也采用波次 PCM 格式。

KMixer 将波次流输出到 WaveCyclic 或 WavePci 设备,其端口和微型端口驱动程序显示在上图左侧的 KMixer 下方。 微型端口驱动程序将自身绑定到端口驱动程序,形成表示基础音频呈现设备的波次筛选器。 典型的渲染设备会输出一个模拟信号,该信号将驱动一组扬声器或外部音频单元。 呈现设备还可以通过 S/PDIF 连接器输出数字音频。 有关 WaveCyclic 和 WavePci 的详细信息,请参阅波次筛选器

或者,KMixer 也可以将输出流传递给 USB 音频设备,该设备由 USBAudio 类系统驱动程序(图中未显示)控制,而不是传递给 WaveCyclic 或 WavePci 设备。

通过调用 GUID 值分别为 CLSID_PortWaveCyclicCLSID_PortWavePciPcNewPort,适配器驱动程序可创建 WaveCyclic 或 WavePci 端口驱动程序的实例。

上图右侧显示了支持将波次数据捕获到文件的应用程序所需的组件。 通过在 WinMM 系统组件中实现的 waveInXxx 函数,波次捕获(或“波次输入”)应用程序可与 WDM 音频驱动程序通信。

在图的右下角,波次捕获设备由波次微型端口驱动程序和端口驱动程序控制。 端口和微型端口驱动程序(可以是 WaveCyclic 或 WavePci 类型)可绑定在一起,形成表示捕获设备的波次筛选器。 此设备通常会从麦克风或其他音频源捕获模拟信号,并将其转换为波次 PCM 流。 设备还可以通过 S/PDIF 连接器输入数字音频流。

波次端口驱动程序会将其波次流直接输出到 KMixer 或 WDMAud。 如果需要在 WDMAud 收到流之前对其进行采样率转换,则流必须通过 KMixer 传递。 执行音频流同时呈现和捕获的系统可能需要两个 KMixer 实例,如图所示。 请注意,SysAudio 会根据需要自动创建这些实例。

或者,所捕获波次流的源也可以是 USB 音频设备,而不是 WaveCyclic 或 WavePci 设备。 在这种情况下,USBAudio 驱动程序(图中未显示)会将流传递给 KMixer。

无论波次流是由 USB 设备还是 WaveCyclic 或 WavePci 设备捕获,KMixer 都会根据需要对流执行采样率转换,但不与其他流混合。 KMixer 会将生成的流输出到 WDMAud 系统驱动程序的内核模式一半 Wdmaud.sys。 用户模式的一半 Wdmaud.drv 通过 waveInXxx 函数将波次流输出到应用程序,这些函数是在 Winmm.dll 中实现的。 最后,在图的顶部,波次捕获应用程序将波次数据写入文件。

在波次捕获应用程序调用 waveInOpen 函数,以打开捕获流时,它会传入指向其回调例程的指针。 发生波次捕获事件时,操作系统将使用包含来自捕获设备的下一个波次样本块的缓冲区调用回调例程。 为了响应回调,应用程序会将下一个波次数据块写入文件。

DirectSound 组件

下图显示了 DirectSound 应用程序用于呈现或捕获波次数据的用户和内核模式组件。

Diagram illustrating user-mode and kernel-mode components for DirectSound rendering and capture.

呈现组件显示在上图的左半部分,捕获组件显示在右侧。 波次微型端口驱动程序显示为深色框,以指示它们是供应商提供的组件。 图中的其他组件由系统提供。

在图的左上角,DirectSound 应用程序将波次数据从文件加载到用户模式 DirectSound 系统组件 (Dsound.dll) 管理的声音缓冲区。 此组件会将波次流发送到 WaveCyclic 或 WavePci 设备,其端口和微型端口驱动程序显示在图的左下角。 如果设备上提供了硬件混音器引脚,流将直接传递到波次端口驱动程序,从而绕过 KMixer。 否则,流首先通过 KMixer 传递,这会将其与任何其他同时播放的流混合。 KMixer 将混合流输出到端口驱动程序。

与之前一样,微型端口驱动程序将自身绑定到端口驱动程序,形成表示基础音频呈现设备的波次筛选器。 例如,此设备可能会通过一组扬声器播放流。

或者,波次流也可以由 USB 音频设备呈现,而不是由 WaveCyclic 或 WavePci 设备呈现。 在这种情况下,流无法绕过 KMixer;USBAudio 类系统驱动程序(图中未显示)始终会将流传递给 KMixer。

上图右侧显示了支持 DirectSoundCapture 应用程序的组件。 应用程序会记录从 WaveCyclic 或 WavePci 捕获设备收到的波次数据。 例如,此设备会将来自麦克风的模拟信号转换为波次流。 设备的波次端口和微型端口驱动程序显示在图的右下角。 如图所示,端口驱动程序从微型端口驱动程序接收流作为输入,并将其直接输出到用户模式 DirectSound 组件 Dsound.dll,或通过 KMixer 间接输出。 这取决于捕获设备是否提供硬件捕获引脚。

或者,所捕获波次流的源也可以是 USB 音频设备。 在这种情况下,流无法绕过 KMixer;USBAudio 驱动程序(图中未显示)始终会将流传递给 KMixer。

如果将 KMixer 插入到捕获流的路径中,则可根据需要对流执行采样率转换,但不会将其与其他流混合。

在上图右上角,应用程序从 DirectSoundCapture 缓冲区读取波次数据并将其写入文件。