应用程序程序依赖于用户模式和内核模式组件的组合来捕获(输入)和呈现(输出)波形流。 波形流是数字音频流,其数据格式由 WAVEATEX 或 WAVEATEXTENSIBLE 结构描述。
应用程序可以使用以下任一软件接口进行波形呈现和捕获:
Microsoft Windows 多媒体 waveOutXxx 和 waveInXxx 函数
DirectSound 和 DirectSoundCapture API
waveOutXxx 和 waveInXxx 函数的行为基于旧版波形驱动程序和设备的功能。 从 Windows 98 开始, WDMAud 系统驱动程序 会将对这些函数的调用转换为 WDM 音频驱动程序的命令。 但是,通过模拟旧软件和硬件的行为,waveOutXxx 函数会牺牲现在可通过 DirectSound API 提供的三维声音效果和硬件加速。 有关 DirectSound 和 Windows 多媒体波函数的详细信息,请参阅 Microsoft Windows SDK 文档。
DirectSound 和 Windows 多媒体波函数是 SysAudio 系统驱动程序的客户端,它生成处理波形和 DirectSound 流的音频筛选器图。 图形生成对于使用这些软件接口的应用程序是透明的。
波形组件
下图显示了波形应用程序用于呈现或捕获由波形 PCM 数据组成的数字音频流的用户模式和内核模式组件。
呈现组件显示在上图的左侧,捕获组件显示在右侧。 表示波形微型端口驱动程序的框变暗,以指示这些是供应商提供的组件。 图中的其他组件是系统提供的。
在图形左上角,波形渲染(或“波形输出”)应用程序通过用户模式 WinMM 系统组件中实现的 waveOutXxx 函数与 WDM 音频驱动程序接口,Winmm.dll。 应用程序从文件中读取波形音频样本块,并调用 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_PortWaveCyclic 或 CLSID_PortWavePci 的 PcNewPort 来创建 WaveCyclic 或 WavePci 端口驱动程序的实例。
上图右侧显示了支持将波形数据捕获到文件的应用程序所需的组件。 波形捕获(或“wave-in”)应用程序通过在 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.sys,这是 WDMAud 系统驱动程序的内核模式一半。 用户模式的一半 Wdmaud.drv 通过 waveInXxx 函数将波形流输出到应用程序程序,这些函数在 Winmm.dll中实现。 最后,在图的顶部,波形捕获应用程序将波形数据写入文件。
在波形捕获应用程序调用 waveInOpen 函数以打开捕获流时,它会传入指向其回调例程的指针。 发生波形捕获事件时,操作系统会使用包含来自捕获设备的下一个波形样本块的缓冲区来调用回调例程。 为了响应回调,应用程序将下一个波形数据块写入文件。
DirectSound 组件
下图显示了 DirectSound 应用程序用来呈现或捕获波形数据的用户模式和内核模式组件。
呈现组件呈现在前图的左侧半部,而捕获组件出现在右侧。 波形微型端口驱动程序显示为深色框,以指示它们是供应商提供的组件。 图中的其他组件是系统提供的。
在图的左上角,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 缓冲区读取波形数据并将其写入文件。