Partager via


Audio Position Propriété

Le client d’un pilote audio utilise la propriété KSPROPERTY_AUDIO_POSITION pour obtenir et définir la position actuelle dans un flux audio. La propriété utilise une structure KSAUDIO_POSITION pour décrire la position actuelle. La structure contient deux membres : PlayOffset et WriteOffset.

Les membres PlayOffset et WriteOffset définissent les limites de la région de la mémoire tampon cliente actuellement réservée à l’utilisation exclusive de l’appareil audio. Le client doit supposer que l’appareil peut actuellement accéder à l’une des données contenues dans cette région. Par conséquent, le client doit accéder uniquement aux parties de la mémoire tampon qui se trouvent en dehors de cette région. Les limites de la région se déplacent à mesure que le flux avance.

Si la mémoire tampon du client est bouclée (autrement dit, le type de flux est KSINTERFACE_STANDARD_LOOPED_STREAMING), PlayOffset et WriteOffset sont des décalages relatifs à la mémoire tampon. Autrement dit, ils sont spécifiés en tant que décalages d’octets à partir du début de la mémoire tampon du client en boucle. Lorsque l’un des décalages est incrémenté à la fin de la mémoire tampon, il s’encapsule au début de la mémoire tampon. (Le décalage au début de la mémoire tampon est égal à zéro.) Par conséquent, aucun décalage ne dépasse jamais la taille de la mémoire tampon.

Si la mémoire tampon du client n’est pas en boucle (autrement dit, le type de flux est KSINTERFACE_STANDARD_STREAMING), PlayOffset et WriteOffset sont des décalages relatifs au flux. Autrement dit, ils sont spécifiés en tant que décalages d’octets à partir du début du flux. Ces décalages peuvent être considérés comme des décalages dans une mémoire tampon idéalisée qui contient le flux entier et qui est contigu du début à la fin.

Dans le cas d’un flux de rendu, le membre PlayOffset spécifie la position de lecture du flux et le membre WriteOffset spécifie la position d’écriture du flux. La figure suivante montre les positions de lecture et d’écriture dans une mémoire tampon cliente.

Diagramme illustrant les positions de lecture et d’écriture dans un flux de rendu.

La position de lecture est le décalage d’octet de l’échantillon en cours de lecture (autrement dit, l’échantillon qui est bloqué à l’entrée du convertisseur numérique à analogique ou DAC). La position d’écriture est la position au-delà de laquelle le client peut écrire en toute sécurité dans la mémoire tampon. À mesure que le flux est lu, les positions de lecture et d’écriture passent de gauche à droite dans la figure précédente. Les écritures du client doivent rester en avance sur la position d'écriture. En outre, si la mémoire tampon est bouclée, les écritures du client ne doivent jamais dépasser la position de lecture.

Bien que le pilote de port WaveCyclique ou WavePci s’appuie sur le pilote miniport pour suivre la position de jeu, le pilote de port suit la position d’écriture. Les pilotes de port WaveCyclique et WavePci mettent à jour la position d’écriture comme suit :

  • WaveCyclique

    Chaque fois que le pilote de port WaveCyclique appelle IDmaChannel ::CopyTo pour copier un nouveau bloc de données dans la mémoire tampon cyclique (à partir de la mémoire tampon du client), la position d’écriture avance vers l’emplacement (dans la mémoire tampon du client) du dernier octet du bloc de données.

  • WavePci

    Par défaut, chaque fois que le pilote Miniport WavePcici appelle IPortWavePciStream ::GetMapping pour acquérir un nouveau mappage (d’une partie de la mémoire tampon du client) et que l’appel réussit, la position d’écriture avance vers l’emplacement (dans la mémoire tampon du client) du dernier octet du nouveau mappage.

    Si le pilote miniport WavePci remplace le comportement par défaut en spécifiant un décalage de prérécupération au pilote de port, la position d’écriture actuelle est toujours égale à la somme de la position de lecture actuelle et du décalage de prérécupération. Pour plus d’informations, consultez Décalages de prérécupération.

Dans le cas d’un flux de capture, le membre PlayOffset spécifie la position d’enregistrement du flux et le membre WriteOffset spécifie la position de lecture du flux. La figure suivante montre les positions d’enregistrement et de lecture dans une mémoire tampon cliente.

Diagramme illustrant les positions d’enregistrement et de lecture dans un flux de capture.

La position de l’enregistrement correspond au décalage d’octet du dernier échantillon à mettre en verrou à la sortie du convertisseur analogique-à-numérique ou DDC. (Cette position spécifie l’emplacement de la mémoire tampon dans lequel le moteur DMA de l’appareil audio écrit l’exemple.) La position de lecture est la position au-delà de laquelle le client ne peut pas lire en toute sécurité à partir de la mémoire tampon. À mesure que l’enregistrement du flux progresse, les positions de lecture et d’enregistrement avancent de gauche à droite dans la figure précédente. Les lectures du client doivent suivre la position de lecture. En outre, si la mémoire tampon est bouclée, les lectures du client doivent devancer la position d'enregistrement.

Bien que le pilote de port WaveCyclique ou WavePci s’appuie sur le pilote miniport pour suivre la position d’enregistrement, le pilote de port suit la position de lecture. Les pilotes de port WaveCyclique et WavePci mettent à jour la position de lecture comme suit :

  • WaveCyclique

    Chaque fois que le pilote de port WaveCyclique appelle IDmaChannel ::CopyFrom pour copier un nouveau bloc de données à partir de la mémoire tampon cyclique (vers la mémoire tampon cliente), la position de lecture avance à l’emplacement (dans la mémoire tampon du client) du dernier octet du bloc de données.

  • WavePci

    Chaque fois que le pilote miniport WavePci appelle IPortWavePciStream ::ReleaseMapping pour libérer un mappage précédemment acquis (d’une partie de la mémoire tampon du client), la position de lecture avance à l’emplacement (dans la mémoire tampon du client) du dernier octet dans le mappage libéré.

Les pilotes miniport n’ont pas besoin d’implémenter des routines de gestionnaire pour les demandes de la propriété KSPROPERTY_AUDIO_POSITION. Au lieu de cela, les pilotes de port WaveCyclique et WavePci gèrent ces demandes au nom des pilotes miniport. Lors de la gestion d’une requête get-property, un pilote de port WaveCyclique ou WavePci a déjà toutes les informations dont il a besoin pour calculer la valeur WriteOffset , mais il a toujours besoin d’informations du pilote miniport pour calculer la valeur PlayOffset . Pour obtenir ces informations, le pilote de port appelle la méthode IMiniportWaveCyclicStream::GetPosition ou IMiniportWavePciStream::GetPosition du pilote miniport.

Pour un flux de rendu, la méthode GetPosition récupère la position de lecture : le décalage d’octet de l’échantillon actuellement en cours de lecture via le DAC. Pour un flux de capture, la méthode GetPosition récupère la position d’enregistrement : décalage d’octet de l’exemple le plus récent à capturer par l’ADC.

Notez que la valeur de décalage récupérée par un appel GetPosition est soit une position de lecture correspondant au signal en cours de transmission via la prise du haut-parleur, soit une position d’enregistrement correspondant au signal actuellement reçu par le biais de la prise de microphone. Ce n'est pas la position de la DMA. (La position DMA est le décalage en octets de l'échantillon que le moteur DMA du périphérique audio est en train de transférer vers ou depuis le tampon DMA.)

Certains matériels audio contiennent un registre de position pour suivre le décalage d’octet de l’exemple actuellement dans chaque DAC ou ADC, auquel cas la méthode GetPosition récupère simplement le contenu du registre de position pour le flux approprié. D’autres matériels audio peuvent uniquement fournir au pilote la position DMA, auquel cas la méthode GetPosition doit fournir une estimation optimale du décalage d’octet de l’exemple dans la DAC ou ADC en tenant compte de la position DMA actuelle et des retards de mise en mémoire tampon internes à l’appareil.

Bien que le gestionnaire de propriétés dans le pilote de port WaveCyclique ou WavePci doit faire la distinction entre les mémoires tampons bouclées et nonloops pour déterminer s’il faut fournir un décalage d’octet relatif au flux ou à la mémoire tampon, ce détail (autrement dit, si une mémoire tampon est en boucle ou nonloop) est transparent pour le pilote miniport.

La méthode IMiniportWaveCyclicStream::GetPosition signale toujours une position de lecture ou d’enregistrement relative à la mémoire tampon, que la mémoire tampon du client soit en boucle ou non-en-boucle. Si la mémoire tampon du client est bouclée, le gestionnaire de propriétés convertit la position relative de la mémoire tampon signalée par le pilote miniport, qui est exprimée sous forme de décalage dans la mémoire tampon cyclique, en un décalage dans la mémoire tampon du client, que le gestionnaire écrit dans le membre PlayOffset. Si la mémoire tampon du client n’est pas en boucle, le gestionnaire de propriétés convertit la position de lecture relative au tampon en position de lecture relative au flux avant de l’écrire dans le membre PlayOffset.

La méthode IMiniportWavePciStream::GetPosition signale toujours une position de lecture ou d’enregistrement relative au flux, que la mémoire tampon du client soit en boucle ou non en boucle. Si la mémoire tampon du client est bouclée, le gestionnaire de propriétés convertit la position de lecture relative du flux en position de lecture relative de mémoire tampon (exprimée sous forme de décalage dans la mémoire tampon du client) avant de l’écrire dans le membre PlayOffset dans la structure KSAUDIO_POSITION dans la requête de propriété. Si la mémoire tampon du client n’est pas activée, le gestionnaire de propriétés écrit la position relative du flux dans le membre PlayOffset .

La position de lecture ou d’enregistrement est égale à zéro immédiatement après l’initialisation du flux. Une transition vers l’état KSSTATE_STOP (voir KSSTATE) réinitialise la position à zéro. Lorsque le flux est arrêté par une transition de KSSTATE_RUN à KSSTATE_PAUSE ou KSSTATE_ACQUIRE, la position se bloque. Il n’est pas rare lorsque le flux passe de KSSTATE_PAUSE ou de KSSTATE_ACQUIRE à KSSTATE_RUN.

Pour obtenir des exemples d’implémentations de méthodes GetPosition pour les pilotes Miniport WaveCyclique et WavePci, consultez les exemples de pilotes audio dans le Kit de pilotes Windows (WDK).