次の方法で共有


オーディオ デバイス モジュールの構成とクエリ

この記事では、オーディオ デバイス モジュールからコマンドを送信し、UWP アプリで変更通知を受信する方法について説明します。 オーディオ デバイス モジュールは、ハードウェア効果処理装置、またはオーディオ ドライバーによって定義されたその他のオーディオ構成モジュールである場合があります。 この機能は、ユーザーが DSP で実行されているオーディオ処理モジュールから状態情報を制御および取得できるようにする UWP アプリを、モジュール プロバイダーが作成できるように設計されています。 この記事に示されているオーディオ デバイス モジュール API を使用するには、アプリ パッケージ マニフェストで制限付き audioDeviceConfiguration 機能を指定する必要があります。

AudioDeviceModulesManager クラスのインスタンスを取得する

この記事に示すすべてのオーディオ デバイス モジュールの操作では、まず AudioDeviceModulesManager のインスタンスを取得することから始めます。 これを行うには、最初に MediaDevice クラスの静的 GetDefaultAudioRenderId メソッドを呼び出します。 これは、オーディオ デバイスに関連付けられているクラスのインスタンスを作成するために AudioDeviceModulesManager のコンストラクターに渡される、既定のオーディオ レンダリング デバイスの ID を返します。

C#

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

インストールされているオーディオ デバイス モジュールのクエリを実行する

AudioDeviceModulesManager クラスの FindAll を呼び出して、インストールされているすべてのオーディオ デバイス モジュールに対してクエリを実行します。 FindAllById を呼び出し 、要求されたモジュールの ID を渡して、特定のオーディオ デバイス モジュールのセットのクエリを実行します。 次の例では、一連のモジュールの ID を定義し、FindAllById を呼び出して AudioDeviceModule オブジェクトの一覧を取得し、各モジュールの詳細をデバッグ出力に出力します。

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

オーディオ デバイス モジュールにコマンドを送信し、結果データを受信する

AudioDeviceModule オブジェクトで SendCommandAsync を呼び出して、オーディオ デバイス モジュールにコマンドを送信します。 SendCommandAsync メソッドは、バイト配列を引数として受け取ります。 通常、このバイト配列にはコマンド識別子とそれに続くコマンドに関連付けられたデータが含まれますが、コマンドの形式と値は完全にベンダー定義であり、システムによって透過的として扱われます。

SendCommandAsync メソッドは、完了時にコマンドの結果を表す ModuleCommandResult オブジェクトを返す非同期操作を返します。 Status プロパティには、システムがコマンドを実行できたかどうかを示す列挙値が含まれています。 これは必ずしも、オーディオ デバイス モジュールがコマンドを正常に実行できたことを示すわけではありません。 Result プロパティには、コマンドの状態を示すためにオーディオ デバイス モジュールによって返されるバイト配列が含まれています。 通常、これは成功または失敗を示す値で、その後にコマンドのデータ結果が続きます。 モジュール コマンドと同様に、モジュール応答の形式と値はベンダーによって定義されます。

次の例では、FindAllAsync を呼び出して、オーディオ デバイス モジュールのセットを取得します。 DataWriter は、コマンドとデータの例を含むバイト配列を作成するために使用されます。 SendCommandAsync が呼び出されてコマンド バッファーが送信され、非同期操作が完了すると ModuleCommandResult が返されます。 コマンドの実行が成功した場合は、モジュールから返された整数の状態値を読み取るために DataReader が最初に使用されます。 この値がベンダーによって定義された成功の値である場合は、結果データの残りの部分が、UI を更新するためなどに、アプリによって読み取られ、使用されます。

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

オーディオ デバイス モジュールが変更されたときに通知を受信する

ModuleNotificationReceived イベントに登録することで、オーディオ デバイス モジュールが更新されたときに、アプリで通知を受け取ることができます。

C#

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

audioModuleManager.ModuleNotificationReceived += AudioModuleManager_ModuleNotificationReceived;

ModuleNotificationReceived は、現在のオーディオ デバイスに関連付けられているオーディオ デバイス モジュールが変更されたときに実行されます。 イベントが特定のモジュールに関連付けられているかどうかを判断するには、イベント ハンドラーに渡された AudioDeviceModuleNoticiationEventArgsModule プロパティにアクセスし、モジュールを識別する ClassId プロパティをチェックすることで、AudioDeviceModule のインスタンスを取得します。 イベントに関連付けられたデータは、イベント引数の NotificationData プロパティに格納されているバイト配列として渡されます。 コマンドや結果と同様に、返されるバイト配列の形式はベンダー定義です。 次の例では、通知データの最初のバイトにモジュールのリバーブ レベル設定の例の値が含まれている場合に、データが読み取られ、UI の更新に使用されます。

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