Author: janderwald Date: Fri Oct 14 22:08:28 2016 New Revision: 72971
URL: http://svn.reactos.org/svn/reactos?rev=72971&view=rev Log: [USBAUDIO] - partly implement BuildUSBAudioFilterTopology
Modified: trunk/reactos/drivers/usb/usbaudio/filter.c trunk/reactos/drivers/usb/usbaudio/guid.c trunk/reactos/drivers/usb/usbaudio/usbaudio.h
Modified: trunk/reactos/drivers/usb/usbaudio/filter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbaudio/filter... ============================================================================== --- trunk/reactos/drivers/usb/usbaudio/filter.c [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbaudio/filter.c [iso-8859-1] Fri Oct 14 22:08:28 2016 @@ -90,13 +90,270 @@ NULL };
+ULONG +CountTopologyComponents( + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor) +{ + PUSB_INTERFACE_DESCRIPTOR Descriptor; + PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor; + PUSB_COMMON_DESCRIPTOR CommonDescriptor; + PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor; + PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor; + PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor; + ULONG NodeCount = 0; + UCHAR Value; + + for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); + Descriptor != NULL; + Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1)) + { + if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */ + { + InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); + if (InterfaceHeaderDescriptor != NULL) + { + CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); + while (CommonDescriptor) + { + InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor; + if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/) + { + NodeCount++; + } + else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/) + { + FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor; + Value = FeatureUnitDescriptor->bmaControls[0]; + if (Value & 0x01) /* MUTE*/ + NodeCount++; + if (Value & 0x02) /* VOLUME */ + NodeCount++; + if (Value & 0x04) /* BASS */ + NodeCount++; + if (Value & 0x08) /* MID */ + NodeCount++; + if (Value & 0x10) /* TREBLE */ + NodeCount++; + if (Value & 0x20) /* GRAPHIC EQUALIZER */ + NodeCount++; + if (Value & 0x40) /* AUTOMATIC GAIN */ + NodeCount++; + if (Value & 0x80) /* DELAY */ + NodeCount++; + + /* FIXME handle logical channels too */ + } + else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */) + { + MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor; + NodeCount += MixerUnitDescriptor->bNrInPins + 1; /* KSNODETYPE_SUPERMIX for each source pin and KSNODETYPE_SUM for target */ + } + else + { + UNIMPLEMENTED + } + CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); + if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) + break; + } + } + } + } + return NodeCount; +} + +
NTSTATUS BuildUSBAudioFilterTopology( - PKSDEVICE Device) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + PKSDEVICE Device, + PKSFILTER_DESCRIPTOR FilterDescriptor) +{ + PDEVICE_EXTENSION DeviceExtension; + ULONG NodeCount, Index; + UCHAR Value; + PUSB_INTERFACE_DESCRIPTOR Descriptor; + PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor; + PUSB_COMMON_DESCRIPTOR CommonDescriptor; + PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor; + PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor; + PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor; + PKSNODE_DESCRIPTOR NodeDescriptors; + + /* get device extension */ + DeviceExtension = Device->Context; + + /* count topology nodes */ + NodeCount = CountTopologyComponents(DeviceExtension->ConfigurationDescriptor); + + /* init node descriptors*/ + FilterDescriptor->NodeDescriptors = NodeDescriptors = AllocFunction(NodeCount * sizeof(KSNODE_DESCRIPTOR)); + if (FilterDescriptor->NodeDescriptors == NULL) + { + /* no memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + FilterDescriptor->NodeDescriptorSize = sizeof(KSNODE_DESCRIPTOR); + + for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); + Descriptor != NULL; + Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1)) + { + if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */ + { + InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); + if (InterfaceHeaderDescriptor != NULL) + { + CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); + while (CommonDescriptor) + { + InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor; + if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/) + { + if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE) + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x200) + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_ADC; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_ADC; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300) + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + else + { + DPRINT1("Unexpected input terminal type %x\n", InputTerminalDescriptor->wTerminalType); + } + } + else if (InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/) + { + if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE) + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300) + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + else + { + DPRINT1("Unexpected output terminal type %x\n", InputTerminalDescriptor->wTerminalType); + } + } + + else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/) + { + FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor; + Value = FeatureUnitDescriptor->bmaControls[0]; + if (Value & 0x01) /* MUTE*/ + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUTE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUTE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + if (Value & 0x02) /* VOLUME */ + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_VOLUME; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_VOLUME; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + + if (Value & 0x04) /* BASS */ + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + + if (Value & 0x08) /* MID */ + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + + if (Value & 0x10) /* TREBLE */ + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + + if (Value & 0x20) /* GRAPHIC EQUALIZER */ + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + + if (Value & 0x40) /* AUTOMATIC GAIN */ + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + + if (Value & 0x80) /* DELAY */ + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + } + else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */) + { + MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor; + for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++) + { + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUPERMIX; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUPERMIX; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUM; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUM; + NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); + FilterDescriptor->NodeDescriptorsCount++; + } + else + { + UNIMPLEMENTED + } + CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); + if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) + break; + } + } + } + } + + return STATUS_SUCCESS; }
NTSTATUS @@ -411,7 +668,7 @@ DeviceExtension = Device->Context;
CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount); - DPRINT1("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu", TotalTerminalDescriptorCount, NonStreamingTerminalDescriptorCount); + DPRINT("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu\n", TotalTerminalDescriptorCount, NonStreamingTerminalDescriptorCount);
/* allocate pins */ Pins = AllocFunction(sizeof(KSPIN_DESCRIPTOR_EX) * TotalTerminalDescriptorCount); @@ -560,7 +817,7 @@ }
/* build topology */ - Status = BuildUSBAudioFilterTopology(Device); + Status = BuildUSBAudioFilterTopology(Device, FilterDescriptor); if (!NT_SUCCESS(Status)) { /* failed*/ @@ -570,7 +827,7 @@
/* lets create the filter */ Status = KsCreateFilterFactory(Device->FunctionalDeviceObject, FilterDescriptor, ReferenceString, NULL, KSCREATE_ITEM_FREEONSTOP, NULL, NULL, NULL); - DPRINT1("KsCreateFilterFactory: %x\n", Status); + DPRINT("KsCreateFilterFactory: %x\n", Status);
return Status; }
Modified: trunk/reactos/drivers/usb/usbaudio/guid.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbaudio/guid.c... ============================================================================== --- trunk/reactos/drivers/usb/usbaudio/guid.c [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbaudio/guid.c [iso-8859-1] Fri Oct 14 22:08:28 2016 @@ -7,5 +7,12 @@ DEFINE_GUID(KSDATAFORMAT_TYPE_AUDIO, 0x73647561L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); DEFINE_GUID(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, 0x05589f81L, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a); - +DEFINE_GUID(KSNODETYPE_SRC, 0x9DB7B9E0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1); +DEFINE_GUID(KSNODETYPE_ADC, 0x4D837FE0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1); +DEFINE_GUID(KSNODETYPE_DAC, 0x507AE360L, 0xC554, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1); +DEFINE_GUID(KSNODETYPE_MUTE, 0x02B223C0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1); +DEFINE_GUID(KSNODETYPE_TONE, 0x7607E580L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1); +DEFINE_GUID(KSNODETYPE_SUM, 0xDA441A60L, 0xC556, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1); +DEFINE_GUID(KSNODETYPE_SUPERMIX, 0xE573ADC0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1); +DEFINE_GUID(KSNODETYPE_VOLUME, 0x3A5ACC00L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1); /* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */
Modified: trunk/reactos/drivers/usb/usbaudio/usbaudio.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbaudio/usbaud... ============================================================================== --- trunk/reactos/drivers/usb/usbaudio/usbaudio.h [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbaudio/usbaudio.h [iso-8859-1] Fri Oct 14 22:08:28 2016 @@ -74,6 +74,34 @@ UCHAR iChannelNames; UCHAR iTerminal; }USB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR, *PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR; + +typedef struct +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + UCHAR bSourceID; + UCHAR bControlSize; + UCHAR bmaControls[1]; + UCHAR iFeature; +}USB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR, *PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR; + +typedef struct +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + UCHAR bNrInPins; + UCHAR baSourceID[1]; + UCHAR bNrChannels; + USHORT wChannelConfig; + UCHAR iChannelNames; + UCHAR bmControls; + UCHAR iMixer; +}USB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR, *PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR; +
typedef struct {