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 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 cliente est en boucle (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 cliente bouclée. Lorsque l’un des décalages est incrémenté à la fin de la mémoire tampon, il est encapsulé 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 la taille de la mémoire tampon.

Si la mémoire tampon cliente n’est pas activée (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 l’ensemble du flux 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’exemple en cours de lecture (c’est-à-dire l’exemple qui est verrouillé à 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 se déplacent 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 en boucle, les écritures du client ne doivent jamais dépasser la position de lecture.

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

  • WaveCyclique

    Chaque fois que le pilote de port WaveCyclic 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 passe à 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 WavePci 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 passe à l’emplacement (dans la mémoire tampon client) du dernier octet du nouveau mappage.

    Si le pilote de miniport WavePci remplace le comportement par défaut en spécifiant un décalage de préfetch sur le 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éversion. Pour plus d’informations, consultez Décalages préalables.

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 est le décalage d’octet du dernier exemple à prendre au niveau de la sortie du convertisseur analogique-numérique ou ADC. (Cette position spécifie l’emplacement de mémoire tampon dans lequel le moteur DMA du périphérique audio va éventuellement écrire 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 être suivis de la position de lecture. En outre, si la mémoire tampon est en boucle, les lectures du client doivent rester en avance sur la position de l’enregistrement.

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

  • WaveCyclique

    Chaque fois que le pilote de port WaveCyclic appelle IDmaChannel ::CopyFrom pour copier un nouveau bloc de données à partir de la mémoire tampon cyclique (vers la mémoire tampon du client), la position de lecture passe à 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 passe à l’emplacement (dans la mémoire tampon du client) du dernier octet du mappage publié.

Les pilotes miniport n’ont pas besoin d’implémenter des routines de gestionnaire pour les demandes de propriétés KSPROPERTY_AUDIO_POSITION. Au lieu de cela, les pilotes de port WaveCyclic et WavePci gèrent ces demandes pour le compte des pilotes miniport. Lors de la gestion d’une demande get-property, un pilote de port WaveCyclic ou WavePci possède 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, c’est-à-dire le décalage d’octet de l’exemple en cours de lecture via la DAC. Pour un flux de capture, la méthode GetPosition récupère la position de l’enregistrement, soit le décalage d’octet du dernier exemple à 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 via la prise du microphone. Il ne s’agit pas de la position DMA. (La position DMA est le décalage d’octet de l’exemple que le moteur DMA de l’appareil audio est en train de transférer vers ou à partir de la mémoire 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 meilleure estimation du décalage d’octet de l’exemple dans la DAC ou L’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 WaveCyclic ou WavePci doit faire la distinction entre les mémoires tampons bouclées et non pilotées pour déterminer s’il faut fournir un décalage d’octet relatif au flux ou relatif à la mémoire tampon, ce détail (autrement dit, si une mémoire tampon est bouclée ou non activée) est transparent pour le pilote miniport.

La méthode IMiniportWaveCyclicStream ::GetPosition signale toujours une lecture ou une position d’enregistrement relative à la mémoire tampon, que la mémoire tampon cliente soit en boucle ou non activée. Si la mémoire tampon cliente 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 décalage dans la mémoire tampon cliente, que le gestionnaire écrit ensuite dans le membre PlayOffset . Si la mémoire tampon cliente n’est pas activée, le gestionnaire de propriétés convertit la position de lecture relative à la mémoire 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 activée. Si la mémoire tampon cliente est bouclée, le gestionnaire de propriétés convertit la position de lecture relative au flux en position de lecture relative à la 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 demande 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 fige. Il se dégele 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 WaveCyclic et WavePci miniport, consultez les exemples de pilotes audio dans le Kit de pilotes Windows (WDK).