Communication de verbes avec le codec audio HD
La IOCTL_AZALIABUS_SENDVERBS IOCTL est utilisée par l’outil de configuration de broche Hdau.exe lorsque vous définissez des topologies sonores pour vos adaptateurs audio. N’utilisez pas ce IOCTL à d’autres fins. Ces informations sur IOCTL_AZALIABUS_SENDVERBS sont fournies pour documenter leur conception et leur implémentation uniquement. Cet IOCTL est pris en charge dans le pilote de classe audio Windows 7 Hdaudio.sys.
Les codecs audio haute définition (HD) peuvent recevoir des verbes et y répondre. Ces verbes et les réponses des codecs à ces verbes sont documentés dans le cadre de la spécification audio HD.
Dans Windows 7 et versions ultérieures des systèmes d’exploitation Windows, le pilote de classe audio HD utilise le IOCTL_AZALIABUS_SENDVERBS IOCTL pour communiquer des verbes avec le codec audio. IOCTL_AZALIABUS_SENDVERBS est défini comme indiqué dans l’exemple suivant :
#define IOCTL_AZALIABUS_SENDVERBS CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
Pour plus d’informations sur FILE_DEVICE_UNKNOWN, METHOD_BUFFERED et FILE_ANY_ACCESS, consultez le fichier d’en-tête Devioctl.h dans le Kit de développement logiciel (SDK) Windows.
Pour lancer la communication avec le codec audio, le pilote de classe appelle la fonction DeviceIoControl avec les paramètres suivants.
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 l’appel à DeviceIoControl réussit, il retourne une valeur différente de zéro. Si l’appel échoue ou est en attente (non traité immédiatement), DeviceIoControl retourne une valeur zéro. Le pilote de classe peut appeler GetLastError pour obtenir un message d’erreur plus détaillé.
Lorsque le pilote audio doit modifier les paramètres par défaut de la configuration des broches, il peut utiliser IOCTL_AZALIABUS_SENDVERBS pour envoyer et recevoir des verbes Set et Get à partir du codec audio. Si la communication avec le codec audio ne concerne pas la configuration de la broche, le codec audio répond uniquement au verbe Get.
L’exemple suivant montre une fonction qui prend une structure AzCorbeEntry et un HANDLE en tant que paramètres et retourne L’AzRirbResponse à partir du codec.
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];
}
Les types de données et les structures utilisés dans l’exemple de code précédent sont définis dans l’exemple suivant :
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;
}
};
Les deux structures suivantes sont utilisées avec l’IOCTL de transfert de verbe pour activer les transferts de commandes et de réponse entre le pilote audio et le codec 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;