WavePci 延迟
WavePci 端口驱动程序处理与 WaveCyclic 驱动程序不同的音频流的缓冲。
如果 WavePci 微型端口驱动程序提供硬件混合,DirectSound 会将 IRP 提交到 WavePci 端口驱动程序,该驱动程序包含单个循环缓冲区中的整个 DirectSound 波次流。 DirectSound 将缓冲区分配为连续虚拟内存块。 为了避免复制 DirectSound 缓冲区,内核流式处理层会将缓冲区映射到内核模式虚拟内存,并生成一个 MDL(内存描述符列表),该列表指定循环缓冲区中内存页的虚拟地址和物理地址。 WavePci 端口驱动程序将循环缓冲区分区为一系列分配器帧(请参阅 KS 分配器)。 端口驱动程序在流初始化期间调用其 IMiniportWavePciStream::GetAllocatorFraming 方法时,微型端口驱动程序将指定其首选分配器帧大小。 但是,系统图形生成器 SysAudio 可以覆盖微型端口驱动程序的首选项,以满足音频筛选器图中其他组件的要求。
WavePci 端口驱动程序将循环缓冲区作为映射序列公开给微型端口驱动程序。 映射是整个分配帧或该帧的一部分。 如果特定分配帧完全位于页面中,端口驱动程序会向微型端口驱动程序将该帧呈现为单个映射。 如果分配帧跨越一个或多个页面边界,则端口驱动程序会拆分每个页面边界的帧,并将其呈现为两个或多个映射。 每次调用 IPortWavePciStream::GetMapping 都会生成序列中的下一个连续映射。
与 WaveCyclic 情况相比,微型端口驱动程序几乎无法控制硬件中缓冲的数据毫秒数,WavePci 微型端口驱动程序可以在一定程度上控制任何时候打开的映射数。 每次调用 GetMapping 时,打开的映射数都会增加一个;每次调用 ReleaseMapping 时,都会减少一个。 (当然,GetMapping 调用可能会失败,因此驱动程序无法完成控制映射数。通过控制打开的映射数并跟踪映射的累积大小,微型端口驱动程序可以确定(在容错范围内取决于映射大小)硬件可用的缓冲毫秒数。 WavePci 微型端口驱动程序应请求足够的页面映射,以减少枯竭到可接受级别的几率。
如果微型端口驱动程序的策略是缓冲多达 50 毫秒的数据,例如,在读取和写入指针之间,请记住,此限制表示驱动程序将累积的最大数据量,但它不代表驱动程序对流延迟的贡献。 应将驱动程序设计为保持其延迟尽可能小。 当微型端口驱动程序在开始播放新流之前获取其初始映射集时,微型端口驱动程序可以继续请求映射,直到它达到其缓冲区限制(在此示例中为 50 毫秒),或者不再提供任何映射。 但是,在后一种情况下,微型端口驱动程序在开始播放流之前,不会等待有更多映射可用。 相反,驱动程序应立即开始播放已获取的映射。 稍后,随着有更多的映射可用,驱动程序可以继续获取其他映射,直到达到其缓冲区大小限制或不再立即有映射可用。
通常,WavePci 设备的 DMA 硬件应设计为直接访问以任意字节对齐方式存储的音频帧,以及物理内存的非连续页之间的跨接边界。 如果有一个要求映射为音频帧的整数的设备,则该设备受其支持的各种音频格式的限制。 当然,具有此限制的设备仍应能够处理一个音频帧大小,其幂为 2。
例如,具有四个声道和 16 位样本大小的设备需要 8 个字节的音频帧大小。 音频帧的整数完全适合在页面内(或任何其他分配帧大小是 8 个字节的倍数)。 但是,对于具有 16 位样本的 5.1 声道流,音频帧大小为 12 字节,并且超过单个页面大小的流必然包含跨页边界的音频帧。 (波次筛选器中的数字说明了这个问题。)无法处理任意字节对齐和任意字节长度映射的硬件必须依赖于驱动程序来执行中间副本,而这会降低性能。
Microsoft Windows 驱动程序工具包 (WDK) 中的 Ac97 示例适配器驱动程序将实现 GetAllocatorFraming 方法。 微型端口驱动程序使用此方法传达其首选帧分配大小。 在 Windows 2000 和 Windows Me 中,端口驱动程序仅在在输出引脚上方实例化拆分器系统驱动程序 (Splitter.sys) 时才调用此方法。 在 Windows XP 及更高版本中,端口驱动程序也会为输入流调用此方法。 请记住,在决定帧分配大小时,SysAudio 可能会选择忽略微型端口驱动程序的首选项。