[USBAUDIO]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Tue, 25 Oct 2016 19:20:09 +0000 (19:20 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Tue, 25 Oct 2016 19:20:09 +0000 (19:20 +0000)
- implement mute control property handler

svn path=/trunk/; revision=73033

reactos/drivers/usb/usbaudio/filter.c
reactos/drivers/usb/usbaudio/guid.c
reactos/drivers/usb/usbaudio/pin.c
reactos/drivers/usb/usbaudio/usbaudio.h

index b544b10..d066af0 100644 (file)
@@ -90,6 +90,155 @@ static KSPIN_DISPATCH UsbAudioPinDispatch =
     NULL
 };
 
+NTSTATUS NTAPI FilterAudioVolumeHandler(IN PIRP Irp, IN PKSIDENTIFIER  Request, IN OUT PVOID  Data);
+NTSTATUS NTAPI FilterAudioMuteHandler(IN PIRP Irp, IN PKSIDENTIFIER  Request, IN OUT PVOID  Data);
+
+DEFINE_KSPROPERTY_TABLE_AUDIO_VOLUME(FilterAudioVolumePropertySet, FilterAudioVolumeHandler);
+DEFINE_KSPROPERTY_TABLE_AUDIO_MUTE(FilterAudioMutePropertySet, FilterAudioMuteHandler);
+
+
+static KSPROPERTY_SET FilterAudioVolumePropertySetArray[] =
+{
+    {
+        &KSPROPSETID_Audio,
+        sizeof(FilterAudioVolumePropertySet) / sizeof(KSPROPERTY_ITEM),
+        (const KSPROPERTY_ITEM*)&FilterAudioVolumePropertySet,
+        0,
+        NULL
+    }
+};
+
+static KSPROPERTY_SET FilterAudioMutePropertySetArray[] =
+{
+    {
+        &KSPROPSETID_Audio,
+        sizeof(FilterAudioMutePropertySet) / sizeof(KSPROPERTY_ITEM),
+        (const KSPROPERTY_ITEM*)&FilterAudioMutePropertySet,
+        0,
+        NULL
+    }
+};
+
+NTSTATUS
+UsbAudioGetSetProperty(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN UCHAR Request,
+    IN USHORT Value,
+    IN USHORT Index,
+    IN PVOID TransferBuffer,
+    IN ULONG TransferBufferLength,
+    IN ULONG TransferFlags)
+{
+    PURB Urb;
+    NTSTATUS Status;
+
+    /* allocate urb */
+    Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
+    if (!Urb)
+    {
+        /* no memory */
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* format urb */
+    UsbBuildVendorRequest(Urb,
+        URB_FUNCTION_CLASS_INTERFACE,
+        sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
+        TransferFlags,
+        0,
+        Request,
+        Value,
+        Index,
+        TransferBuffer,
+        NULL,
+        TransferBufferLength,
+        NULL);
+
+    /* submit urb */
+    Status = SubmitUrbSync(DeviceObject, Urb);
+
+    DPRINT1("UsbAudioGetSetProperty Status %x\n", Status);
+    FreeFunction(Urb);
+    return Status;
+}
+
+PNODE_CONTEXT
+FindNodeContextWithNode(
+    IN PNODE_CONTEXT NodeContext,
+    IN ULONG NodeContextCount,
+    IN ULONG NodeId)
+{
+    ULONG Index, NodeIndex;
+    for (Index = 0; Index < NodeContextCount; Index++)
+    {
+        for (NodeIndex = 0; NodeIndex < NodeContext[Index].NodeCount; NodeIndex++)
+        {
+            if (NodeContext[Index].Nodes[NodeIndex] == NodeId)
+            {
+                return &NodeContext[Index];
+            }
+        }
+    }
+    return NULL;
+}
+
+
+NTSTATUS
+NTAPI
+FilterAudioMuteHandler(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER  Request,
+    IN OUT PVOID  Data)
+{
+    PKSNODEPROPERTY_AUDIO_CHANNEL Property;
+    PKSFILTER Filter;
+    PFILTER_CONTEXT FilterContext;
+    PNODE_CONTEXT NodeContext;
+    PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
+    NTSTATUS Status = STATUS_INVALID_PARAMETER;
+
+    /* get filter from irp */
+    Filter = KsGetFilterFromIrp(Irp);
+
+    if (Filter)
+    {
+        /* get property */
+        Property = (PKSNODEPROPERTY_AUDIO_CHANNEL)Request;
+
+        /* get filter context */
+        FilterContext = (PFILTER_CONTEXT)Filter->Context;
+
+        /* search for node context */
+        NodeContext = FindNodeContextWithNode(FilterContext->DeviceExtension->NodeContext, FilterContext->DeviceExtension->NodeContextCount, Property->NodeProperty.NodeId);
+        if (NodeContext)
+        {
+            FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)NodeContext->Descriptor;
+            if (Property->NodeProperty.Property.Flags & KSPROPERTY_TYPE_GET)
+            {
+                Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x81, 0x100, FeatureUnitDescriptor->bUnitID << 8, Data, 1, USBD_TRANSFER_DIRECTION_IN);
+                Irp->IoStatus.Information = sizeof(BOOL);
+            }
+            else
+            {
+                Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x01, 0x100, FeatureUnitDescriptor->bUnitID << 8, Data, 1, USBD_TRANSFER_DIRECTION_OUT);
+            }
+        }
+    }
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+FilterAudioVolumeHandler(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER  Request,
+    IN OUT PVOID  Data)
+{
+    UNIMPLEMENTED
+    return STATUS_SUCCESS;
+}
+
+
 ULONG
 CountTopologyComponents(
     IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
@@ -200,10 +349,11 @@ BuildUSBAudioFilterTopology(
     PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
     PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
     PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor;
-       PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR OutputTerminalDescriptor;
+    PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR OutputTerminalDescriptor;
     PKSNODE_DESCRIPTOR NodeDescriptors;
     PNODE_CONTEXT NodeContext, PreviousNodeContext;
     PKSTOPOLOGY_CONNECTION Connections;
+    PKSAUTOMATION_TABLE AutomationTable;
 
     /* get device extension */
     DeviceExtension = Device->Context;
@@ -220,12 +370,13 @@ BuildUSBAudioFilterTopology(
     }
     FilterDescriptor->NodeDescriptorSize = sizeof(KSNODE_DESCRIPTOR);
 
-    NodeContext = AllocFunction(sizeof(NODE_CONTEXT) * ControlDescriptorCount);
+    DeviceExtension->NodeContext = NodeContext = AllocFunction(sizeof(NODE_CONTEXT) * ControlDescriptorCount);
     if (!NodeContext)
     {
         /* no memory */
         return STATUS_INSUFFICIENT_RESOURCES;
     }
+    DeviceExtension->NodeContextCount = ControlDescriptorCount;
     DescriptorCount = 0;
 
     /* first enumerate all topology nodes */
@@ -336,7 +487,13 @@ BuildUSBAudioFilterTopology(
                         {
                             NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUTE;
                             NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUTE;
-                            NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
+                            NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
+                            if (AutomationTable)
+                            {
+                                AutomationTable->PropertySets = FilterAudioMutePropertySetArray;
+                                AutomationTable->PropertySetsCount = 1;
+                                AutomationTable->PropertyItemSize = sizeof(KSPROPERTY_ITEM);
+                            }
 
                             /* insert into node context*/
                             NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
@@ -348,7 +505,13 @@ BuildUSBAudioFilterTopology(
                         {
                             NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_VOLUME;
                             NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_VOLUME;
-                            NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
+                            NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
+                            if (AutomationTable)
+                            {
+                                AutomationTable->PropertySets = FilterAudioVolumePropertySetArray;
+                                AutomationTable->PropertySetsCount = 1;
+                                AutomationTable->PropertyItemSize = sizeof(KSPROPERTY_ITEM);
+                            }
 
                             /* insert into node context*/
                             NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
index 3447c78..e117155 100644 (file)
@@ -16,4 +16,5 @@ DEFINE_GUID(KSNODETYPE_SUM,                      0xDA441A60L, 0xC556, 0x11D0, 0x
 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);
 DEFINE_GUID(KSCOMPONENTID_USBAUDIO,              0x8F1275F0L, 0x26E9, 0x4264, 0xBA, 0x4D, 0x39, 0xFF, 0xF0, 0x1D, 0x94, 0xAA);
+DEFINE_GUID(KSPROPSETID_Audio,                   0x45FFAAA0L, 0x6E1B, 0x11D0, 0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
 /* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */
index 180f14a..daba4c4 100644 (file)
@@ -90,58 +90,6 @@ UsbAudioAllocCaptureUrbIso(
 
 }
 
-NTSTATUS
-UsbAudioSetMuteOff(
-    IN PKSPIN Pin)
-{
-    PURB Urb;
-    PVOID SampleRateBuffer;
-    PPIN_CONTEXT PinContext;
-    NTSTATUS Status;
-
-    /* allocate sample rate buffer */
-    SampleRateBuffer = AllocFunction(sizeof(ULONG));
-    if (!SampleRateBuffer)
-    {
-        /* no memory */
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* allocate urb */
-    Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
-    if (!Urb)
-    {
-        /* no memory */
-        FreeFunction(SampleRateBuffer);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* FIXME: determine controls and format urb */
-    UsbBuildVendorRequest(Urb,
-        URB_FUNCTION_CLASS_INTERFACE,
-        sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
-        USBD_TRANSFER_DIRECTION_OUT,
-        0,
-        0x01,
-        0x100,
-        0x300,
-        SampleRateBuffer,
-        NULL,
-        1,
-        NULL);
-
-    /* get pin context */
-    PinContext = Pin->Context;
-
-    /* submit urb */
-    Status = SubmitUrbSync(PinContext->LowerDevice, Urb);
-
-    DPRINT1("UsbAudioSetMuteOff Pin %p Status %x\n", Pin, Status);
-    FreeFunction(Urb);
-    FreeFunction(SampleRateBuffer);
-    return Status;
-}
-
 NTSTATUS
 UsbAudioSetVolume(
     IN PKSPIN Pin)
@@ -696,7 +644,6 @@ USBAudioPinCreate(
     }
 
     /* FIXME move to build filter topology*/
-    UsbAudioSetMuteOff(Pin);
     UsbAudioSetVolume(Pin);
 
     /* select streaming interface */
index 36b95f0..6050806 100644 (file)
 #define USB_AUDIO_INPUT_TERMINAL (0x02)
 #define USB_AUDIO_OUTPUT_TERMINAL (0x03)
 
+#define DEFINE_KSPROPERTY_ITEM_AUDIO_VOLUME(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_AUDIO_VOLUMELEVEL,\
+        (Handler),\
+        sizeof(KSNODEPROPERTY_AUDIO_CHANNEL),\
+        sizeof(LONG),\
+        (Handler), NULL, 0, NULL, NULL, 0)
+
+
+#define DEFINE_KSPROPERTY_TABLE_AUDIO_VOLUME(TopologySet, Handler)\
+DEFINE_KSPROPERTY_TABLE(TopologySet) {\
+    DEFINE_KSPROPERTY_ITEM_AUDIO_VOLUME(Handler)\
+}
+
+#define DEFINE_KSPROPERTY_ITEM_AUDIO_MUTE(Handler)\
+    DEFINE_KSPROPERTY_ITEM(\
+        KSPROPERTY_AUDIO_MUTE,\
+        (Handler),\
+        sizeof(KSNODEPROPERTY_AUDIO_CHANNEL),\
+        sizeof(BOOL),\
+        (Handler), NULL, 0, NULL, NULL, 0)
+
+#define DEFINE_KSPROPERTY_TABLE_AUDIO_MUTE(TopologySet, Handler)\
+DEFINE_KSPROPERTY_TABLE(TopologySet) {\
+    DEFINE_KSPROPERTY_ITEM_AUDIO_MUTE(Handler)\
+}
+
+
+
 #include <pshpack1.h>
 
 typedef struct
@@ -128,6 +157,13 @@ typedef struct
 
 #include <poppack.h>
 
+typedef struct
+{
+    PUSB_COMMON_DESCRIPTOR Descriptor;
+    ULONG NodeCount;
+    ULONG Nodes[20];
+}NODE_CONTEXT, *PNODE_CONTEXT;
+
 typedef struct __DEVICE_EXTENSION__
 {
     PDEVICE_OBJECT LowerDevice;                                  /* lower device*/
@@ -135,7 +171,8 @@ typedef struct __DEVICE_EXTENSION__
     PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;                     /* usb device descriptor */
     PUSBD_INTERFACE_INFORMATION InterfaceInfo;                   /* interface information */
     USBD_CONFIGURATION_HANDLE ConfigurationHandle;               /* configuration handle */
-
+    PNODE_CONTEXT NodeContext;                                   /* node context */
+    ULONG NodeContextCount;                                      /* node context count */
 }DEVICE_EXTENSION, *PDEVICE_EXTENSION;
 
 typedef struct
@@ -161,14 +198,6 @@ typedef struct
     PKSWORKER        StarvationWorker;                              /* capture worker */
 }PIN_CONTEXT, *PPIN_CONTEXT;
 
-typedef struct
-{
-    PUSB_COMMON_DESCRIPTOR Descriptor;
-    ULONG NodeCount;
-    ULONG Nodes[20];
-}NODE_CONTEXT, *PNODE_CONTEXT;
-
-
 /* filter.c */
 
 NTSTATUS