Share via


Latence WavePci

Le pilote de port WavePci gère la mise en mémoire tampon d’un flux audio différemment du pilote WaveCyclique.

Si votre pilote de miniport WavePci fournit un mélange de matériel, DirectSound envoie un IRP au pilote de port WavePci qui contient l’intégralité du flux d’ondes DirectSound dans une mémoire tampon cyclique unique. DirectSound alloue la mémoire tampon en tant que bloc contigu de mémoire virtuelle. Pour éviter de copier la mémoire tampon DirectSound, la couche de diffusion en continu du noyau mappe la mémoire tampon en mémoire virtuelle en mode noyau et génère une liste MDL (descripteur de mémoire) qui spécifie à la fois les adresses virtuelles et physiques des pages mémoire dans la mémoire tampon cyclique. Le pilote de port WavePci partitionne la mémoire tampon cyclique en une séquence de trames d’allocateur (voir Allocators KS). Le pilote miniport spécifie sa taille d’image d’allocator préférée lorsque sa méthode IMiniportWavePciStream::GetAllocatorFraming est appelée par le pilote de port lors de l’initialisation du flux. Toutefois, SysAudio, le générateur de graphiques système, peut remplacer les préférences du pilote miniport afin de répondre aux exigences des autres composants du graphique de filtre audio.

Le pilote de port WavePci expose la mémoire tampon cyclique au pilote miniport en tant que séquence de mappages. Un mappage est soit une image d’allocation entière, soit une partie d’un frame. Si un cadre d’allocation particulier se trouve entièrement dans une page, le pilote de port présente cette trame au pilote miniport sous la forme d’un mappage unique. Si un cadre d’allocation chevauche une ou plusieurs limites de page, le pilote de port fractionne le cadre à chaque limite de page et le présente sous la forme de deux mappages ou plus. Chaque appel à IPortWavePciStream::GetMapping génère le mappage successif suivant dans la séquence.

Contrairement au cas WaveCyclique, où le pilote miniport a peu de contrôle sur le nombre de millisecondes de données mises en mémoire tampon sur le matériel, le pilote de miniport WavePci a un contrôle considérable sur le nombre de mappages qu’il a ouverts à tout moment. Le nombre de mappages ouverts augmente d’un à chaque appel à GetMapping et diminue d’un avec chaque appel à ReleaseMapping. (Un appel GetMapping peut échouer, bien sûr, de sorte que le pilote a moins de contrôle total sur le nombre de mappages.) En contrôlant le nombre de mappages ouverts et en effectuant le suivi de la taille cumulée des mappages, le pilote miniport peut déterminer (dans une tolérance dépendante de la taille du mappage) le nombre de millisecondes de mise en mémoire tampon disponibles pour le matériel. Votre pilote de miniport WavePci doit demander suffisamment de mappages de pages pour réduire les risques de famine à des niveaux acceptables.

Si la stratégie de votre pilote miniport consiste à mettre en mémoire tampon jusqu’à 50 millisecondes de données, par exemple, entre les pointeurs de lecture et d’écriture, n’oubliez pas que cette limite représente la quantité maximale de données que votre pilote va accumuler, mais elle ne représente pas et ne doit pas représenter la contribution de votre pilote à la latence du flux. Votre pilote doit être conçu pour maintenir sa latence aussi faible que possible. Lorsqu’un pilote miniport obtient son ensemble initial de mappages avant de commencer à lire un nouveau flux, le pilote miniport peut continuer à demander des mappages jusqu’à ce qu’il atteigne sa limite de mémoire tampon (50 millisecondes dans cet exemple) ou qu’aucun autre mappage ne soit immédiatement disponible. Dans ce dernier cas, cependant, le pilote miniport ne doit pas attendre que d’autres mappages soient disponibles avant de commencer à jouer le flux. Au lieu de cela, le pilote doit commencer immédiatement à lire les mappages qu’il a déjà obtenus. Plus tard, à mesure que d’autres mappages deviennent disponibles, le pilote peut continuer à acquérir des mappages supplémentaires jusqu’à ce qu’il atteigne sa limite de taille de mémoire tampon ou qu’aucun autre mappage ne soit immédiatement disponible.

En général, le matériel DMA d’un appareil WavePci doit être conçu pour accéder directement aux trames audio stockées à des alignements d’octets arbitraires et qui se chevauchent entre les pages de mémoire physique non incohérentes. Si vous avez un appareil qui nécessite que les mappages soient un nombre intégral d’images audio, ce périphérique est limité dans les types de formats audio qu’il prend en charge. Bien sûr, un appareil avec cette limitation doit toujours être en mesure de gérer une taille d’image audio qui est une puissance de deux.

Par exemple, un appareil avec quatre canaux et une taille d’échantillon de 16 bits nécessite une taille de trame audio de huit octets. Un nombre intégral d’images audio s’intègre parfaitement dans une page (ou toute autre taille d’image d’allocation qui est un multiple de huit octets). Toutefois, dans le cas d’un flux de 5,1 canaux avec des exemples 16 bits, la taille d’image audio est de 12 octets et un flux qui dépasse la taille d’une seule page contient nécessairement des trames audio qui chevauchent les limites de page. (Les illustrations des filtres d’ondes illustrent ce problème.) Le matériel qui ne peut pas gérer les alignements d’octets arbitraires et les mappages de longueur d’octets arbitraires doit dépendre du pilote pour effectuer une copie intermédiaire, ce qui dégrade les performances.

L’exemple de pilote d’adaptateur Ac97 dans le Kit de pilotes Microsoft Windows (WDK) implémente une méthode GetAllocatorFraming . Le pilote miniport utilise cette méthode pour communiquer sa taille d’allocation de trame préférée. Dans Windows 2000 et Windows Me, le pilote de port appelle cette méthode uniquement lorsque le pilote système Splitter (Splitter.sys) est instancié au-dessus de la broche de sortie. Dans Windows XP et versions ultérieures, le pilote de port appelle également cette méthode pour les flux d’entrée. N’oubliez pas que SysAudio peut choisir d’ignorer les préférences du pilote miniport lors du choix d’une taille d’allocation de trame.