延迟时钟

合成器微型端口驱动程序模型旨在允许在多个设备之间同步音频输出。 因此,它包含比纯 UART 设备提供的更复杂的计时模型。

事件连同关联的时间戳一起被传递到微型端口驱动程序,并从中被捕获。 此时间戳相对于 主时钟。 主时钟是整个系统中所有时序使用的相同时钟。 主时钟时间以 100 纳秒刻度为单位测量。

微型端口驱动程序通过调用 IMasterClock::GetTime 从主时钟获取当前时间。 在引脚创建时,端口驱动程序将内核模式 IMasterClock 接口作为 IMiniportDMus::NewStream 方法的输入参数之一传递给微型端口驱动程序。 目前,主时钟负责协调系统实时时钟。 当有引脚需要主时钟处于运行状态时,主时钟永远不会更改。 它是永不暂停的常量速率时钟。

所有呈现设备在接受事件的时间和可以听到事件的时间之间都有一定的延迟。 此延迟可以是常量或可变(如软件合成器的情况),其中延迟取决于音频缓冲区的当前播放位置。 此延迟由以下方式进行补偿:

  • 允许 DMus 微型端口驱动程序提前足够时间接收事件,以便可以及时播放,即使设备存在延迟。 事件由 DMus 端口驱动程序中的 sequencer 引擎为微型端口驱动程序排序。

    在引脚创建时,端口驱动程序以 100 纳秒为单位查询微型端口驱动程序的增量时间。 增量时间表示微型端口驱动程序希望在事件呈现时间之前多长时间接收该事件。 端口驱动程序尽最大努力提前处理事件。 指定此增量非常大的值(通过 SchedulePreFetch 参数在 IMiniportDMus::NewStream 中指定)会导致端口驱动程序在事件从用户模式传递到端口驱动程序后立即将事件传递给微型端口驱动程序。

  • 通知应用程序提前多久计划事件。 在这种情况下,不需要使用最大延迟。 由于提交事件后无法取消,因此越接近事件呈现时间提交,应用程序与合成器的交互响应会越及时。 为了处理此要求,DirectMusic 引入了延迟时钟的概念。

    延迟性时钟提供了将来最接近的可安排时间,当事件被计划在此时间播放时,仍能按时播放。 换句话说,如果应用程序根据延迟时钟计划在当前时间之前播放的事件,则事件将延迟播放。 合成器微型端口驱动程序通过响应 KSPROPERTY_SYNTH_LATENCYCLOCK 属性项来提供延迟时钟。

    查询微型端口驱动程序 KSPROPSETID_Synth 和KSPROPERTY_SYNTH_LATENCYCLOCK。 微型端口驱动程序的属性处理程序应返回一个以主时钟为基准的延迟时钟,该时钟指定下次可以按计划时间呈现数据的时机。 例如,如果主时钟当前读取 50,并且当前有 25 个单位的延迟,则延迟时钟读取 75。 通过这种方式实现时钟的原因在于延迟不需要保持为常量,并且返回的值对应用程序的益处超越了仅仅的“delta”。