Freigeben über


Streamlatenz während der Wiedergabe

Während sich ein Audiowiedergabestream im Status Ausführen befindet, ist die Rolle des WaveRT-Porttreibers minimal. Wie im folgenden Diagramm gezeigt, schreibt der Client des WaveRT-Porttreibers seine Daten während der Wiedergabe in den zyklischen Puffer, und das Audiogerät liest diese Daten dann aus dem Puffer. Für diese Aktivität ist kein Eingreifen des Porttreibers erforderlich. Mit anderen Worten, Audiodaten fließen direkt zwischen der Benutzermodusanwendung und der Audiohardware, ohne dass von Irgendwelchen Kernelmodus-Softwarekomponenten berührt werden.

Im Diagramm werden die Schreib- und Wiedergabepositionen kontinuierlich von links nach rechts fortgesetzt, während der Audiodatenstrom den zyklischen Puffer durchläuft. Der Puffer wird als zyklischer Wert beschrieben, da wenn die Wiedergabeposition oder die Schreibposition das Ende des Puffers erreicht, automatisch bis zum Anfang des Puffers umschließt.

Die Streamlatenz während der Wiedergabe weist zwei Standard Quellen auf, die im folgenden Diagramm als A und B angegeben sind.

Diagramm, das die Latenz eines Wiedergabestreams mit Schreib- und Wiedergabepositionen in einem zyklischen Puffer zeigt.

Im obigen Diagramm ist die Schreibposition der Speicherort direkt hinter dem letzten Beispiel, das der Client in den Puffer geschrieben hat. Die Wiedergabeposition ist das Beispiel, das das Audiogerät derzeit über den Lautsprecher abgibt.

Die Latenz zwischen dem Zeitpunkt, zu dem der Client ein Audiobeispiel in den Puffer schreibt, bis das Audiogerät es wiedergibt, ist einfach die Trennung zwischen den Schreib- und Wiedergabepositionen. Diese Trennung ist die Summe der beiden folgenden Latenzquellen (im Diagramm als A und B gekennzeichnet):

Latenz A: Nachdem das Audiogerät Daten aus dem Puffer gelesen hat, befinden sich die Daten in einem FIFO-Puffer (First In, First Out), bis das Audiogerät die Daten über den Digital-/Analog-Wandler (DAC) taktet.

Latenz B: Nachdem der Client Daten in den zyklischen Puffer geschrieben hat, befinden sich die Daten im Puffer, bis das Audiogerät die Daten liest.

Der Client hat keine Kontrolle über Latenz A, die vollständig von der Hardware abhängt. Ein typischer FIFO kann genügend Proben speichern, um die DAC für etwa 64 Ticks der Beispieluhr zu füttern. Der Client steuert jedoch die Latenz B. Wenn latenz B zu groß ist, führt das System zu unnötigen Verzögerungen. Wenn Sie es jedoch zu klein machen, besteht die Gefahr, dass das Audiogerät erschöpft wird.

Obwohl der Client einen Timer einrichten kann, um seinen Pufferschreibthread regelmäßig zu aktivieren, erreicht diese Methode nicht die geringste Latenz. Um die Latenz weiter zu verringern, kann der Client das Gerät so konfigurieren, dass es jedes Mal eine Hardwarebenachrichtigung generiert, wenn das Gerät mit dem Lesen eines neuen Blocks von Wiedergabedaten aus dem Puffer fertig ist. In diesem Fall wird der Clientthread nicht durch einen Timer, sondern durch Hardwarebenachrichtigungen aktiviert.

Wenn das Audiogerät den Client jedes Mal benachrichtigt, wenn es mit dem Lesen eines Datenblocks aus dem Puffer fertig ist, kann der Client die Latenz verringern, als es andernfalls praktisch wäre.

Der Client kann eine Zusammenfassung der Verzögerungen erhalten, die zur Streamlatenz beitragen, indem er eine KSPROPERTY_RTAUDIO_HWLATENCY Anforderung an den WaveRT-Porttreiber sendet.

Nachdem der Client den Umfang der Trennung zwischen den Schreib- und Wiedergabepositionen bestimmt hat, überwacht der Client Änderungen an der Wiedergabeposition, um zu bestimmen, wie weit die Schreibposition vor sich gehen soll. Unter Windows Server 2008 und höher sendet der Client eine KSPROPERTY_RTAUDIO_POSITIONREGISTER Eigenschaftsanforderung, um die Wiedergabeposition zu bestimmen. Unterstützung für dieses Feature wird durch Verbesserungen im PortCls-Systemtreiber bereitgestellt.

Wenn das Audiogerät wie im vorherigen Diagramm dargestellt über ein Positionsregister verfügt, ordnet die Eigenschaftsanforderung das Register einer virtuellen Speicheradresse zu, auf die der Client im Benutzermodus zugreifen kann. Nachdem das Positionsregister zugeordnet wurde, kann der Client den Inhalt der Speicheradresse lesen, um die aktuelle Wiedergabeposition zu bestimmen.