Freigeben über


Latenzuhren

Das Synthesizer-Miniporttreibermodell wurde entwickelt, um die Synchronisierung der Audioausgabe zwischen mehreren Geräten zu ermöglichen. Daher enthält es ein komplexeres Timing-Modell als das, das von einem reinen UART-Gerät bereitgestellt wird.

Ereignisse werden mit einem zugeordneten Zeitstempel an den Miniporttreiber übermittelt und von diesem erfasst. Dieser Zeitstempel ist relativ zu einer Masteruhr. Die Masteruhr ist die gleiche Uhr, die von allen Sequenzierungen im gesamten System verwendet wird. Die Masteruhrzeit wird in Einheiten von 100-Nanosekunden-Ticks gemessen.

Der Miniporttreiber ruft die aktuelle Uhrzeit von der Masteruhr ab, indem IMasterClock::GetTime aufgerufen wird. Zur Pinerstellung übergibt der Porttreiber die Kernelmodus-IMasterClock-Schnittstelle als einen der Eingabeparameter an die IMiniportDMus::NewStream-Methode an den Miniporttreiber . Derzeit umschließt die Masteruhr die System-Echtzeituhr. Die Masteruhr ändert sich nie, wenn pins vorhanden sind, die erfordern, dass sie sich im Ausführungszustand befinden. Es ist eine konstante Taktuhr, die nie angehalten wird.

Alle Renderinggeräte haben eine gewisse Latenz zwischen dem Zeitpunkt, zu dem sie ein Ereignis akzeptieren, und dem Zeitpunkt, zu dem das Ereignis gehört werden kann. Diese Latenz kann konstant oder variabel sein (wie bei einem Softwaresynthesizer, wobei die Latenz von der aktuellen Wiedergabeposition des Audiopuffers abhängt). Diese Latenz wird durch Folgendes kompensiert:

  • Der DMus-Miniporttreiber kann Ereignisse weit genug im Voraus empfangen, damit sie trotz der Latenz des Geräts rechtzeitig wiedergegeben werden können. Ereignisse werden für den Miniporttreiber durch ein Sequenzermodul im DMus-Porttreiber sequenziert.

    Zum Zeitpunkt der Pinerstellung fragt der Porttreiber den Miniporttreiber nach einer Delta-Zeit in 100-Nanosekundeneinheiten ab. Diese Delta-Zeit ist, wie weit vor der Präsentation jedes Ereignisses der Miniporttreiber das Ereignis empfangen möchte. Der Porttreiber bemüht sich am besten, Ereignisse so weit voraus zu liefern. Wenn Sie einen sehr großen Wert für dieses Delta angeben (angegeben durch den SchedulePreFetch-Parameter von IMiniportDMus::NewStream), übergibt der Porttreiber die Ereignisse an den Miniporttreiber, sobald er vom Benutzermodus an den Porttreiber übermittelt wird.

  • Um Anwendungen darüber zu informieren, wie weit voraus Ereignisse geplant werden sollen. Die Verwendung der maximalen Latenz ist in diesem Fall nicht wünschenswert. Je näher Ereignisse an der Präsentationszeit übermittelt werden können, desto reaktionsfähiger kann die Anwendung mit dem Synthesizer interagieren, da Ereignisse nach der Übermittlung nicht mehr abgebrochen werden können. Um diese Anforderung zu erfüllen, hat DirectMusic das Konzept einer Latenzuhr eingeführt.

    Die Latenzuhr gibt die nächste Zeit in der Zukunft an, zu der ein Ereignis geplant werden kann, um es noch rechtzeitig abzuspielen. Anders ausgedrückt: Wenn die Anwendung ein Ereignis plant, das vor der aktuellen Zeit gemäß der Latenzuhr ausgeführt werden soll, dann wird das Ereignis zu spät ausgeführt. Synthesizer-Miniport-Treiber bieten eine Latenz-Uhr, indem sie auf das KSPROPERTY_SYNTH_LATENCYCLOCK-Eigenschaftselement reagieren.

    Der Miniporttreiber wird für KSPROPSETID_Synth und KSPROPERTY_SYNTH_LATENCYCLOCK abgefragt. Der Eigenschaftshandler des Miniporttreibers sollte einen Latenzzeitgeber zurückgeben, der im Bezug auf die Masteruhr die nächste mögliche Zeit festlegt, zu der die Daten rechtzeitig gerendert werden können. Wenn beispielsweise die Masteruhr derzeit 50 liest und derzeit 25 Latenzeinheiten vorhanden sind, liest die Latenzuhr 75. Der Grund, warum die Uhr auf diese Weise implementiert wird, ist, dass die Latenz nicht konstant sein muss, und der zurückgegebene Wert ist von mehr Verwendung für Anwendungen als nur das Delta.