Configurar e consultar módulos de dispositivo de áudio
Este artigo mostra como enviar comandos e receber notificações de alteração de módulos de dispositivo de áudio de um aplicativo UWP. Um módulo de dispositivo de áudio pode ser uma unidade de processamento de efeito de hardware ou qualquer outro módulo de configuração de áudio definido por um driver de áudio. Esse recurso foi projetado para permitir que os provedores de módulo criem aplicativos UWP que permitem que os usuários controlem e obtenham status informações de um módulo de processamento de áudio em execução em um DSP. Para usar as APIs de módulo de dispositivo de áudio mostradas neste artigo, você deve especificar a funcionalidade de audioDeviceConfiguration restrita no manifesto do pacote do aplicativo.
Obter uma instância da classe AudioDeviceModulesManager
Todas as operações de módulo de dispositivo de áudio mostradas neste artigo começam obtendo uma instância do AudioDeviceModulesManager. Faça isso primeiro chamando o método GetDefaultAudioRenderId estático da classe MediaDevice . Isso retorna a ID do dispositivo de renderização de áudio padrão, que é então passado para o construtor de AudioDeviceModulesManager para criar uma instância da classe associada ao dispositivo de áudio.
C#
var endpointId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);
var audioModuleManager = new AudioDeviceModulesManager(endpointId);
Consultar módulos de dispositivo de áudio instalados
Consulte todos os módulos de dispositivo de áudio instalados chamando FindAll da classe AudioDeviceModulesManager . Consulte um conjunto específico de módulos de dispositivo de áudio chamando FindAllById e passando a ID dos módulos solicitados. O exemplo a seguir define uma ID para um conjunto de módulos, chama FindAllById para recuperar uma lista de objetos AudioDeviceModule e, em seguida, imprime os detalhes de cada módulo na saída de depuração.
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}");
}
Enviar um comando para um módulo de dispositivo de áudio e receber dados de resultado
Envie comandos para um módulo de dispositivo de áudio chamando SendCommandAsync no objeto AudioDeviceModule . O método SendCommandAsync usa uma matriz de bytes como um argumento. Normalmente, essa matriz de bytes contém um identificador de comando seguido pelos dados associados ao comando, mas o formato de comando e os valores são totalmente definidos pelo fornecedor e são tratados como transparentes pelo sistema.
O método SendCommandAsync retorna uma operação assíncrona que, após a conclusão, retorna um objeto ModuleCommandResult que representa o resultado do comando. A propriedade Status contém um valor de enumeração que indica se o sistema foi capaz de executar o comando. Isso não indica necessariamente que o módulo de dispositivo de áudio foi capaz de executar o comando com êxito. A propriedade Result contém uma matriz de bytes retornada pelo módulo de dispositivo de áudio para indicar o status do comando. Normalmente, esse será um valor que indica êxito ou falha seguido pelo resultado dos dados do comando. Assim como acontece com os comandos do módulo, os formatos e os valores de resposta do módulo são definidos pelo fornecedor.
O exemplo a seguir chama FindAllAsync para recuperar um conjunto de módulos de dispositivo de áudio. Um DataWriter é usado para criar uma matriz de bytes que contém um exemplo de comando e dados. SendCommandAsync é chamado para enviar o buffer de comando e, após a conclusão da operação assíncrona, um ModuleCommandResult é retornado. Se a execução do comando tiver sido bem-sucedida, um DataReader será usado pela primeira vez para ler um inteiro status valor retornado do módulo. Se esse valor for o valor de sucesso definido pelo fornecedor, o restante dos dados de resultado será lido e usado pelo aplicativo, como para atualizar a interface do usuário.
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
}
}
}
}
Receber notificações quando os módulos de dispositivo de áudio forem modificados
Os aplicativos podem receber notificações quando um módulo de dispositivo de áudio foi atualizado registrando-se para o evento ModuleNotificationReceived .
C#
var endpointId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);
var audioModuleManager = new AudioDeviceModulesManager(endpointId);
audioModuleManager.ModuleNotificationReceived += AudioModuleManager_ModuleNotificationReceived;
ModuleNotificationReceived será gerado quando qualquer módulo de dispositivo de áudio associado ao dispositivo de áudio atual for modificado. Para determinar se o evento está associado a um módulo específico, obtenha uma instância de AudioDeviceModule acessando a propriedade Module do AudioDeviceModuleNoticiationEventArgs passado para o manipulador de eventos e verificando a propriedade ClassId que identifica o módulo. Os dados associados ao evento são passados como uma matriz de bytes armazenada na propriedade NotificationData dos args de evento. Assim como acontece com comandos e resultados, o formato da matriz de bytes retornada é definido pelo fornecedor. No exemplo abaixo, se o primeiro byte dos dados de notificação contiver o valor de exemplo para a configuração de nível reverb do módulo, os dados serão lidos e usados para atualizar a interface do usuário.
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];
}
}
}
}