Udostępnij przez


Właściwość Pozycji dźwięku

Klient sterownika audio używa właściwości KSPROPERTY_AUDIO_POSITION w celu pobrania i ustawienia bieżącej pozycji w strumieniu audio. Właściwość używa struktury KSAUDIO_POSITION do opisania bieżącej pozycji. Struktura zawiera dwa elementy członkowskie: PlayOffset i WriteOffset.

Elementy PlayOffset i WriteOffset określają granice obszaru buforu klienta, który jest obecnie zarezerwowany wyłącznie do użytku przez urządzenie audio. Klient musi założyć, że urządzenie może obecnie uzyskiwać dostęp do dowolnego z danych zawartych w tym regionie. W związku z tym klient musi uzyskać dostęp tylko do części buforu, które znajdują się poza tym regionem. Granice regionu są przenoszone wraz z postępem strumienia.

Jeśli bufor klienta jest w pętli (czyli typ strumienia to KSINTERFACE_STANDARD_LOOPED_STREAMING), przesunięcia PlayOffset i WriteOffset są względne względem buforu. Oznacza to, że są one określane jako przesunięcia bajtów od początku buforu pętli klienta. Kiedy przesunięcie dochodzi do końca bufora, przechodzi z powrotem na początek bufora. (Przesunięcie na początku buforu wynosi zero). W związku z tym żadne przesunięcie nigdy nie przekracza rozmiaru buforu.

Jeśli bufor klienta jest nieloopowany (czyli typ strumienia jest KSINTERFACE_STANDARD_STREAMING), PlayOffset i WriteOffset są przesunięciami względnymi strumienia. Oznacza to, że są one określane jako przesunięcia byte'ów od początku strumienia. Te przesunięcia można traktować jako przesunięcia do idealizowanego buforu, który zawiera cały strumień i jest ciągły od początku do końca.

W przypadku strumienia renderowania element członkowski PlayOffset określa pozycję odtwarzania strumienia, a element członkowski WriteOffset określa pozycję zapisu strumienia. Ilustracja poniżej pokazuje pozycje odtwarzania i zapisu w buforze klienta.

Diagram ilustrujący pozycje odtwarzania i zapisu w strumieniu renderowania.

Pozycja odtwarzania to przesunięcie bajtu próbki, która jest aktualnie odtwarzana, czyli próbki znajdującej się na wejściu przetwornika cyfrowo-analogowego (DAC). Pozycja zapisu to pozycja, poza którą klient może bezpiecznie zapisywać w buforze. W miarę odtwarzania strumienia, pozycje odtwarzania i zapisu przesuwają się od lewej do prawej na poprzednim diagramie. Zapis klienta musi wyprzedzać pozycję zapisu. Ponadto, jeśli bufor jest zapętlony, zapisy klienta nigdy nie mogą wyprzedzić pozycji odtwarzania.

Mimo że sterownik portu WaveCyclic lub WavePci opiera się na sterowniku miniportu, aby śledzić pozycję odtwarzania, sterownik portu śledzi położenie zapisu. Sterowniki portów WaveCyclic i WavePci aktualizują położenie zapisu w następujący sposób:

  • WaveCyclic

    Za każdym razem, gdy sterownik portu WaveCyclic wywołuje element IDmaChannel::CopyTo , aby skopiować nowy blok danych do buforu cyklicznego (z buforu klienta), pozycja zapisu przechodzi do lokalizacji (w buforze klienta) ostatniego bajtu w bloku danych.

  • WavePci

    Domyślnie za każdym razem, gdy sterownik miniportu WavePci wywołuje IPortWavePciStream::GetMapping, aby uzyskać nowe mapowanie (porcję buforu klienta) i gdy wywołanie to zakończy się powodzeniem, pozycja zapisu przesuwa się do lokalizacji ostatniego bajtu (w buforze klienta) w nowym mapowaniu.

    Jeśli sterownik miniportu WavePci zastępuje domyślne zachowanie, określając przesunięcie wstępne dla sterownika portu, bieżąca pozycja zapisu jest zawsze równa sumie bieżącej pozycji odtwarzania i przesunięcia wstępnego. Aby uzyskać więcej informacji, zobacz Przesunięcia przed pobraniem.

W przypadku strumienia przechwytywania element członkowski PlayOffset określa położenie rekordu strumienia, a element członkowski WriteOffset określa pozycję odczytu strumienia. Na poniższej ilustracji przedstawiono rekord i pozycje odczytu w buforze klienta.

Diagram ilustrujący pozycje zapisu i odczytu w strumieniu przechwytywania.

Pozycja rekordu to offset bajtu najnowszej próbki, która ma zostać zatrzaśniętą na wyjściu konwertera analogowo-cyfrowego lub ADC. (To położenie określa lokalizację buforu, w której silnik DMA urządzenia audio ostatecznie zapisze próbkę.) Pozycja odczytu to pozycja, poza którą klient nie może bezpiecznie odczytać z buforu. W miarę postępu rejestrowania strumienia pozycje odczytu i rekordu przechodzą od lewej do prawej na poprzedniej ilustracji. Odczyty klienta muszą podążać za pozycją odczytu. Ponadto, jeśli bufor jest zapętlony, odczyty klienta muszą pozostać przed pozycją rekordu.

Chociaż sterownik portu WaveCyclic lub WavePci opiera się na sterowniku miniportu, aby śledzić pozycję nagrania, sterownik portu śledzi pozycję odczytu. Sterowniki portów WaveCyclic i WavePci aktualizują pozycję odczytu w następujący sposób:

  • WaveCyclic

    Za każdym razem, gdy sterownik portu WaveCyclic wywołuje element IDmaChannel::CopyFrom , aby skopiować nowy blok danych z buforu cyklicznego (do buforu klienta), pozycja odczytu przechodzi do lokalizacji (w buforze klienta) ostatniego bajtu w bloku danych.

  • WavePci

    Za każdym razem, gdy sterownik miniportu WavePci wywołuje element IPortWavePciStream::ReleaseMapping, aby zwolnić wcześniej pozyskane mapowanie części buforu klienta, pozycja odczytu przesuwa się do lokalizacji ostatniego bajtu w zwolnionym mapowaniu (w buforze klienta).

Sterowniki Miniport nie muszą implementować procedur obsługi dla żądań właściwości KSPROPERTY_AUDIO_POSITION. Zamiast tego sterowniki portów WaveCyclic i WavePci obsługują te żądania w imieniu sterowników miniportu. W przypadku obsługi żądania get-property sterownik portu WaveCyclic lub WavePci ma już wszystkie informacje potrzebne do obliczenia wartości WriteOffset , ale nadal potrzebuje informacji ze sterownika miniportu, aby obliczyć wartość PlayOffset . Aby uzyskać te informacje, sterownik portu wywołuje metodę IMiniportWaveCyclicStream::GetPosition lub IMiniportWavePciStream::GetPosition .

W przypadku strumienia renderowania metoda GetPosition pobiera pozycję odtwarzania — przesunięcie bajtowe próbki, która jest obecnie odtwarzana przez DAC. W przypadku strumienia przechwytywania, metoda GetPosition pobiera położenie zapisu — przesunięcie bajtowe najnowszej próbki zarejestrowanej przez przetwornik ADC.

Należy pamiętać, że wartość przesunięcia pobrana przez wywołanie GetPosition jest pozycją odtwarzania odpowiadającą sygnałowi aktualnie przesyłanemu za pośrednictwem gniazda głośnika lub pozycji rekordu odpowiadającej sygnałowi aktualnie odbieranemu za pośrednictwem gniazda mikrofonu. Nie jest to pozycja DMA. (Pozycja DMA to przesunięcie bajtów próbki, którą silnik DMA w urządzeniu audio obecnie przesyła do lub z bufora DMA).

Niektóre urządzenia audio zawierają rejestr położenia, aby śledzić przesunięcie bajtowe próbki aktualnie znajdującej się w każdym DAC lub ADC, w tym przypadku metoda GetPosition po prostu pobiera zawartość rejestru położenia dla odpowiedniego strumienia. Inny sprzęt audio może dostarczyć sterownikowi jedynie informację o położeniu DMA, w takim przypadku metoda GetPosition powinna dostarczyć jak najlepsze oszacowanie przesunięcia bajtu próbki w DAC lub ADC, przy uwzględnieniu bieżącego położenia DMA oraz wewnętrznych opóźnień buforowania urządzenia.

Mimo że program obsługi właściwości w sterowniku portów WaveCyclic lub WavePci musi rozróżniać zapętlone i niezapętlone bufory, aby określić, czy podać wartość przesunięcia bajtu względem strumienia czy buforu, ten szczegół (tj. czy bufor jest zapętlony, czy niezapętlony) jest przezroczysty dla sterownika miniportu.

Metoda IMiniportWaveCyclicStream::GetPosition zawsze zgłasza pozycję odtwarzania lub nagrywania relatywną względem bufora, niezależnie od tego, czy bufor klienta jest zapętlony, czy niezapętlony. Jeśli bufor klienta jest zapętlony, obsługa właściwości konwertuje położenie względne buforu raportowane przez sterownik miniportu, które jest wyrażone jako przesunięcie w buforze cyklicznym, na przesunięcie względem buforu klienta, które następnie zapisuje do elementu członkowskiego PlayOffset. Jeśli bufor klienta jest niezloopowany, obsługujący właściwości konwertuje pozycję odtwarzania względną bufora na pozycję odtwarzania względną strumienia przed zapisaniem jej do elementu członkowskiego PlayOffset.

Metoda IMiniportWavePciStream::GetPosition zawsze zgłasza pozycję odtwarzania lub nagrywania względem strumienia, niezależnie od tego, czy bufor klienta jest zapętlony, czy niezapętlony. Jeśli bufor klienta jest w pętli, obsługiwacz właściwości konwertuje pozycję odtwarzania względną strumienia na pozycję odtwarzania względną buforu (wyrażoną jako przesunięcie w buforze klienta) przed zapisaniem jej do elementu członkowskiego PlayOffset w strukturze KSAUDIO_POSITION w żądaniu właściwości. Jeśli bufor klienta jest niezapętlony, obsługiwacz właściwości zapisuje położenie względne strumienia do elementu członkowskiego PlayOffset.

Pozycja odtwarzania lub nagrywania wynosi zero bezpośrednio po zainicjowaniu strumienia. Przejście do stanu KSSTATE_STOP (zobacz KSSTATE) resetuje pozycję do zera. Gdy strumień zostanie zatrzymany przez przejście z KSSTATE_RUN do KSSTATE_PAUSE lub KSSTATE_ACQUIRE, pozycja zamraża się. Odmrozi się, gdy strumień przechodzi z KSSTATE_PAUSE lub KSSTATE_ACQUIRE z powrotem do KSSTATE_RUN.

Na przykład implementacje metod GetPosition dla sterowników miniportów WaveCyclic i WavePci, zobacz przykładowe sterowniki audio w zestawie sterowników dla systemu Windows (WDK).