Utilisation de l’interface IKsControl pour accéder aux propriétés audio
Dans de rares cas, une application audio spécialisée peut nécessiter l’utilisation de l’interface IKsControl pour accéder à certaines fonctionnalités matérielles d’une carte audio qui ne sont pas exposées par l' API DEVICETOPOLOGY ou l' API MMDevice. L’interface IKsControl rend les propriétés, les événements et les méthodes des appareils de streaming noyau (KS) disponibles pour les applications en mode utilisateur. L’intérêt principal des applications audio est les propriétés KS. L’interface IKsControl peut être utilisée conjointement avec l’API DeviceTopology et l’API MMDevice pour accéder aux propriétés KS des adaptateurs audio.
L’interface IKsControl est destinée principalement à être utilisée par des fournisseurs de matériel qui écrivent des applications de panneau de contrôle pour gérer leur matériel audio. IKsControl est moins utile pour les applications audio à usage général qui ne sont pas liées à des périphériques matériels particuliers. La raison en est que les fournisseurs de matériel implémentent fréquemment des mécanismes propriétaires pour accéder aux propriétés audio de leurs appareils. Contrairement à l’API DeviceTopology, qui masque les caractéristiques des pilotes spécifiques au matériel et fournit une interface relativement uniforme pour accéder aux propriétés audio, les applications utilisent IKsControl pour communiquer directement avec les pilotes. pour plus d’informations sur IKsControl, consultez la documentation Windows DDK.
Comme indiqué dans topologies d’appareils, une sous-unité dans la topologie d’un périphérique d’adaptateur peut prendre en charge une ou plusieurs des interfaces de contrôle spécifiques à la fonction affichées dans la colonne de gauche du tableau suivant. Chaque entrée dans la colonne de droite de la table est la propriété KS qui correspond à l’interface de contrôle à gauche. L’interface de contrôle fournit un accès pratique à la propriété. La plupart des pilotes audio utilisent les propriétés KS pour représenter les fonctionnalités de traitement spécifiques aux fonctions des sous-unités (également appelées nœuds KS) dans les topologies de leurs adaptateurs audio. pour plus d’informations sur les propriétés ks et les nœuds ks, consultez la documentation Windows DDK.
| Interface de contrôle | Propriété KS |
|---|---|
| IAudioAutoGainControl | _AGC audio _ KSPROPERTY |
| IAudioBass | _basses audio _ KSPROPERTY |
| IAudioChannelConfig | _configuration du _ canal _ audio KSPROPERTY |
| IAudioInputSelector | _ _ source mux audio _ KSPROPERTY |
| IAudioLoudness | KSPROPERTY _ audio _ |
| IAudioMidrange | KSPROPERTY _ audio _ Mid |
| IAudioMute | KSPROPERTY _ audio _ muet |
| IAudioOutputSelector | KSPROPERTY _ audio _ DEMUX _ dest |
| IAudioPeakMeter | KSPROPERTY _ audio _ PEAKMETER |
| IAudioTreble | _ _ aigus audio KSPROPERTY |
| IAudioVolumeLevel | KSPROPERTY _ audio _ VOLUMELEVEL |
| IDeviceSpecificProperty | _spécifique au _ dev _ audio KSPROPERTY |
Les topologies de certains adaptateurs audio peuvent contenir des sous-unités qui ont des propriétés KS qui ne sont pas répertoriées dans le tableau précédent. Par exemple, supposons qu’un appel à la méthode IPart :: GetSubType pour une sous-unité particulière récupère la valeur Guid KSNODETYPE _ tonal. Ce GUID de sous-type indique que la sous-unité prend en charge une ou plusieurs des propriétés KS suivantes :
- _basses audio _ KSPROPERTY
- KSPROPERTY _ audio _ Mid
- _ _ aigus audio KSPROPERTY
- KSPROPERTY _ audio _ - _ Booster
Les trois premières propriétés de cette liste sont accessibles par le biais des interfaces de contrôle qui s’affichent dans le tableau précédent, mais la _ propriété KSPROPERTY audio _ Bass _ Boost n’a pas d’interface de contrôle correspondante dans l’API DeviceTopology. Toutefois, une application peut utiliser l’interface IKsControl pour accéder à cette propriété, si la sous-unité prend en charge la propriété.
Les étapes suivantes sont requises pour accéder à la _ propriété KSPROPERTY audio _ Bass _ Boost d’une sous-unité de sous-type KSNODETYPE _ tonal :
- Appelez la méthode IConnector :: GetDeviceIdConnectedTo ou IDeviceTopology :: GetDeviceId pour obtenir la chaîne d’ID d’appareil qui identifie l’appareil d’adaptateur. Cette chaîne est similaire à une chaîne d’ID de point de terminaison, à ceci près qu’elle identifie un périphérique d’adaptateur au lieu d’un périphérique de point de terminaison. Pour plus d’informations sur la différence entre un périphérique d’adaptateur et un périphérique de point de terminaison, consultez périphériques de point de terminaison audio.
- Obtenez l’interface IMMDevice de l’adaptateur en appelant la méthode IMMDeviceEnumerator :: GetDevice avec la chaîne d’ID de l’appareil. Cette interface IMMDevice est identique à l’interface décrite dans interface IMMDevice, mais elle représente un périphérique adaptateur au lieu d’un périphérique de point de terminaison.
- Obtenez l’interface IKsControl sur la sous-unité en appelant la méthode IMMDevice :: Activate avec l' IID de paramètre défini sur REFIID IID _ IKsControl. Notez que les interfaces prises en charge par cette méthode Activate , qui est destinée à un périphérique d’adaptateur, sont différentes des interfaces prises en charge par la méthode Activate pour un appareil de point de terminaison. En particulier, la méthode Activate pour un appareil d’adaptateur prend en charge IKsControl.
- Appelez la méthode IPart :: GetLocalId pour obtenir l’ID local de la sous-unité.
- Construit une demande de propriété KS. L’ID de nœud KS requis pour la requête est contenu dans les 16 bits les moins significatifs de l’ID local obtenu à l’étape précédente.
- Envoyez la demande de propriété KS au pilote audio en appelant la méthode IKsControl :: KsProperty . pour plus d’informations sur cette méthode, consultez la documentation Windows DDK.
L’exemple de code suivant récupère la valeur de la _ propriété KSPROPERTY audio _ Bass _ Boost à partir d’une sous-unité de sous-type KSNODETYPE _ Tone :
//-----------------------------------------------------------
// This function calls the IKsControl::Property method to get
// the value of the KSPROPERTY_AUDIO_BASS_BOOST property of
// a subunit. Parameter pPart should point to a part that is
// a subunit with a subtype GUID value of KSNODETYPE_TONE.
//-----------------------------------------------------------
#define PARTID_MASK 0x0000ffff
#define EXIT_ON_ERROR(hres) \
if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) \
{ (punk)->Release(); (punk) = NULL; }
const IID IID_IKsControl = __uuidof(IKsControl);
HRESULT GetBassBoost(IMMDeviceEnumerator *pEnumerator,
IPart *pPart, BOOL *pbValue)
{
HRESULT hr;
IDeviceTopology *pTopology = NULL;
IMMDevice *pPnpDevice = NULL;
IKsControl *pKsControl = NULL;
LPWSTR pwszDeviceId = NULL;
if (pEnumerator == NULL || pPart == NULL || pbValue == NULL)
{
return E_INVALIDARG;
}
// Get the topology object for the adapter device that contains
// the subunit represented by the IPart interface.
hr = pPart->GetTopologyObject(&pTopology);
EXIT_ON_ERROR(hr)
// Get the device ID string that identifies the adapter device.
hr = pTopology->GetDeviceId(&pwszDeviceId);
EXIT_ON_ERROR(hr)
// Get the IMMDevice interface of the adapter device object.
hr = pEnumerator->GetDevice(pwszDeviceId, &pPnpDevice);
EXIT_ON_ERROR(hr)
// Activate an IKsControl interface on the adapter device object.
hr = pPnpDevice->Activate(IID_IKsControl, CLSCTX_ALL, NULL, (void**)&pKsControl);
EXIT_ON_ERROR(hr)
// Get the local ID of the subunit (contains the KS node ID).
UINT localId = 0;
hr = pPart->GetLocalId(&localId);
EXIT_ON_ERROR(hr)
KSNODEPROPERTY_AUDIO_CHANNEL ksprop;
ZeroMemory(&ksprop, sizeof(ksprop));
ksprop.NodeProperty.Property.Set = KSPROPSETID_Audio;
ksprop.NodeProperty.Property.Id = KSPROPERTY_AUDIO_BASS_BOOST;
ksprop.NodeProperty.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
ksprop.NodeProperty.NodeId = localId & PARTID_MASK;
ksprop.Channel = 0;
// Send the property request.to the device driver.
BOOL bValue = FALSE;
ULONG valueSize;
hr = pKsControl->KsProperty(
&ksprop.NodeProperty.Property, sizeof(ksprop),
&bValue, sizeof(bValue), &valueSize);
EXIT_ON_ERROR(hr)
*pbValue = bValue;
Exit:
SAFE_RELEASE(pTopology)
SAFE_RELEASE(pPnpDevice)
SAFE_RELEASE(pKsControl)
CoTaskMemFree(pwszDeviceId);
return hr;
}
Dans l’exemple de code précédent, la fonction GetBassBoost prend les trois paramètres suivants :
pEnumeratorpointe vers l’interface IMMDeviceEnumerator d’un énumérateur de point de terminaison audio.pPartpointe vers l’interface IPart d’une sous-unité qui a un sous-type de KSNODETYPE _ Tone.pbValuepointe vers une variable booléenne dans laquelle la fonction écrit la valeur de la propriété.
Un programme appelle GetBassBoost uniquement après avoir appelé IPart :: GetSubType et détermine que le sous-type de la sous-unité est KSNODETYPE _ Tone. La valeur de la propriété est true si la Booster est activée. La valeur est false si l’augmentation des basses est désactivée.
Au début de la fonction GetBassBoost, l’appel à la méthode IPart :: GetTopologyObject obtient l’interface IDeviceTopology du périphérique adaptateur qui contient la sous-unité de _ ton KSNODETYPE. L’appel de la méthode IDeviceTopology :: GetDeviceId récupère la chaîne d’ID de l’appareil qui identifie l’appareil de l’adaptateur. L’appel de la méthode IMMDeviceEnumerator :: GetDevice prend la chaîne d’ID de l’appareil comme paramètre d’entrée et récupère l’interface IMMDevice de l’appareil de l’adaptateur. Ensuite, l’appel de la méthode IMMDevice :: Activate récupère l’interface IKsControl de la sous-unité. pour plus d’informations sur l’interface IKsControl , consultez la documentation Windows DDK.
Ensuite, l’exemple de code précédent crée une structure de _ _ canal audio KSNODEPROPERTY qui décrit la propriété Bass-Boost. L’exemple de code passe un pointeur vers la structure à la méthode IKsControl :: KsProperty , qui utilise les informations de la structure pour récupérer la valeur de la propriété. pour plus d’informations sur la structure de _ _ canaux AUDIO KSNODEPROPERTY et la méthode IKsControl :: KsProperty , consultez la documentation Windows DDK.
Le matériel audio affecte généralement un état d’amélioration des basses à chaque canal dans un flux audio. En principe, la Booster de basses peut être activée pour certains canaux et désactivée pour d’autres. La structure de _ _ canal audio KSNODEPROPERTY contient un membre de canal qui spécifie le numéro de canal. Si un flux contient n canaux, les canaux sont numérotés de 0 à n— 1. L’exemple de code précédent obtient la valeur de la propriété Bass-Boost pour le canal 0 uniquement. Cette implémentation suppose implicitement que les propriétés d’augmentation des basses pour tous les canaux sont définies uniformément dans le même État. Par conséquent, la lecture de la propriété Bass-Boost pour le canal 0 suffit pour déterminer la valeur de la propriété de l’augmentation du nombre de basses pour le flux. Pour être cohérente avec cette hypothèse, une fonction correspondante permettant de définir la propriété Bass-Boost définit tous les canaux sur la même valeur de propriété Bass-Boost. Il s’agit de conventions raisonnables, mais tous les fournisseurs de matériel ne les suivent pas nécessairement. Par exemple, un fournisseur peut fournir une application de panneau de configuration qui active le suramplificateur de basses uniquement pour les canaux qui dirigent des orateurs à plage complète. (Un conférencier complet est en train de jouer des sons sur toute la plage de basses à des aigus.) Dans ce cas, la valeur de propriété récupérée par l’exemple de code précédent peut ne pas représenter avec précision l’état de booster (Bass-Boost) du flux.
Les clients qui utilisent les interfaces de contrôle figurant dans le tableau précédent peuvent appeler la méthode IPart :: RegisterControlChangeCallback pour s’inscrire aux notifications lorsque la valeur d’un paramètre de contrôle change. Notez que l’interface IKsControl ne fournit pas un moyen similaire pour que les clients s’inscrivent pour les notifications lorsqu’une valeur de propriété change. Si IKsControl prenait en charge les notifications de modification de propriété, il peut informer une application qu’une autre application a modifié une valeur de propriété. Toutefois, contrairement aux contrôles les plus couramment utilisés qui sont surveillés par le biais de notifications IPart , les propriétés gérées par IKsControl sont principalement destinées à être utilisées par les fournisseurs de matériel, et ces propriétés sont susceptibles d’être modifiées uniquement par les applications du panneau de configuration écrites par les fournisseurs. Si une application doit détecter les modifications de propriété apportées par une autre application, elle peut détecter les modifications en interrogeant régulièrement la valeur de la propriété par le biais de IKsControl.