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/filte…
==============================================================================
--- 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.…
==============================================================================
--- 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/usbau…
==============================================================================
--- 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>