WavePci 设备的硬件要求

选择新硬件设计的功能时,供应商应遵循以下一般原则:

  • 供应商应该根据对性能的影响来权衡每项功能的成本,而不是简单地将所有处理都移到硬件上。

  • 在考虑硬件功能的潜在价值时,供应商应根据对整个系统的影响来评估该功能,而不是将注意力缩小到音频等特定子系统上。

  • 通过明智地选择要在硬件中加速的功能,供应商可以缓解 CPU 工作负载并提高内存使用率,从而使系统的资源可供其他任务使用。

从历史上看,并非所有音频硬件设计都成功地遵循了这些原则。

播放音频内容或混合多个流时,某些 WDM 音频驱动程序不需要消耗大量 CPU 时间和总线带宽。 此类缺陷通常是存在缺陷的硬件设计和低效驱动程序实现导致的。 硬件设计缺陷还可以防止音频驱动程序处理某些波形格式或要求使用需要软件干预的解决方法。

WaveCyclic 设备模型的目的是适应较旧的音频设备的硬件限制。 新的硬件设计应完全符合 WavePci。

能够执行真实分散/聚集 DMA 的 WavePci 设备无需 CPU 花费时间在缓冲区之间复制音频数据。 与 WaveCyclic 不同,WavePci 本身不需要数据复制,因此成为多流或硬件加速音频设备的首选微型端口驱动程序。 设计良好的 WavePci 设备几乎不会消耗 CPU 资源,因此可以将大量音频流(64 或更多)发送到硬件进行三维处理和混合。

WavePci 设备需要支持分散/聚集 DMA 传输的总线主 DMA 控制器。 硬件设计不应对 DMA 控制器可以处理的数据传输类型施加任意限制。 WavePci 设备应满足以下要求:

  • 设备必须是总线主控。

    它应该能够自主访问系统内存,而无需从操作系统进行干预,也无需使用系统 DMA 资源。

  • 设备必须能够处理任意长度的数据传输。

    它应处理大于内存页的映射(请参阅 IPortWavePciStream::GetMapping)。 例如,传输限制为 4 KB 的设备不符合 WavePci 的完整要求。 在支持 Microsoft Windows 的 64 位 CPU 上,页面大小为 8 KB,这使得某些映射的大小可能大于 4 KB。 理论上,单个映射中超过 32 KB 的数据传输是可能的,具体取决于物理内存碎片。 在其他极端情况下,可以映射一个字节的大小。

  • 设备应处理系统内存中任意位置的数据传输。

    跨 32 千字节或更大的 2 的幂边界的数据传输很有可能。 在 64 位 CPU 或 x86 物理地址扩展 (PAE) 的情况下,计算机现在可以包含超过 4 GB 的 RAM,在这些系统中,映射可以位于超过 4 GB 的物理内存中。 为了在这些计算机上实现最佳性能,供应商应创建支持 64 位寻址的设备。 否则,需要在软件中复制数据。 对于具有 24 位寻址的设备,具有超过 16 兆字节 RAM 的系统上需要数据复制。 如果设备无法从物理内存中的任何位置读取或写入,则设备应使用 WaveCyclic 而非 WavePci。 驱动程序可以在设备启动时(见 IRP_MN_START_DEVICE)做出此决定,此前它有机会确定其地址范围是否足以访问系统内存总线的完整地址范围。

  • 设备应使用任意对齐方式处理数据传输。

    映射可以在内存中的任意字节边界上开始和结束。 音频数据帧可以在映射之间拆分,前几个声道的样本在第一个映射的末尾,剩余声道的样本在第二个映射中。 有关示例,请参阅波形筛选器。 对于某些样本大小,甚至可以在多个映射之间拆分一个示例容器。 如果设备要求传输必须位于缓存行边界上,或者如果设备要求传输严格与音频帧边界对齐(例如,假设传输大小均匀划分为 4,在立体声 16 位的情况下),则此设备不足以完全符合 WavePci 标准。 请注意,通过限制驱动程序公开的数据范围或格式(例如,仅限某些位深度或仅限特定声道配置),可将不合规的一块硬件公开为 WavePci 设备。

对于上述列表中的最后一点,WavePci 设备的分散/聚集 DMA 引擎应处理跨越内存页边界的缓冲区。 例如,对于 48 kHz、5.1 声道波形流,包含 10 毫秒的 16 位 PCM 音频样本的缓冲区大小如下:

(6 个样本/帧)*(2 个字节/样本)*(48K 帧/秒)*(10 毫秒)= 5760 字节

这超出了内存页大小(4096 字节),意味着缓冲区包含一个或两个页面边界,具体取决于它在内存中的位置。 缓冲区包含整数 (480) 个音频数据的帧,但其中一两个帧可能会跨越页面边界。

因此,应将 WavePci 设备的分散/聚集 DMA 硬件设计为处理音频帧(如下图中的帧 197),这些帧在内存中两个物理上不连续的页面之间拆分。

Diagram illustrating an audio buffer with an offset from the start of a memory page.

上图顶部是一个 5760 字节缓冲区,跨两页之间的边界。 在此示例中,缓冲区从第一页开始的 1728 字节偏移量开始,该偏移量将缓冲区的开头与内存中的 64 字节边界对齐。 假设每个音频帧占用 12 个字节,并且包含六个声道。 第一页包含 0 到 196 的所有帧,但仅包含帧 197 的前四个字节。

图底部是音频帧 197 的详细视图,其中显示只有第一页中声道 0 和 1 的示例。 第二页中包含声道 2 到 5 的示例。

尽管这两个页面在图的顶部彼此相邻,但它们实际上仅在内核虚拟内存中连续。 由于包含缓冲区的页面在物理内存中是不连续的,因此使用物理地址的分散/聚集 DMA 控制器必须将缓冲区的两个部分指定为其传输队列中的两个单独条目。 WavePci 端口驱动程序会自动将缓冲区拆分为页面边界上的两个单独物理映射。

即使前面的示例已更改为将缓冲区与第一页的开头对齐,拆分帧问题也不会消失。 下图演示了这一点。 在这种情况下,帧 341 在页面边界处拆分,声道 0 和 1 的示例再次落在第一页中,第 2 到第 5 个声道的示例位于第二页。

Diagram illustrating an audio buffer aligned to the start of a memory page.

分散/聚集 DMA 控制器无法正确处理拆分音频帧的 WavePci 设备,其可处理的音频数据格式种类受到限制,尽管软件解决方法可能有助于缓解某些硬件设计缺陷。 有关详细信息,请参阅 WavePci 延迟