Comunicación de verbos con el códec de audio HD
El IOCTL_AZALIABUS_SENDVERBS IOCTL lo usa la herramienta de configuración de patillas de Hdau.exe al definir topologías de sonido para los adaptadores de audio. No use este IOCTL para otros fines. Esta información sobre IOCTL_AZALIABUS_SENDVERBS solo se proporciona para documentar su diseño e implementación. Este IOCTL se admite en el controlador de clase de audio de Windows 7 Hdaudio.sys.
Los códecs de audio de alta definición (HD) pueden recibir y responder a verbos. Estos verbos y las respuestas de los códecs a estos verbos se documentan como parte de la especificación de audio HD.
En Windows 7 y versiones posteriores de los sistemas operativos Windows, el controlador de clase de audio HD usa el IOCTL_AZALIABUS_SENDVERBS IOCTL para comunicar verbos con el códec de audio. IOCTL_AZALIABUS_SENDVERBS se define como se muestra en el ejemplo siguiente:
#define IOCTL_AZALIABUS_SENDVERBS CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
Para obtener más información sobre FILE_DEVICE_UNKNOWN, METHOD_BUFFERED y FILE_ANY_ACCESS, consulte el archivo de encabezado Devioctl.h en Windows SDK.
Para iniciar la comunicación con el códec de audio, el controlador de clase llama a la función DeviceIoControl con los parámetros siguientes.
BOOL DeviceIoControl(
(HANDLE) hDevice, // handle to device
IOCTL_AZALIABUS_SENDVERBS, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
(LPVOID) lpOutBuffer, // output buffer
(DWORD) nOutBufferSize, // size of output buffer
(LPDWORD) lpBytesReturned, // number of bytes returned
(LPOVERLAPPED) lpOverlapped // OVERLAPPED structure
);
Si la llamada a DeviceIoControl se realiza correctamente, devuelve un valor distinto de cero. Si se produce un error en la llamada o está pendiente (no se procesa inmediatamente), DeviceIoControl devuelve un valor cero. El controlador de clase puede llamar a GetLastError para obtener un mensaje de error más detallado.
Cuando el controlador de audio debe cambiar los valores predeterminados de configuración de patillas, puede usar IOCTL_AZALIABUS_SENDVERBS para enviar y recibir verbos Set y Get del códec de audio. Si la comunicación con el códec de audio no está relacionada con la configuración de patillas, el códec de audio solo responde al verbo Get.
En el ejemplo siguiente se muestra una función que toma una estructura AzCorbeEntry y un HANDLE como parámetros y devuelve AzRirbResponse desde el códec.
AzRirbEntry SendVerb(HANDLE handle, AzCorbEntry verb)
{
UserModeCodecCommandPacket c;
UserModeCodecResponsePacket r;
c.NumCommands = 1;
c.Command[0] = verb;
DWORD BytesReturned;
//A nonzero value is returned for a successful call and it is interpreted as TRUE
BOOL rc = DeviceIoControl(handle, IOCTL_AZALIABUS_SENDVERBS, &c, sizeof(c), &r, sizeof(r), &BytesReturned, 0);
if(!rc)
{
printf("Failed to communicate with the device!\n");
return 0;
}
if(BytesReturned != sizeof(r))
{
printf("Wrong number of bytes returned!\n");
return 0;
}
return r.Response[0];
}
Los tipos de datos y estructuras que se usan en el ejemplo de código anterior se definen en el ejemplo siguiente:
AzCorbEntry
struct AzCorbEntry
{
ULONG Verb : 20; // 0:19
ULONG NodeId : 7; // 20:26
ULONG IndirectNID : 1; // 27
ULONG LinkId : 4; // 28:31
enum {Invalid = 0xffffffff};
AzCorbEntry(ULONG x = 0)
:
Verb(x),
NodeId(x >> 20),
IndirectNID(x >> 27),
LinkId(x >> 28) {}
operator ULONG()
{
return Verb | NodeId << 20 | IndirectNID << 27 | LinkId << 28;
}
};
AzRirbEntry
struct AzRirbEntry
{
union
{
struct
{
ULONG Response : 21; // 0 : 20
ULONG SubTag : 5; // 21 : 25
ULONG Tag : 6; // 26 : 31
} UnsolicitedForm;
ULONG Response : 32; // 0:31
};
ULONG Sdi : 4; // 32:35
ULONG Unsolicited : 1; // 36
ULONG Reserved0 : 26; // 37:62
ULONG Valid : 1; // 63 note this bit only exists
// on the "link". The fact that the response
// got into memory assures that it is valid
AzRirbEntry (ULONGLONG x = 0)
{
Response = x & 0xffffffff;
Sdi = x >> 32;
Unsolicited = x >> 36;
Reserved0 = x >> 37;
Valid = x >> 63;
}
operator ULONGLONG()
{
return (ULONGLONG)Response | (ULONGLONG)Sdi << 32 | (ULONGLONG)Unsolicited << 36 | (ULONGLONG)Reserved0 << 37 | (ULONGLONG)Valid << 63;
}
};
Las dos estructuras siguientes se usan junto con el IOCTL de transferencia de verbos para habilitar las transferencias de comandos y respuestas entre el controlador de audio y el códec de audio HD.
UserModeCodecCommandPacket
typedef struct _UserModeCodecCommandPacket
{
ULONG NumCommands; // number of commands in this packet
AzCorbEntry Command[1]; // variable length array of verbs
} UserModeCodecCommandPacket;
UserModeCodecResponsePacket
typedef struct _UserModeCodecResponsePacket
{
ULONG NumResponses; // on successful IOCTL, this will be updated with the number of responses.
AzRirbEntry Response[1]; // Variable length array of responses. lpOutBuffer param to DeviceIoControl
// must point to sufficient space to hold this IOCTL with all its responses
} UserModeCodecResponsePacket;