共用方式為


音訊位置屬性

音訊驅動程式的用戶端會使用 KSPROPERTY_AUDIO_POSITION 屬性來取得和設定音訊資料流程中的目前位置。 屬性會使用 KSAUDIO_POSITION 結構來描述目前的位置。 結構包含兩個成員: PlayOffsetWriteOffset

PlayOffsetWriteOffset成員會定義目前保留供音訊裝置獨佔使用的用戶端緩衝區區域界限。 用戶端必須假設裝置目前可能存取此區域所包含的任何資料。 因此,用戶端只能存取位於此區域外的緩衝區部分。 區域界限會隨著資料流程前進而移動。

如果用戶端緩衝區 (迴圈,則資料流程類型會KSINTERFACE_STANDARD_LOOPED_STREAMING) PlayOffset 和 WriteOffset是緩衝區相對位移。 也就是說,它們會指定為迴圈用戶端緩衝區開頭的位元組位移。 當任一位移遞增至緩衝區結尾時,它會繞著緩衝區的開頭。 (緩衝區開頭的位移為零 ) 。因此,任何位移都不會超過緩衝區大小。

如果用戶端緩衝區不是 (,則資料流程類型會KSINTERFACE_STANDARD_STREAMING) ,PlayOffset 和WriteOffset是資料流程相對位移。 也就是說,它們會指定為數據流開頭的位元組位移。 這些位移可視為包含整個資料流程且從頭到尾的理想化緩衝區的位移。

在轉譯資料流程的情況下, PlayOffset 成員會指定資料流程的播放位置, 而 WriteOffset 成員會指定資料流程的寫入位置。 下圖顯示用戶端緩衝區中的播放和寫入位置。

說明轉譯資料流程中播放和寫入位置的圖表。

播放位置是目前現正播放之樣本的位元組位移 (,也就是在數位對類比轉換器的輸入或 DAC) 閂鎖的樣本。 寫入位置是用戶端可以安全地寫入緩衝區的位置。 當資料流程播放時,播放和寫入位置會從上圖的左至右移動。 用戶端的寫入必須保持在寫入位置之前。 此外,如果緩衝區是迴圈的,用戶端的寫入絕對不能超過播放位置。

雖然 WaveCyclic 或 WavePci 埠驅動程式依賴迷你埠驅動程式來追蹤播放位置,但埠驅動程式會持續追蹤寫入位置。 WaveCyclic 和 WavePci 埠驅動程式會更新寫入位置,如下所示:

  • WaveCyclic

    每次 WaveCyclic 埠驅動程式呼叫 IDmaChannel::CopyTo ,將新的資料區塊複製到用戶端緩衝區 (的迴圈緩衝區) 時,寫入位置會前進到用戶端緩衝區中最後一個位元組) 中的位置 (。

  • WavePci

    根據預設,每次 WavePci 迷你埠驅動程式呼叫 IPortWavePciStream::GetMapping 以取得用戶端緩衝區部分的新對應 () ,且呼叫成功時,寫入位置會前進 (到用戶端緩衝區中最後一個位元組) 中最後一個位元組的位置) 。

    如果 WavePci 迷你埠驅動程式藉由指定埠驅動程式的預先擷取位移來覆寫預設行為,則目前的寫入位置一律等於目前播放位置和預先擷取位移的總和。 如需詳細資訊,請參閱 預先擷取位移

在擷取資料流程的情況下, PlayOffset 成員會指定資料流程的記錄位置, 而 WriteOffset 成員會指定資料流程的讀取位置。 下圖顯示用戶端緩衝區中的記錄和讀取位置。

說明擷取資料流程中記錄和讀取位置的圖表。

記錄位置是最新樣本的位元組位移,要閂鎖在類比到數位轉換器或 ADC 的輸出上。 (此位置會指定音訊裝置的 DMA 引擎最終會寫入 sample.) 讀取位置是用戶端無法安全地從緩衝區讀取的位置。 當資料流程的錄製進行時,讀取和記錄位置會從上圖從左至右往右前進。 用戶端的讀取必須追蹤讀取位置。 此外,如果緩衝區是迴圈的,用戶端的讀取必須保持記錄位置的前面。

雖然 WaveCyclic 或 WavePci 埠驅動程式依賴迷你埠驅動程式來追蹤記錄位置,但埠驅動程式會持續追蹤讀取位置。 WaveCyclic 和 WavePci 埠驅動程式會更新讀取位置,如下所示:

  • WaveCyclic

    每次 WaveCyclic 埠驅動程式呼叫 IDmaChannel::CopyFrom ,將新的資料區塊從迴圈緩衝區 (複製到用戶端緩衝區) 時,讀取位置會前進至用戶端緩衝區中最後一個位元組) 中的位置 (。

  • WavePci

    每次 WavePci 迷你埠驅動程式呼叫 IPortWavePciStream::ReleaseMapping 以釋放先前取得的用戶端緩衝區 (部分的對應) 時,讀取位置會前進到用戶端緩衝區中 (的位置) 發行的對應。

迷你埠驅動程式不需要實作KSPROPERTY_AUDIO_POSITION屬性要求的處理常式常式。 相反地,WaveCyclic 和 WavePci 埠驅動程式會代表迷你埠驅動程式處理這些要求。 處理 get-property 要求時,WaveCyclic 或 WavePci 埠驅動程式已經有計算 WriteOffset 值所需的所有資訊,但仍需要迷你埠驅動程式的資訊來計算 PlayOffset 值。 若要取得這項資訊,埠驅動程式會呼叫迷你埠驅動程式的 IMiniportWaveCyclicStream::GetPositionIMiniportWavePciStream::GetPosition 方法。

針對轉譯資料流程, GetPosition 方法會擷取播放位置 - 目前透過 DAC 播放之樣本的位元組位移。 針對擷取資料流程, GetPosition 方法會擷取記錄位置 - ADC 所擷取之最新樣本的位元組位移。

請注意, GetPosition 呼叫所擷取的位移值是目前透過喇叭插接傳輸之訊號的播放位置,或是對應到目前透過麥克風插接器接收之訊號的錄製位置。 這不是 DMA 位置。 (DMA 位置是音訊裝置中 DMA 引擎目前傳輸至 DMA 緩衝區或從 DMA 緩衝區傳輸的位元組位移。)

某些音訊硬體包含位置暫存器,可追蹤目前在每個 DAC 或 ADC 中樣本的位元組位移,在此情況下, GetPosition 方法只會擷取適當資料流程的位置暫存器內容。 其他音訊硬體只能提供 DMA 位置的驅動程式,在此情況下, GetPosition 方法必須藉由考慮目前的 DMA 位置和裝置內部緩衝延遲,來提供最佳的樣本位元組位移估計。

雖然 WaveCyclic 或 WavePci 埠驅動程式中的屬性處理常式必須區分迴圈和非ooped 緩衝區,以判斷是否要提供資料流程相對或緩衝區相對位元組位移,但此詳細資料 (亦即,緩衝區是迴圈或非迴圈) 對迷你埠驅動程式而言是透明的。

不論用戶端緩衝區是迴圈還是非迴圈, IMiniportWaveCyclicStream::GetPosition 方法一律會報告緩衝區相對播放或記錄位置。 如果用戶端緩衝區是迴圈的,則屬性處理常式會將迷你埠驅動程式所報告的緩衝區相對位置,以迴圈緩衝區的位移表示為迴圈緩衝區的位移,再將處理常式寫入 PlayOffset 成員的用戶端緩衝區中。 如果用戶端緩衝區為非oop,則屬性處理常式會先將緩衝區相對播放位置轉換成資料流程相對播放位置,再將它寫入 PlayOffset 成員。

不論用戶端緩衝區是迴圈還是非迴圈, IMiniportWavePciStream::GetPosition 方法一律會報告資料流程相對播放或記錄位置。 如果用戶端緩衝區是迴圈的,屬性處理常式會將資料流程相對播放位置轉換成緩衝區相對播放位置, (以位移表示至用戶端緩衝區) ,然後再將它寫入屬性要求中KSAUDIO_POSITION 結構中的 PlayOffset 成員。 如果用戶端緩衝區為非oop,則屬性處理常式會將資料流程相對位置寫入 PlayOffset 成員。

播放或記錄位置在資料流程初始化後立即為零。 轉換至KSSTATE_STOP狀態 (請參閱 KSSTATE) 將位置重設為零。 當從KSSTATE_RUN轉換到KSSTATE_PAUSE或KSSTATE_ACQUIRE時,該位置會凍結。 當資料流程從KSSTATE_PAUSE或KSSTATE_ACQUIRE轉換回KSSTATE_RUN時,它會解除凍結。

如需 WaveCyclic 和 WavePci 迷你埠驅動程式之 GetPosition 方法的範例實作,請參閱 Windows 驅動程式套件中的範例音訊驅動程式 (WDK) 。