Audio Position, proprietà
Il client di un driver audio usa la proprietà KSPROPERTY_AUDIO_POSITION per ottenere e impostare la posizione corrente in un flusso audio. La proprietà usa una struttura KSAUDIO_POSITION per descrivere la posizione corrente. La struttura contiene due membri: PlayOffset e WriteOffset.
I membri PlayOffset e WriteOffset definiscono i limiti dell'area del buffer client attualmente riservato per l'uso esclusivo del dispositivo audio. Il client deve presupporre che il dispositivo possa attualmente accedere a uno dei dati contenuti in questa area. Di conseguenza, il client deve accedere solo alle parti del buffer che si trovano all'esterno di questa area. I limiti dell'area si spostano man mano che il flusso avanza.
Se il buffer client viene eseguito in ciclo( ovvero, il tipo di flusso è KSINTERFACE_STANDARD_LOOPED_STREAMING), PlayOffset e WriteOffset sono offset relativi al buffer. Ovvero, vengono specificati come offset di byte dall'inizio del buffer client ciclo. Quando entrambi gli offset aumentano alla fine del buffer, viene eseguito il wrapping all'inizio del buffer. L'offset all'inizio del buffer è zero. Pertanto, nessuno dei due offset supera mai le dimensioni del buffer.
Se il buffer client è nonlooped, ovvero il tipo di flusso è KSINTERFACE_STANDARD_STREAMING, PlayOffset e WriteOffset sono offset relativi al flusso. Ovvero, vengono specificati come offset di byte dall'inizio del flusso. Questi offset possono essere considerati come offset in un buffer idealizzato che contiene l'intero flusso ed è contiguo dall'inizio alla fine.
Nel caso di un flusso di rendering, il membro PlayOffset specifica la posizione di riproduzione del flusso e il membro WriteOffset specifica la posizione di scrittura del flusso. La figura seguente mostra le posizioni di riproduzione e scrittura in un buffer client.
La posizione di riproduzione è l'offset di byte dell'esempio attualmente in fase di riproduzione, ovvero l'esempio che viene latchato all'input del convertitore digitale-analogico o dell'applicazione livello dati. La posizione di scrittura è la posizione oltre la quale il client può scrivere in modo sicuro nel buffer. Durante la riproduzione del flusso, le posizioni di riproduzione e scrittura passano da sinistra a destra nella figura precedente. Le scritture del client devono rimanere in anticipo sulla posizione di scrittura. Inoltre, se il buffer viene eseguito in ciclo, le scritture del client non devono mai superare la posizione di gioco.
Anche se il driver della porta WaveCyclic o WavePci si basa sul driver miniport per tenere traccia della posizione di gioco, il driver porta tiene traccia della posizione di scrittura. I driver di porta WaveCyclic e WavePci aggiornano la posizione di scrittura come indicato di seguito:
WaveCyclic
Ogni volta che il driver di porta WaveCyclic chiama IDmaChannel::CopyTo per copiare un nuovo blocco di dati nel buffer ciclico (dal buffer client), la posizione di scrittura passa alla posizione (nel buffer client) dell'ultimo byte nel blocco dati.
WavePci
Per impostazione predefinita, ogni volta che il driver miniport WavePci chiama IPortWavePciStream::GetMapping per acquisire un nuovo mapping (di una parte del buffer client) e la chiamata ha esito positivo, la posizione di scrittura passa alla posizione (nel buffer client) dell'ultimo byte nel nuovo mapping.
Se il driver miniport WavePci esegue l'override del comportamento predefinito specificando un offset di prefetch al driver della porta, la posizione di scrittura corrente è sempre uguale alla somma della posizione di riproduzione corrente e dell'offset di prefetch. Per altre informazioni, vedere Offset di prefetch.
Nel caso di un flusso di acquisizione, il membro PlayOffset specifica la posizione del record del flusso e il membro WriteOffset specifica la posizione di lettura del flusso. Nella figura seguente viene illustrato il record e le posizioni di lettura in un buffer client.
La posizione del record è l'offset di byte dell'ultimo campione da latch all'output del convertitore analogico a digitale o adC. Questa posizione specifica il percorso del buffer in cui il motore DMA del dispositivo audio scriverà infine l'esempio. La posizione di lettura è la posizione oltre la quale il client non può leggere in modo sicuro dal buffer. Quando la registrazione del flusso procede, le posizioni di lettura e record passano da sinistra a destra nella figura precedente. Le letture del client devono tracciare la posizione di lettura. Inoltre, se il buffer viene eseguito in ciclo, le letture del client devono rimanere in anticipo sulla posizione del record.
Anche se il driver della porta WaveCyclic o WavePci si basa sul driver miniport per tenere traccia della posizione del record, il driver porta tiene traccia della posizione di lettura. I driver della porta WaveCyclic e WavePci aggiornano la posizione di lettura come indicato di seguito:
WaveCyclic
Ogni volta che il driver di porta WaveCyclic chiama IDmaChannel::CopyFrom per copiare un nuovo blocco di dati dal buffer ciclico (al buffer client), la posizione di lettura passa alla posizione (nel buffer client) dell'ultimo byte nel blocco di dati.
WavePci
Ogni volta che il driver miniport WavePci chiama IPortWavePciStream::ReleaseMapping per rilasciare un mapping acquisito in precedenza (di una parte del buffer client), la posizione di lettura passa alla posizione (nel buffer client) dell'ultimo byte nel mapping rilasciato.
I driver miniport non devono implementare le routine del gestore per le richieste di proprietà KSPROPERTY_AUDIO_POSITION. Al contrario, i driver di porta WaveCyclic e WavePci gestiscono queste richieste per conto dei driver miniport. Quando si gestisce una richiesta get-property, un driver di porta WaveCyclic o WavePci ha già tutte le informazioni necessarie per calcolare il valore WriteOffset , ma richiede comunque informazioni dal driver miniport per calcolare il valore PlayOffset . Per ottenere queste informazioni, il driver di porta chiama il metodo IMiniportWaveCyclicStream::GetPosition o IMiniportWavePciStream::GetPosition .
Per un flusso di rendering, il metodo GetPosition recupera la posizione di riproduzione, ovvero l'offset di byte dell'esempio attualmente riprodotto tramite l'applicazione livello dati. Per un flusso di acquisizione, il metodo GetPosition recupera la posizione del record: l'offset di byte dell'esempio più recente da acquisire da ADC.
Si noti che il valore di offset recuperato da una chiamata GetPosition è una posizione di riproduzione corrispondente al segnale attualmente trasmesso tramite il jack dell'altoparlante o una posizione di record corrispondente al segnale attualmente ricevuto tramite il jack del microfono. Non è la posizione DMA. La posizione DMA è l'offset di byte dell'esempio che il motore DMA nel dispositivo audio sta attualmente trasferendo o dal buffer DMA.
Alcuni hardware audio contengono un registro posizione per tenere traccia dell'offset di byte dell'esempio attualmente in ogni applicazione livello dati o ADC, nel qual caso il metodo GetPosition recupera semplicemente il contenuto del registro di posizione per il flusso appropriato. Altri hardware audio possono fornire solo il driver con la posizione DMA, nel qual caso il metodo GetPosition deve fornire una stima migliore dell'offset di byte del campione nell'applicazione livello dati o ADC tenendo conto della posizione DMA corrente e dei ritardi di buffer interni al dispositivo.
Anche se il gestore delle proprietà nel driver di porta WaveCyclic o WavePci deve distinguere tra buffer ciclici e nonlooped per determinare se fornire un offset di byte relativo o relativo al flusso, questo dettaglio , ovvero se un buffer è ciclo o nonlooped, è trasparente al driver miniport.
Il metodo IMiniportWaveCyclicStream::GetPosition segnala sempre una posizione di riproduzione o record relativa al buffer indipendentemente dal fatto che il buffer client sia ciclo o nonlooped. Se il buffer client viene eseguito il ciclo, il gestore delle proprietà converte la posizione relativa al buffer segnalata dal driver miniport, espresso come offset nel buffer ciclico, in un offset nel buffer client, che il gestore scrive quindi nel membro PlayOffset . Se il buffer client è nonlooped, il gestore della proprietà converte la posizione di riproduzione relativa al buffer in una posizione di riproduzione relativa al flusso prima di scriverla nel membro PlayOffset .
Il metodo IMiniportWavePciStream::GetPosition segnala sempre una posizione di riproduzione o record relativa al flusso indipendentemente dal fatto che il buffer client sia ciclo o nonlooped. Se il buffer client viene eseguito in ciclo, il gestore della proprietà converte la posizione di riproduzione relativa al flusso in una posizione di riproduzione relativa al buffer (espressa come offset nel buffer client) prima di scriverla nel membro PlayOffset nella struttura KSAUDIO_POSITION nella richiesta di proprietà. Se il buffer client è nonlooped, il gestore della proprietà scrive la posizione relativa al flusso al membro PlayOffset .
La posizione di riproduzione o record è zero immediatamente dopo l'inizializzazione del flusso. Una transizione allo stato KSSTATE_STOP (vedere KSSTATE) reimposta la posizione su zero. Quando il flusso viene arrestato da una transizione da KSSTATE_RUN a KSSTATE_PAUSE o KSSTATE_ACQUIRE, la posizione viene bloccata. Non libera quando il flusso passa da KSSTATE_PAUSE o KSSTATE_ACQUIRE indietro a KSSTATE_RUN.
Ad esempio, le implementazioni dei metodi GetPosition per i driver miniport WaveCyclic e WavePci, vedere i driver audio di esempio in Windows Driver Kit (WDK).