Configurer et interroger des modules d’appareil audio

Cet article explique comment envoyer des commandes et recevoir des notifications de modification à partir de modules d’appareil audio à partir d’une application UWP. Un module de périphérique audio peut être une unité de traitement d’effet matériel ou tout autre module de configuration audio défini par un pilote audio. Cette fonctionnalité a été conçue pour permettre aux fournisseurs de modules de créer des applications UWP qui permettent aux utilisateurs de contrôler et d’obtenir des informations status à partir d’un module de traitement audio s’exécutant dans un DSP. Pour utiliser les API de module de périphérique audio présentées dans cet article, vous devez spécifier la fonctionnalité audioDeviceConfiguration restreinte dans le manifeste de votre package d’application.

Obtenir un instance de la classe AudioDeviceModulesManager

Toutes les opérations de module d’appareil audio présentées dans cet article commencent par obtenir une instance de AudioDeviceModulesManager. Pour ce faire, appelez d’abord la méthode statique GetDefaultAudioRenderId de la classe MediaDevice . Cette opération retourne l’ID du périphérique de rendu audio par défaut, qui est ensuite transmis au constructeur pour AudioDeviceModulesManager afin de créer un instance de la classe associée au périphérique audio.

C#

var endpointId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);
var audioModuleManager = new AudioDeviceModulesManager(endpointId);

Requête pour les modules d’appareil audio installés

Recherchez tous les modules de périphérique audio installés en appelant findAll de la classe AudioDeviceModulesManager . Recherchez un ensemble spécifique de modules d’appareil audio en appelant FindAllById et en transmettant l’ID des modules demandés. L’exemple suivant définit un ID pour un ensemble de modules, appelle FindAllById pour récupérer une liste d’objets AudioDeviceModule , puis imprime les détails de chaque module dans la sortie de débogage.

C#

public const string Contoso_AudioDeviceModuleId = "F72E09C3-FEBA-4C50-93BE-2CA56123AF09";

C#

var endpointId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);
var audioModuleManager = new AudioDeviceModulesManager(endpointId);
var modules = audioModuleManager.FindAllById(Contoso_AudioDeviceModuleId);

foreach (var module in modules)
{
    var classId = module.ClassId;
    var name = module.DisplayName;
    var minorVersion = module.MinorVersion;
    var majorVersion = module.MajorVersion;
    var instanceId = module.InstanceId;

        Debug.WriteLine($"{classId} : {name} : {minorVersion} : {majorVersion} : {instanceId}");
}

Envoyer une commande à un module de périphérique audio et recevoir des données de résultat

Envoyez des commandes à un module de périphérique audio en appelant SendCommandAsync sur l’objet AudioDeviceModule . La méthode SendCommandAsync prend un tableau d’octets comme argument. En règle générale, ce tableau d’octets contient un identificateur de commande suivi des données associées à la commande, mais le format et les valeurs de la commande sont entièrement définis par le fournisseur et sont traités comme transparents par le système.

La méthode SendCommandAsync retourne une opération asynchrone qui, une fois terminée, retourne un objet ModuleCommandResult représentant le résultat de la commande. La propriété Status contient une valeur d’énumération qui indique si le système a pu exécuter la commande. Cela n’indique pas nécessairement que le module de périphérique audio a pu exécuter la commande avec succès. La propriété Result contient un tableau d’octets retourné par le module de périphérique audio pour indiquer la status de la commande. En règle générale, il s’agit d’une valeur qui indique la réussite ou l’échec, suivie du résultat des données de la commande. Comme pour les commandes de module, les formats et les valeurs de réponse de module sont définis par le fournisseur.

L’exemple suivant appelle FindAllAsync pour récupérer un ensemble de modules de périphérique audio. Un DataWriter est utilisé pour créer un tableau d’octets contenant un exemple de commande et de données. SendCommandAsync est appelé pour envoyer la mémoire tampon de commande et, une fois l’opération asynchrone terminée, un ModuleCommandResult est retourné. Si l’exécution de la commande a réussi, un DataReader est d’abord utilisé pour lire un entier status valeur retournée à partir du module. Si cette valeur est la valeur de réussite définie par le fournisseur, le reste des données de résultat est lu et utilisé par l’application, par exemple pour mettre à jour l’interface utilisateur.

C#

public const byte Contoso_ReverbLevel_Command = 30; 
public const byte Contoso_SendCommand_Success = 99;

C#

var endpointId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);
var audioModuleManager = new AudioDeviceModulesManager(endpointId);
var modules = audioModuleManager.FindAllById(Contoso_AudioDeviceModuleId);

foreach (var module in modules)
{
    var writer = new Windows.Storage.Streams.DataWriter();
    writer.WriteByte(Contoso_ReverbLevel_Command);
    writer.WriteByte(100);

    var command = writer.DetachBuffer();

    var result = await module.SendCommandAsync(command);

    if (result.Status == SendCommandStatus.Success)
    {
        using (DataReader reader = DataReader.FromBuffer(result.Result))
        {
            int bufferStatus = reader.ReadInt32();
            if (bufferStatus == Contoso_SendCommand_Success)
            {
                byte[] data = { 0, 0 };
                reader.ReadBytes(data);
                // Do something with returned data, such as update UI
            }
        }
    }
}

Recevoir des notifications lorsque les modules d’appareil audio sont modifiés

Les applications peuvent recevoir des notifications lorsqu’un module d’appareil audio a été mis à jour en s’inscrivant à l’événement ModuleNotificationReceived .

C#

var endpointId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);
var audioModuleManager = new AudioDeviceModulesManager(endpointId);

audioModuleManager.ModuleNotificationReceived += AudioModuleManager_ModuleNotificationReceived;

ModuleNotificationReceived est déclenché quand un module de périphérique audio associé au périphérique audio actuel est modifié. Pour déterminer si l’événement est associé à un module particulier, obtenez une instance d’AudioDeviceModule en accédant à la propriété Module de l’AudioDeviceModuleNoticiationEventArgs passée dans le gestionnaire d’événements, puis en vérifiant la propriété ClassId qui identifie le module. Les données associées à l’événement sont passées sous la forme d’un tableau d’octets stocké dans la propriété NotificationData des arguments d’événement. Comme pour les commandes et les résultats, le format du tableau d’octets retourné est défini par le fournisseur. Dans l’exemple ci-dessous, si le premier octet des données de notification contient l’exemple de valeur pour le paramètre de niveau de réverbération du module, les données sont lues et utilisées pour mettre à jour l’interface utilisateur.

C#

public const byte Contoso_ReverbLevel_Data = 25;

C#

private void AudioModuleManager_ModuleNotificationReceived(AudioDeviceModulesManager sender, AudioDeviceModuleNotificationEventArgs args)
{
    if (args.Module.ClassId == Contoso_AudioDeviceModuleId)
    {
        // Get the coefficient data from the reverb module.
        using (DataReader reader = DataReader.FromBuffer(args.NotificationData))
        {
            // read notification data.
            byte item = reader.ReadByte();

            // if reverb coefficient data are changed.
            if (item == Contoso_ReverbLevel_Data)
            {
                // read the new value
                byte[] data = { 0 };
                reader.ReadBytes(data);
                ReverbLevelSlider.Value = data[0];
            }
        }
    }
}