From 885506056c83726ebbcd6b01501494b8dc19e389 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 23 Sep 2016 19:53:19 +0000 Subject: [PATCH] [USBAUDIO] - start implementing USBAudioPinBuildDescriptors svn path=/trunk/; revision=72781 --- reactos/drivers/usb/usbaudio/filter.c | 310 +++++++++++++++++++++++- reactos/drivers/usb/usbaudio/guid.c | 1 + reactos/drivers/usb/usbaudio/usbaudio.h | 2 + 3 files changed, 309 insertions(+), 4 deletions(-) diff --git a/reactos/drivers/usb/usbaudio/filter.c b/reactos/drivers/usb/usbaudio/filter.c index 2ff6593f544..062d0b5473c 100644 --- a/reactos/drivers/usb/usbaudio/filter.c +++ b/reactos/drivers/usb/usbaudio/filter.c @@ -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) @@ -17,6 +82,17 @@ BuildUSBAudioFilterTopology( return STATUS_NOT_IMPLEMENTED; } +NTSTATUS +NTAPI +USBAudioFilterCreate( + PKSFILTER Filter, + PIRP Irp) +{ + UNIMPLEMENTED + return STATUS_SUCCESS; +} + + VOID CountTerminalUnits( IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, @@ -51,6 +127,9 @@ CountTerminalUnits( } TotalTerminalCount++; } + CommonDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); + if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) + break; } } } @@ -61,9 +140,145 @@ CountTerminalUnits( } *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( PKSDEVICE Device, @@ -71,8 +286,83 @@ USBAudioPinBuildDescriptors( 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 @@ USBAudioInitComponentId( 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 @@ USBAudioCreateFilterContext( PKSDEVICE Device) { KSFILTER_DESCRIPTOR FilterDescriptor; + PDEVICE_EXTENSION DeviceExtension; PKSCOMPONENTID ComponentId; NTSTATUS Status; @@ -107,7 +399,11 @@ USBAudioCreateFilterContext( /* 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,15 +430,21 @@ USBAudioCreateFilterContext( 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; } diff --git a/reactos/drivers/usb/usbaudio/guid.c b/reactos/drivers/usb/usbaudio/guid.c index 46ef2a4ea37..cfe056370e0 100644 --- a/reactos/drivers/usb/usbaudio/guid.c +++ b/reactos/drivers/usb/usbaudio/guid.c @@ -5,6 +5,7 @@ #include #include +#include #include #include diff --git a/reactos/drivers/usb/usbaudio/usbaudio.h b/reactos/drivers/usb/usbaudio/usbaudio.h index 33b911c0279..314527c98f2 100644 --- a/reactos/drivers/usb/usbaudio/usbaudio.h +++ b/reactos/drivers/usb/usbaudio/usbaudio.h @@ -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 -- 2.17.1