Freigeben über


Konfigurieren und Abfragen von Audiogerätemodulen

In diesem Artikel wird gezeigt, wie Sie Befehle senden und Änderungsbenachrichtigungen von Audiogerätemodulen aus einer UWP-App empfangen. Ein Audiogerätemodul kann eine Hardwareeffektverarbeitungseinheit oder ein anderes Audiokonfigurationsmodul sein, das von einem Audiotreiber definiert wird. Dieses Feature wurde entwickelt, um Modulanbietern das Erstellen von UWP-Apps zu ermöglichen, mit denen Benutzer status Informationen aus einem Audioverarbeitungsmodul steuern und abrufen können, das in einem DSP ausgeführt wird. Um die in diesem Artikel gezeigten APIs des Audiogerätemoduls verwenden zu können, müssen Sie die eingeschränkte audioDeviceConfiguration-Funktion in Ihrem App-Paketmanifest angeben.

Abrufen einer instance der AudioDeviceModulesManager-Klasse

Alle Vorgänge des Audiogerätemoduls in diesem Artikel beginnen mit dem Abrufen einer instance des AudioDeviceModulesManagers. Rufen Sie hierzu zuerst die statische GetDefaultAudioRenderId-Methode der MediaDevice-Klasse auf. Dadurch wird die ID des Standard-Audiorenderinggeräts zurückgegeben, das dann an den Konstruktor für AudioDeviceModulesManager übergeben wird, um eine instance der Klasse zu erstellen, die dem Audiogerät zugeordnet ist.

C#

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

Abfragen nach installierten Audiogerätemodulen

Fragen Sie alle installierten Audiogerätemodule ab, indem Sie die FindAll-Klasse der AudioDeviceModulesManager-Klasse aufrufen. Fragen Sie eine bestimmte Gruppe von Audiogerätemodulen ab, indem Sie FindAllById aufrufen und die ID der angeforderten Module übergeben. Im folgenden Beispiel wird eine ID für einen Satz von Modulen definiert, FindAllById aufgerufen, um eine Liste von AudioDeviceModule-Objekten abzurufen, und dann werden die Details der einzelnen Module in der Debugausgabe ausgegeben.

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}");
}

Senden eines Befehls an ein Audiogerätemodul und Empfangen von Ergebnisdaten

Senden Sie Befehle an ein Audiogerätemodul, indem Sie SendCommandAsync für das AudioDeviceModule-Objekt aufrufen. Die SendCommandAsync-Methode akzeptiert ein Bytearray als Argument. In der Regel enthält dieses Bytearray einen Befehlsbezeichner gefolgt von den dem Befehl zugeordneten Daten, aber das Befehlsformat und die Werte sind vollständig herstellerdefiniert und werden vom System als transparent behandelt.

Die SendCommandAsync-Methode gibt einen asynchronen Vorgang zurück, der nach Abschluss ein ModuleCommandResult-Objekt zurückgibt, das das Ergebnis des Befehls darstellt. Die Status-Eigenschaft enthält einen Enumerationswert, der angibt, ob das System den Befehl ausführen konnte. Dies bedeutet nicht unbedingt, dass das Audiogerätemodul den Befehl erfolgreich ausführen konnte. Die Result-Eigenschaft enthält ein Bytearray, das vom Audiogerätemodul zurückgegeben wird, um die status des Befehls anzugeben. In der Regel ist dies ein Wert, der den Erfolg oder Fehler angibt, gefolgt von dem Datenergebnis des Befehls. Wie bei Modulbefehlen sind die Modulantwortformate und -werte vom Hersteller definiert.

Im folgenden Beispiel wird FindAllAsync aufgerufen, um eine Reihe von Audiogerätemodulen abzurufen. Ein DataWriter wird verwendet, um ein Bytearray zu erstellen, das einen Beispielbefehl und Daten enthält. SendCommandAsync wird aufgerufen, um den Befehlspuffer zu senden, und nach Abschluss des asynchronen Vorgangs wird ein ModuleCommandResult zurückgegeben. Wenn die Befehlsausführung erfolgreich war, wird zunächst ein DataReader verwendet, um eine ganzzahlige status wert zu lesen, der aus dem Modul zurückgegeben wurde. Wenn dieser Wert der vom Hersteller definierte Erfolgswert ist, werden die restlichen Ergebnisdaten gelesen und von der App verwendet, z. B. zum Aktualisieren der Benutzeroberfläche.

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
            }
        }
    }
}

Empfangen von Benachrichtigungen, wenn Audiogerätemodule geändert werden

Apps können Benachrichtigungen empfangen, wenn ein Audiogerätemodul aktualisiert wurde, indem sie sich für das ModuleNotificationReceived-Ereignis registrieren.

C#

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

audioModuleManager.ModuleNotificationReceived += AudioModuleManager_ModuleNotificationReceived;

ModuleNotificationReceived wird ausgelöst, wenn ein Audiogerätemodul geändert wird, das dem aktuellen Audiogerät zugeordnet ist. Um zu bestimmen, ob das Ereignis einem bestimmten Modul zugeordnet ist, rufen Sie eine instance von AudioDeviceModule ab, indem Sie auf die Module-Eigenschaft der AudioDeviceModuleNoticiationEventArgs zugreifen, die an den Ereignishandler übergeben wurde, und dann die ClassId-Eigenschaft überprüfen, die das Modul identifiziert. Die dem Ereignis zugeordneten Daten werden als Bytearray übergeben, das in der NotificationData-Eigenschaft der Ereignisargumente gespeichert ist. Wie bei Befehlen und Ergebnissen ist das Format des zurückgegebenen Bytearrays vom Hersteller definiert. Wenn im folgenden Beispiel das erste Byte der Benachrichtigungsdaten den Beispielwert für die Einstellung der Reverbebene des Moduls enthält, werden die Daten gelesen und zum Aktualisieren der Benutzeroberfläche verwendet.

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];
            }
        }
    }
}