Author: janderwald Date: Fri Sep 23 19:53:19 2016 New Revision: 72781
URL: http://svn.reactos.org/svn/reactos?rev=72781&view=rev Log: [USBAUDIO] - start implementing USBAudioPinBuildDescriptors
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 Sep 23 19:53:19 2016 @@ -9,6 +9,71 @@
#include "usbaudio.h"
+GUID NodeTypeMicrophone = { STATIC_KSNODETYPE_MICROPHONE }; +GUID NodeTypeDesktopMicrophone = { STATIC_KSNODETYPE_DESKTOP_MICROPHONE }; +GUID NodeTypePersonalMicrophone = { STATIC_KSNODETYPE_PERSONAL_MICROPHONE }; +GUID NodeTypeOmmniMicrophone = { STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE }; +GUID NodeTypeArrayMicrophone = { STATIC_KSNODETYPE_MICROPHONE_ARRAY }; +GUID NodeTypeProcessingArrayMicrophone = { STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY }; +GUID NodeTypeSpeaker = { STATIC_KSNODETYPE_SPEAKER }; +GUID NodeTypeHeadphonesSpeaker = { STATIC_KSNODETYPE_HEADPHONES }; +GUID NodeTypeHMDA = { STATIC_KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO }; +GUID NodeTypeDesktopSpeaker = { STATIC_KSNODETYPE_DESKTOP_SPEAKER }; +GUID NodeTypeRoomSpeaker = { STATIC_KSNODETYPE_ROOM_SPEAKER }; +GUID NodeTypeCommunicationSpeaker = { STATIC_KSNODETYPE_COMMUNICATION_SPEAKER }; +GUID NodeTypeSubwoofer = { STATIC_KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER }; +GUID NodeTypeCapture = { STATIC_PINNAME_CAPTURE }; +GUID NodeTypePlayback = { STATIC_KSCATEGORY_AUDIO }; +GUID GUID_KSCATEGORY_AUDIO = { STATIC_KSCATEGORY_AUDIO }; + +KSPIN_INTERFACE StandardPinInterface = +{ + {STATIC_KSINTERFACESETID_Standard}, + KSINTERFACE_STANDARD_STREAMING, + 0 +}; + +KSPIN_MEDIUM StandardPinMedium = +{ + {STATIC_KSMEDIUMSETID_Standard}, + KSMEDIUM_TYPE_ANYINSTANCE, + 0 +}; + +KSDATARANGE BridgePinAudioFormat[] = +{ + { + sizeof(KSDATAFORMAT), + 0, + 0, + 0, + {STATIC_KSDATAFORMAT_TYPE_AUDIO}, + {STATIC_KSDATAFORMAT_SUBTYPE_ANALOG}, + {STATIC_KSDATAFORMAT_SPECIFIER_NONE} + } +}; + +static PKSDATARANGE BridgePinAudioFormats[] = +{ + &BridgePinAudioFormat[0] +}; + +static LPWSTR ReferenceString = L"global"; + +NTSTATUS +NTAPI +USBAudioFilterCreate( + PKSFILTER Filter, + PIRP Irp); + +static KSFILTER_DISPATCH USBAudioFilterDispatch = +{ + USBAudioFilterCreate, + NULL, + NULL, + NULL +}; + NTSTATUS BuildUSBAudioFilterTopology( PKSDEVICE Device) @@ -16,6 +81,17 @@ UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; } + +NTSTATUS +NTAPI +USBAudioFilterCreate( + PKSFILTER Filter, + PIRP Irp) +{ + UNIMPLEMENTED + return STATUS_SUCCESS; +} +
VOID CountTerminalUnits( @@ -51,6 +127,9 @@ } TotalTerminalCount++; } + CommonDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); + if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) + break; } } } @@ -61,8 +140,144 @@ } *NonStreamingTerminalDescriptorCount = NonStreamingTerminalCount; *TotalTerminalDescriptorCount = TotalTerminalCount; - -} +} + +LPGUID +UsbAudioGetPinCategoryFromTerminalDescriptor( + IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor) +{ + if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE) + return &NodeTypeMicrophone; + else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE) + return &NodeTypeDesktopMicrophone; + else if (TerminalDescriptor->wTerminalType == USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE) + return &NodeTypePersonalMicrophone; + else if (TerminalDescriptor->wTerminalType == USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE) + return &NodeTypeOmmniMicrophone; + else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE) + return &NodeTypeArrayMicrophone; + else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE) + return &NodeTypeProcessingArrayMicrophone; + + /* playback types */ + if (TerminalDescriptor->wTerminalType == USB_AUDIO_SPEAKER_TERMINAL_TYPE) + return &NodeTypeSpeaker; + else if (TerminalDescriptor->wTerminalType == USB_HEADPHONES_SPEAKER_TERMINAL_TYPE) + return &NodeTypeHeadphonesSpeaker; + else if (TerminalDescriptor->wTerminalType == USB_AUDIO_HMDA_TERMINAL_TYPE) + return &NodeTypeHMDA; + else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE) + return &NodeTypeDesktopSpeaker; + else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE) + return &NodeTypeRoomSpeaker; + else if (TerminalDescriptor->wTerminalType == USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE) + return &NodeTypeCommunicationSpeaker; + else if (TerminalDescriptor->wTerminalType == USB_AUDIO_SUBWOOFER_TERMINAL_TYPE) + return &NodeTypeSubwoofer; + + if (TerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE) + { + if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL) + return &NodeTypeCapture; + else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL) + return &NodeTypePlayback; + + } + return NULL; +} + +PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR +UsbAudioGetStreamingTerminalDescriptorByIndex( + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, + IN ULONG Index) +{ + PUSB_INTERFACE_DESCRIPTOR Descriptor; + PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor; + PUSB_COMMON_DESCRIPTOR CommonDescriptor; + PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor; + ULONG TerminalCount = 0; + + 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 = 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*/) + { + if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE) + { + if (TerminalCount == Index) + { + return InputTerminalDescriptor; + } + TerminalCount++; + } + } + CommonDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); + if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) + break; + } + } + } + } + return NULL; +} + +PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR +UsbAudioGetNonStreamingTerminalDescriptorByIndex( + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, + IN ULONG Index) +{ + + PUSB_INTERFACE_DESCRIPTOR Descriptor; + PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor; + PUSB_COMMON_DESCRIPTOR CommonDescriptor; + PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor; + ULONG TerminalCount = 0; + + 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 = 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*/) + { + if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE) + { + if (TerminalCount == Index) + { + return InputTerminalDescriptor; + } + TerminalCount++; + } + } + CommonDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); + if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) + break; + } + } + } + } + return NULL; +} + +
NTSTATUS USBAudioPinBuildDescriptors( @@ -71,8 +286,83 @@ PULONG PinDescriptorsCount, PULONG PinDescriptorSize) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + PDEVICE_EXTENSION DeviceExtension; + PKSPIN_DESCRIPTOR_EX Pins; + ULONG TotalTerminalDescriptorCount = 0; + ULONG NonStreamingTerminalDescriptorCount = 0; + ULONG Index = 0; + PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor = NULL; + + /* get device extension */ + DeviceExtension = Device->Context; + + CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount); + DPRINT1("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu", TotalTerminalDescriptorCount, NonStreamingTerminalDescriptorCount); + + /* allocate pins */ + Pins = AllocFunction(sizeof(KSPIN_DESCRIPTOR_EX) * TotalTerminalDescriptorCount); + if (!Pins) + { + /* no memory*/ + return STATUS_INSUFFICIENT_RESOURCES; + } + + for (Index = 0; Index < TotalTerminalDescriptorCount; Index++) + { + if (Index < (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount)) + { + /* irp sink pins*/ + TerminalDescriptor = UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index); + Pins[Index].PinDescriptor.InterfacesCount = 1; + Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface; + Pins[Index].PinDescriptor.MediumsCount = 1; + Pins[Index].PinDescriptor.Mediums = &StandardPinMedium; + Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor); + + if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL) + { + Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BOTH; + Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT; + } + else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL) + { + Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_SINK; + Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN; + } + + /* irp sinks / sources can be instantiated */ + Pins[Index].InstancesPossible = 1; + } + else + { + /* bridge pins */ + TerminalDescriptor = UsbAudioGetNonStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index - (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount)); + Pins[Index].PinDescriptor.InterfacesCount = 1; + Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface; + Pins[Index].PinDescriptor.MediumsCount = 1; + Pins[Index].PinDescriptor.Mediums = &StandardPinMedium; + Pins[Index].PinDescriptor.DataRanges = BridgePinAudioFormats; + Pins[Index].PinDescriptor.DataRangesCount = 1; + Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BRIDGE; + Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor); + + if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL) + { + Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN; + } + else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL) + { + Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT; + } + } + + } + + *PinDescriptors = Pins; + *PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR_EX); + *PinDescriptorsCount = TotalTerminalDescriptorCount; + + return STATUS_SUCCESS; }
NTSTATUS @@ -88,6 +378,7 @@ INIT_USBAUDIO_MID(&ComponentId->Manufacturer, DeviceExtension->DeviceDescriptor->idVendor); INIT_USBAUDIO_PID(&ComponentId->Product, DeviceExtension->DeviceDescriptor->idProduct);
+ //ComponentId->Component = KSCOMPONENTID_USBAUDIO; UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; } @@ -99,6 +390,7 @@ PKSDEVICE Device) { KSFILTER_DESCRIPTOR FilterDescriptor; + PDEVICE_EXTENSION DeviceExtension; PKSCOMPONENTID ComponentId; NTSTATUS Status;
@@ -107,7 +399,11 @@
/* init filter descriptor*/ FilterDescriptor.Version = KSFILTER_DESCRIPTOR_VERSION; + FilterDescriptor.Flags = 0; FilterDescriptor.ReferenceGuid = &KSNAME_Filter; + FilterDescriptor.Dispatch = &USBAudioFilterDispatch; + FilterDescriptor.CategoriesCount = 1; + FilterDescriptor.Categories = &GUID_KSCATEGORY_AUDIO;
/* init component id*/ ComponentId = AllocFunction(sizeof(KSCOMPONENTID)); @@ -134,14 +430,20 @@ return Status; }
+ DbgBreakPoint(); /* build topology */ Status = BuildUSBAudioFilterTopology(Device); if (!NT_SUCCESS(Status)) { /* failed*/ - FreeFunction(ComponentId); - return Status; - } + //FreeFunction(ComponentId); + //return Status; + } + + /* lets create the filter */ + DeviceExtension = Device->Context; + Status = KsCreateFilterFactory(Device->FunctionalDeviceObject, &FilterDescriptor, ReferenceString, NULL, KSCREATE_ITEM_FREEONSTOP, NULL, NULL, NULL); + DPRINT1("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 Sep 23 19:53:19 2016 @@ -5,6 +5,7 @@
#include <initguid.h> #include <wdmguid.h> +#include <ksmedia.h> #include <hubbusif.h> #include <usbbusif.h>
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 Sep 23 19:53:19 2016 @@ -32,6 +32,8 @@ #define USB_AUDIO_SUBWOOFER_TERMINAL_TYPE (0x0307) #define USB_AUDIO_UNDEFINED_TERMINAL_TYPE (0xFFFF)
+#define USB_AUDIO_INPUT_TERMINAL (0x02) +#define USB_AUDIO_OUTPUT_TERMINAL (0x03)
#include <pshpack1.h>