[NTFS]
[reactos.git] / drivers / usb / usbaudio / filter.c
1 /*
2 * PROJECT: ReactOS Universal Audio Class Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbaudio/filter.c
5 * PURPOSE: USB Audio device driver.
6 * PROGRAMMERS:
7 * Johannes Anderwald (johannes.anderwald@reactos.org)
8 */
9
10 #include "usbaudio.h"
11
12 GUID NodeTypeMicrophone = { STATIC_KSNODETYPE_MICROPHONE };
13 GUID NodeTypeDesktopMicrophone = { STATIC_KSNODETYPE_DESKTOP_MICROPHONE };
14 GUID NodeTypePersonalMicrophone = { STATIC_KSNODETYPE_PERSONAL_MICROPHONE };
15 GUID NodeTypeOmmniMicrophone = { STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE };
16 GUID NodeTypeArrayMicrophone = { STATIC_KSNODETYPE_MICROPHONE_ARRAY };
17 GUID NodeTypeProcessingArrayMicrophone = { STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY };
18 GUID NodeTypeSpeaker = { STATIC_KSNODETYPE_SPEAKER };
19 GUID NodeTypeHeadphonesSpeaker = { STATIC_KSNODETYPE_HEADPHONES };
20 GUID NodeTypeHMDA = { STATIC_KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO };
21 GUID NodeTypeDesktopSpeaker = { STATIC_KSNODETYPE_DESKTOP_SPEAKER };
22 GUID NodeTypeRoomSpeaker = { STATIC_KSNODETYPE_ROOM_SPEAKER };
23 GUID NodeTypeCommunicationSpeaker = { STATIC_KSNODETYPE_COMMUNICATION_SPEAKER };
24 GUID NodeTypeSubwoofer = { STATIC_KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER };
25 GUID NodeTypeCapture = { STATIC_PINNAME_CAPTURE };
26 GUID NodeTypePlayback = { STATIC_KSCATEGORY_AUDIO };
27 GUID GUID_KSCATEGORY_AUDIO = { STATIC_KSCATEGORY_AUDIO };
28
29 KSPIN_INTERFACE StandardPinInterface =
30 {
31 {STATIC_KSINTERFACESETID_Standard},
32 KSINTERFACE_STANDARD_STREAMING,
33 0
34 };
35
36 KSPIN_MEDIUM StandardPinMedium =
37 {
38 {STATIC_KSMEDIUMSETID_Standard},
39 KSMEDIUM_TYPE_ANYINSTANCE,
40 0
41 };
42
43 KSDATARANGE BridgePinAudioFormat[] =
44 {
45 {
46 {
47 sizeof(KSDATAFORMAT),
48 0,
49 0,
50 0,
51 {STATIC_KSDATAFORMAT_TYPE_AUDIO},
52 {STATIC_KSDATAFORMAT_SUBTYPE_ANALOG},
53 {STATIC_KSDATAFORMAT_SPECIFIER_NONE}
54 }
55 }
56 };
57
58 static PKSDATARANGE BridgePinAudioFormats[] =
59 {
60 &BridgePinAudioFormat[0]
61 };
62
63 static LPWSTR ReferenceString = L"global";
64
65 NTSTATUS
66 NTAPI
67 USBAudioFilterCreate(
68 PKSFILTER Filter,
69 PIRP Irp);
70
71 static KSFILTER_DISPATCH USBAudioFilterDispatch =
72 {
73 USBAudioFilterCreate,
74 NULL,
75 NULL,
76 NULL
77 };
78
79 static KSPIN_DISPATCH UsbAudioPinDispatch =
80 {
81 USBAudioPinCreate,
82 USBAudioPinClose,
83 USBAudioPinProcess,
84 USBAudioPinReset,
85 USBAudioPinSetDataFormat,
86 USBAudioPinSetDeviceState,
87 NULL,
88 NULL,
89 NULL,
90 NULL
91 };
92
93 NTSTATUS NTAPI FilterAudioVolumeHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
94 NTSTATUS NTAPI FilterAudioMuteHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
95
96 DEFINE_KSPROPERTY_TABLE_AUDIO_VOLUME(FilterAudioVolumePropertySet, FilterAudioVolumeHandler);
97 DEFINE_KSPROPERTY_TABLE_AUDIO_MUTE(FilterAudioMutePropertySet, FilterAudioMuteHandler);
98
99
100 static KSPROPERTY_SET FilterAudioVolumePropertySetArray[] =
101 {
102 {
103 &KSPROPSETID_Audio,
104 sizeof(FilterAudioVolumePropertySet) / sizeof(KSPROPERTY_ITEM),
105 (const KSPROPERTY_ITEM*)&FilterAudioVolumePropertySet,
106 0,
107 NULL
108 }
109 };
110
111 static KSPROPERTY_SET FilterAudioMutePropertySetArray[] =
112 {
113 {
114 &KSPROPSETID_Audio,
115 sizeof(FilterAudioMutePropertySet) / sizeof(KSPROPERTY_ITEM),
116 (const KSPROPERTY_ITEM*)&FilterAudioMutePropertySet,
117 0,
118 NULL
119 }
120 };
121
122 NTSTATUS
123 UsbAudioGetSetProperty(
124 IN PDEVICE_OBJECT DeviceObject,
125 IN UCHAR Request,
126 IN USHORT Value,
127 IN USHORT Index,
128 IN PVOID TransferBuffer,
129 IN ULONG TransferBufferLength,
130 IN ULONG TransferFlags)
131 {
132 PURB Urb;
133 NTSTATUS Status;
134
135 /* allocate urb */
136 Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
137 if (!Urb)
138 {
139 /* no memory */
140 return STATUS_INSUFFICIENT_RESOURCES;
141 }
142
143 /* format urb */
144 UsbBuildVendorRequest(Urb,
145 URB_FUNCTION_CLASS_INTERFACE,
146 sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
147 TransferFlags,
148 0,
149 Request,
150 Value,
151 Index,
152 TransferBuffer,
153 NULL,
154 TransferBufferLength,
155 NULL);
156
157 /* submit urb */
158 Status = SubmitUrbSync(DeviceObject, Urb);
159
160 FreeFunction(Urb);
161 return Status;
162 }
163
164 PNODE_CONTEXT
165 FindNodeContextWithNode(
166 IN PNODE_CONTEXT NodeContext,
167 IN ULONG NodeContextCount,
168 IN ULONG NodeId)
169 {
170 ULONG Index, NodeIndex;
171 for (Index = 0; Index < NodeContextCount; Index++)
172 {
173 for (NodeIndex = 0; NodeIndex < NodeContext[Index].NodeCount; NodeIndex++)
174 {
175 if (NodeContext[Index].Nodes[NodeIndex] == NodeId)
176 {
177 return &NodeContext[Index];
178 }
179 }
180 }
181 return NULL;
182 }
183
184
185 NTSTATUS
186 NTAPI
187 FilterAudioMuteHandler(
188 IN PIRP Irp,
189 IN PKSIDENTIFIER Request,
190 IN OUT PVOID Data)
191 {
192 PKSNODEPROPERTY_AUDIO_CHANNEL Property;
193 PKSFILTER Filter;
194 PFILTER_CONTEXT FilterContext;
195 PNODE_CONTEXT NodeContext;
196 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
197 NTSTATUS Status = STATUS_INVALID_PARAMETER;
198
199 /* get filter from irp */
200 Filter = KsGetFilterFromIrp(Irp);
201
202 if (Filter)
203 {
204 /* get property */
205 Property = (PKSNODEPROPERTY_AUDIO_CHANNEL)Request;
206
207 /* get filter context */
208 FilterContext = (PFILTER_CONTEXT)Filter->Context;
209
210 /* search for node context */
211 NodeContext = FindNodeContextWithNode(FilterContext->DeviceExtension->NodeContext, FilterContext->DeviceExtension->NodeContextCount, Property->NodeProperty.NodeId);
212 if (NodeContext)
213 {
214 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)NodeContext->Descriptor;
215 if (Property->NodeProperty.Property.Flags & KSPROPERTY_TYPE_GET)
216 {
217 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x81, 0x1 << 8, FeatureUnitDescriptor->bUnitID << 8, Data, 1, USBD_TRANSFER_DIRECTION_IN);
218 Irp->IoStatus.Information = sizeof(BOOL);
219 }
220 else
221 {
222 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x01, 0x1 << 8, FeatureUnitDescriptor->bUnitID << 8, Data, 1, USBD_TRANSFER_DIRECTION_OUT);
223 }
224 }
225 }
226 return Status;
227 }
228
229 NTSTATUS
230 NTAPI
231 FilterAudioVolumeHandler(
232 IN PIRP Irp,
233 IN PKSIDENTIFIER Request,
234 IN OUT PVOID Data)
235 {
236 PKSNODEPROPERTY_AUDIO_CHANNEL Property;
237 PKSFILTER Filter;
238 PFILTER_CONTEXT FilterContext;
239 PNODE_CONTEXT NodeContext;
240 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
241 PSHORT TransferBuffer;
242 LONG Value;
243 NTSTATUS Status = STATUS_INVALID_PARAMETER;
244
245
246 /* get filter from irp */
247 Filter = KsGetFilterFromIrp(Irp);
248
249 if (Filter)
250 {
251 /* get property */
252 Property = (PKSNODEPROPERTY_AUDIO_CHANNEL)Request;
253
254 /* get filter context */
255 FilterContext = (PFILTER_CONTEXT)Filter->Context;
256
257 TransferBuffer = AllocFunction(sizeof(USHORT) * 3);
258 ASSERT(TransferBuffer);
259
260 Value = *(PLONG)Data;
261
262 /* search for node context */
263 NodeContext = FindNodeContextWithNode(FilterContext->DeviceExtension->NodeContext, FilterContext->DeviceExtension->NodeContextCount, Property->NodeProperty.NodeId);
264 if (NodeContext)
265 {
266 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)NodeContext->Descriptor;
267 if (Property->NodeProperty.Property.Flags & KSPROPERTY_TYPE_GET)
268 {
269 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x81, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[0], sizeof(USHORT), USBD_TRANSFER_DIRECTION_IN);
270 Value = (LONG)TransferBuffer[0] * 256;
271
272 *(PLONG)Data = Value;
273 Irp->IoStatus.Information = sizeof(BOOL);
274 }
275 else
276 {
277 /* downscale value */
278 Value /= 256;
279
280 /* get minimum value */
281 UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x82, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[0], sizeof(USHORT), USBD_TRANSFER_DIRECTION_IN);
282
283 /* get maximum value */
284 UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x83, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[1], sizeof(USHORT), USBD_TRANSFER_DIRECTION_IN);
285
286 if (TransferBuffer[0] > Value)
287 {
288 /* use minimum value */
289 Value = TransferBuffer[0];
290 }
291
292 if (TransferBuffer[1] < Value)
293 {
294 /* use maximum value */
295 Value = TransferBuffer[1];
296 }
297
298 /* store value */
299 TransferBuffer[2] = Value;
300
301 /* set volume request */
302 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x01, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[2], sizeof(USHORT), USBD_TRANSFER_DIRECTION_OUT);
303 if (NT_SUCCESS(Status))
304 {
305 /* store number of bytes transferred*/
306 Irp->IoStatus.Information = sizeof(LONG);
307 }
308 }
309 }
310
311 /* free transfer buffer */
312 FreeFunction(TransferBuffer);
313 }
314 return Status;
315 }
316
317
318 ULONG
319 CountTopologyComponents(
320 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
321 OUT PULONG OutDescriptorCount)
322 {
323 PUSB_INTERFACE_DESCRIPTOR Descriptor;
324 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
325 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
326 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
327 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
328 PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor;
329 PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR SelectorUnitDescriptor;
330 ULONG NodeCount = 0, Length, Index;
331 ULONG DescriptorCount = 0;
332 UCHAR Value;
333
334 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
335 Descriptor != NULL;
336 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
337 {
338 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
339 {
340 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
341 if (InterfaceHeaderDescriptor != NULL)
342 {
343 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
344 while (CommonDescriptor)
345 {
346 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
347 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
348 {
349 NodeCount++;
350 DescriptorCount++;
351 }
352 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
353 {
354 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor;
355 DescriptorCount++;
356
357 /* get controls from all channels*/
358 Value = 0;
359 Length = FeatureUnitDescriptor->bLength - 7;
360 for (Index = 0; Index < Length; Index++)
361 {
362 Value |= FeatureUnitDescriptor->bmaControls[Index];
363 }
364
365 if (Value & 0x01) /* MUTE*/
366 NodeCount++;
367 if (Value & 0x02) /* VOLUME */
368 NodeCount++;
369 if (Value & 0x04) /* BASS */
370 NodeCount++;
371 if (Value & 0x08) /* MID */
372 NodeCount++;
373 if (Value & 0x10) /* TREBLE */
374 NodeCount++;
375 if (Value & 0x20) /* GRAPHIC EQUALIZER */
376 NodeCount++;
377 if (Value & 0x40) /* AUTOMATIC GAIN */
378 NodeCount++;
379 if (Value & 0x80) /* DELAY */
380 NodeCount++;
381 }
382 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
383 {
384 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor;
385 DescriptorCount++;
386 NodeCount += MixerUnitDescriptor->bNrInPins + 1; /* KSNODETYPE_SUPERMIX for each source pin and KSNODETYPE_SUM for target */
387 }
388 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR_UNIT */)
389 {
390 SelectorUnitDescriptor = (PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR)InputTerminalDescriptor;
391 DescriptorCount++;
392 NodeCount++;
393 }
394 else
395 {
396 UNIMPLEMENTED;
397 }
398 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
399 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
400 break;
401 }
402 }
403 }
404 }
405 *OutDescriptorCount = DescriptorCount;
406 return NodeCount;
407 }
408
409 PNODE_CONTEXT
410 FindNodeContextWithId(
411 IN PNODE_CONTEXT NodeContext,
412 IN ULONG NodeContextCount,
413 IN UCHAR TerminalId)
414 {
415 ULONG Index;
416 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor;
417
418 for (Index = 0; Index < NodeContextCount; Index++)
419 {
420 TerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)NodeContext[Index].Descriptor;
421 if (TerminalDescriptor->bTerminalID == TerminalId)
422 return &NodeContext[Index];
423 }
424 return NULL;
425 }
426
427 NTSTATUS
428 BuildUSBAudioFilterTopology(
429 PKSDEVICE Device,
430 PKSFILTER_DESCRIPTOR FilterDescriptor)
431 {
432 PDEVICE_EXTENSION DeviceExtension;
433 ULONG NodeCount, Index, DescriptorCount, StreamingTerminalIndex, NonStreamingTerminalDescriptorCount, TotalTerminalDescriptorCount, StreamingTerminalPinOffset, ControlDescriptorCount, Length;
434 UCHAR Value;
435 PUSB_INTERFACE_DESCRIPTOR Descriptor;
436 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
437 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
438 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
439 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
440 PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor;
441 PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR OutputTerminalDescriptor;
442 PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR SelectorUnitDescriptor;
443 PKSNODE_DESCRIPTOR NodeDescriptors;
444 PNODE_CONTEXT NodeContext, PreviousNodeContext;
445 PKSTOPOLOGY_CONNECTION Connections;
446 PKSAUTOMATION_TABLE AutomationTable;
447
448 /* get device extension */
449 DeviceExtension = Device->Context;
450
451 /* count topology nodes */
452 NodeCount = CountTopologyComponents(DeviceExtension->ConfigurationDescriptor, &ControlDescriptorCount);
453
454 /* init node descriptors*/
455 FilterDescriptor->NodeDescriptors = NodeDescriptors = AllocFunction(NodeCount * sizeof(KSNODE_DESCRIPTOR));
456 if (FilterDescriptor->NodeDescriptors == NULL)
457 {
458 /* no memory */
459 return STATUS_INSUFFICIENT_RESOURCES;
460 }
461 FilterDescriptor->NodeDescriptorSize = sizeof(KSNODE_DESCRIPTOR);
462
463 DeviceExtension->NodeContext = NodeContext = AllocFunction(sizeof(NODE_CONTEXT) * ControlDescriptorCount);
464 if (!NodeContext)
465 {
466 /* no memory */
467 return STATUS_INSUFFICIENT_RESOURCES;
468 }
469 DeviceExtension->NodeContextCount = ControlDescriptorCount;
470 DescriptorCount = 0;
471
472 /* first enumerate all topology nodes */
473 for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
474 Descriptor != NULL;
475 Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
476 {
477 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
478 {
479 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
480 if (InterfaceHeaderDescriptor != NULL)
481 {
482 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
483 while (CommonDescriptor)
484 {
485 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
486 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/)
487 {
488 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
489 {
490 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC;
491 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC;
492 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
493
494 /* insert into node context*/
495 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
496 NodeContext[DescriptorCount].NodeCount = 1;
497 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
498 DescriptorCount++;
499
500 FilterDescriptor->NodeDescriptorsCount++;
501 }
502 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x200)
503 {
504 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_ADC;
505 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_ADC;
506 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
507
508 /* insert into node context*/
509 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
510 NodeContext[DescriptorCount].NodeCount = 1;
511 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
512 DescriptorCount++;
513
514
515 FilterDescriptor->NodeDescriptorsCount++;
516 }
517 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300)
518 {
519 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC;
520 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC;
521 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
522
523 /* insert into node context*/
524 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
525 NodeContext[DescriptorCount].NodeCount = 1;
526 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
527 DescriptorCount++;
528
529 FilterDescriptor->NodeDescriptorsCount++;
530 }
531 else
532 {
533 DPRINT1("Unexpected input terminal type %x\n", InputTerminalDescriptor->wTerminalType);
534 }
535 }
536 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
537 {
538 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
539 {
540 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC;
541 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC;
542 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
543
544 /* insert into node context*/
545 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
546 NodeContext[DescriptorCount].NodeCount = 1;
547 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
548 DescriptorCount++;
549
550 FilterDescriptor->NodeDescriptorsCount++;
551 }
552 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300)
553 {
554 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC;
555 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC;
556 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
557
558 /* insert into node context*/
559 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
560 NodeContext[DescriptorCount].NodeCount = 1;
561 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
562 DescriptorCount++;
563
564 FilterDescriptor->NodeDescriptorsCount++;
565 }
566 else
567 {
568 DPRINT1("Unexpected output terminal type %x\n", InputTerminalDescriptor->wTerminalType);
569 }
570 }
571
572 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
573 {
574 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)CommonDescriptor;
575
576 /* get controls from all channels*/
577 Value = 0;
578 Length = FeatureUnitDescriptor->bLength - 7;
579 for (Index = 0; Index < Length; Index++)
580 {
581 Value |= FeatureUnitDescriptor->bmaControls[Index];
582 }
583
584
585 if (Value & 0x01) /* MUTE*/
586 {
587 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUTE;
588 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUTE;
589 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
590 if (AutomationTable)
591 {
592 AutomationTable->PropertySets = FilterAudioMutePropertySetArray;
593 AutomationTable->PropertySetsCount = 1;
594 AutomationTable->PropertyItemSize = sizeof(KSPROPERTY_ITEM);
595 }
596
597 /* insert into node context*/
598 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
599 NodeContext[DescriptorCount].NodeCount++;
600
601 FilterDescriptor->NodeDescriptorsCount++;
602 }
603 if (Value & 0x02) /* VOLUME */
604 {
605 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_VOLUME;
606 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_VOLUME;
607 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
608 if (AutomationTable)
609 {
610 AutomationTable->PropertySets = FilterAudioVolumePropertySetArray;
611 AutomationTable->PropertySetsCount = 1;
612 AutomationTable->PropertyItemSize = sizeof(KSPROPERTY_ITEM);
613 }
614
615 /* insert into node context*/
616 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
617 NodeContext[DescriptorCount].NodeCount++;
618
619 FilterDescriptor->NodeDescriptorsCount++;
620 }
621
622 if (Value & 0x04) /* BASS */
623 {
624 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
625 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
626 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
627
628 /* insert into node context*/
629 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
630 NodeContext[DescriptorCount].NodeCount++;
631
632 FilterDescriptor->NodeDescriptorsCount++;
633 }
634
635 if (Value & 0x08) /* MID */
636 {
637 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
638 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
639 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
640
641 /* insert into node context*/
642 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
643 NodeContext[DescriptorCount].NodeCount++;
644
645 FilterDescriptor->NodeDescriptorsCount++;
646 }
647
648 if (Value & 0x10) /* TREBLE */
649 {
650 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
651 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
652 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
653
654 /* insert into node context*/
655 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
656 NodeContext[DescriptorCount].NodeCount++;
657
658
659 FilterDescriptor->NodeDescriptorsCount++;
660 }
661
662 if (Value & 0x20) /* GRAPHIC EQUALIZER */
663 {
664 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
665 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
666 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
667
668 /* insert into node context*/
669 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
670 NodeContext[DescriptorCount].NodeCount++;
671
672 FilterDescriptor->NodeDescriptorsCount++;
673 }
674
675 if (Value & 0x40) /* AUTOMATIC GAIN */
676 {
677 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_AGC;
678 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_AGC;
679 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
680
681 /* insert into node context*/
682 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
683 NodeContext[DescriptorCount].NodeCount++;
684
685
686 FilterDescriptor->NodeDescriptorsCount++;
687 }
688
689 if (Value & 0x80) /* DELAY */
690 {
691 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
692 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
693 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
694
695 /* insert into node context*/
696 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
697 NodeContext[DescriptorCount].NodeCount++;
698
699 FilterDescriptor->NodeDescriptorsCount++;
700 }
701 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
702 DescriptorCount++;
703
704 }
705 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
706 {
707 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)CommonDescriptor;
708 for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++)
709 {
710 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUPERMIX;
711 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUPERMIX;
712 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
713
714 /* insert into node context*/
715 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
716 NodeContext[DescriptorCount].NodeCount++;
717
718 FilterDescriptor->NodeDescriptorsCount++;
719 }
720
721 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUM;
722 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUM;
723 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
724
725 /* insert into node context*/
726 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
727 NodeContext[DescriptorCount].NodeCount++;
728 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
729 DescriptorCount++;
730
731 FilterDescriptor->NodeDescriptorsCount++;
732 }
733 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR UNIT */)
734 {
735 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUX;
736 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUX;
737 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
738
739 /* insert into node context*/
740 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
741 NodeContext[DescriptorCount].NodeCount = 1;
742 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
743 DescriptorCount++;
744 FilterDescriptor->NodeDescriptorsCount++;
745 }
746 else
747 {
748 UNIMPLEMENTED;
749 }
750 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
751 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
752 break;
753 }
754 }
755 }
756 }
757
758 /* FIXME determine connections count*/
759 FilterDescriptor->Connections = Connections = AllocFunction(sizeof(KSTOPOLOGY_CONNECTION) * FilterDescriptor->NodeDescriptorsCount * 2);
760 if (!FilterDescriptor->Connections)
761 {
762 /* no memory */
763 return STATUS_INSUFFICIENT_RESOURCES;
764 }
765 FilterDescriptor->ConnectionsCount = 0;
766
767 /* now build connections array */
768 DescriptorCount = 0;
769 StreamingTerminalIndex = 0;
770 NodeCount = 0;
771
772 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount);
773 StreamingTerminalPinOffset = TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount;
774
775 for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
776 Descriptor != NULL;
777 Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
778 {
779 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
780 {
781 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
782 if (InterfaceHeaderDescriptor != NULL)
783 {
784 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
785 while (CommonDescriptor)
786 {
787 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
788 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/)
789 {
790 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
791 {
792 Connections[FilterDescriptor->ConnectionsCount].FromNode = KSFILTER_NODE;
793 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = StreamingTerminalIndex;
794 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
795 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
796 FilterDescriptor->ConnectionsCount++;
797 StreamingTerminalIndex++;
798
799 }
800 else
801 {
802 Connections[FilterDescriptor->ConnectionsCount].FromNode = KSFILTER_NODE;
803 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = StreamingTerminalPinOffset;
804 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
805 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
806 FilterDescriptor->ConnectionsCount++;
807 StreamingTerminalPinOffset++;
808 }
809 DescriptorCount++;
810 }
811 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
812 {
813 OutputTerminalDescriptor = (PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
814 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, OutputTerminalDescriptor->bSourceID);
815 if (PreviousNodeContext)
816 {
817 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
818 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
819 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
820 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
821 FilterDescriptor->ConnectionsCount++;
822 }
823
824 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
825 {
826 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[0];
827 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
828 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = StreamingTerminalIndex;
829 Connections[FilterDescriptor->ConnectionsCount].ToNode = KSFILTER_NODE;
830 FilterDescriptor->ConnectionsCount++;
831 StreamingTerminalIndex++;
832 }
833 else
834 {
835 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[0];
836 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
837 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = StreamingTerminalPinOffset;
838 Connections[FilterDescriptor->ConnectionsCount].ToNode = KSFILTER_NODE;
839 FilterDescriptor->ConnectionsCount++;
840
841 StreamingTerminalPinOffset++;
842 }
843 DescriptorCount++;
844 }
845 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
846 {
847 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor;
848 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, FeatureUnitDescriptor->bSourceID);
849 if (PreviousNodeContext)
850 {
851 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount-1];
852 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
853 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
854 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
855 FilterDescriptor->ConnectionsCount++;
856 }
857 for (Index = 1; Index < NodeContext[DescriptorCount].NodeCount; Index++)
858 {
859 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[Index - 1];
860 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
861 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
862 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[Index];
863 FilterDescriptor->ConnectionsCount++;
864 }
865
866 DescriptorCount++;
867 }
868 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
869 {
870 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor;
871 for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++)
872 {
873 Value = MixerUnitDescriptor->baSourceID[Index];
874 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, Value);
875 if (PreviousNodeContext)
876 {
877 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
878 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
879 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
880 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[Index];
881 FilterDescriptor->ConnectionsCount++;
882 }
883
884 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[Index];
885 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
886 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1 + Index;
887 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount-1];
888 FilterDescriptor->ConnectionsCount++;
889 }
890 DescriptorCount++;
891 }
892 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR_UNIT */)
893 {
894 SelectorUnitDescriptor = (PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR)InputTerminalDescriptor;
895 for (Index = 0; Index < SelectorUnitDescriptor->bNrInPins; Index++)
896 {
897 Value = SelectorUnitDescriptor->baSourceID[Index];
898 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, Value);
899 if (PreviousNodeContext)
900 {
901 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
902 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
903 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
904 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
905 FilterDescriptor->ConnectionsCount++;
906 }
907 }
908 DescriptorCount++;
909 }
910 else
911 {
912 UNIMPLEMENTED;
913 }
914 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
915 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
916 break;
917 }
918 }
919 }
920 }
921
922
923
924 return STATUS_SUCCESS;
925 }
926
927 NTSTATUS
928 NTAPI
929 USBAudioFilterCreate(
930 PKSFILTER Filter,
931 PIRP Irp)
932 {
933 PKSFILTERFACTORY FilterFactory;
934 PKSDEVICE Device;
935 PFILTER_CONTEXT FilterContext;
936
937 FilterFactory = KsGetParent(Filter);
938 if (FilterFactory == NULL)
939 {
940 /* invalid parameter */
941 return STATUS_INVALID_PARAMETER;
942 }
943
944 Device = KsGetParent(FilterFactory);
945 if (Device == NULL)
946 {
947 /* invalid parameter */
948 return STATUS_INVALID_PARAMETER;
949 }
950
951 /* alloc filter context */
952 FilterContext = AllocFunction(sizeof(FILTER_CONTEXT));
953 if (FilterContext == NULL)
954 {
955 /* no memory */
956 return STATUS_INSUFFICIENT_RESOURCES;
957 }
958
959 /* init context */
960 FilterContext->DeviceExtension = Device->Context;
961 FilterContext->LowerDevice = Device->NextDeviceObject;
962 Filter->Context = FilterContext;
963
964 DPRINT("USBAudioFilterCreate FilterContext %p LowerDevice %p DeviceExtension %p\n", FilterContext, FilterContext->LowerDevice, FilterContext->DeviceExtension);
965 KsAddItemToObjectBag(Filter->Bag, FilterContext, ExFreePool);
966 return STATUS_SUCCESS;
967 }
968
969
970 VOID
971 NTAPI
972 CountTerminalUnits(
973 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
974 OUT PULONG NonStreamingTerminalDescriptorCount,
975 OUT PULONG TotalTerminalDescriptorCount)
976 {
977 PUSB_INTERFACE_DESCRIPTOR Descriptor;
978 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
979 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
980 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
981 ULONG NonStreamingTerminalCount = 0;
982 ULONG TotalTerminalCount = 0;
983
984 for(Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
985 Descriptor != NULL;
986 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
987 {
988 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
989 {
990 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
991 if (InterfaceHeaderDescriptor != NULL)
992 {
993 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
994 while (CommonDescriptor)
995 {
996 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
997 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
998 {
999 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
1000 {
1001 NonStreamingTerminalCount++;
1002 }
1003 TotalTerminalCount++;
1004 }
1005 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
1006 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
1007 break;
1008 }
1009 }
1010 }
1011 else if (Descriptor->bInterfaceSubClass == 0x03) /* MIDI_STREAMING */
1012 {
1013 UNIMPLEMENTED;
1014 }
1015 }
1016 *NonStreamingTerminalDescriptorCount = NonStreamingTerminalCount;
1017 *TotalTerminalDescriptorCount = TotalTerminalCount;
1018 }
1019
1020 LPGUID
1021 UsbAudioGetPinCategoryFromTerminalDescriptor(
1022 IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor)
1023 {
1024 if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE)
1025 return &NodeTypeMicrophone;
1026 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE)
1027 return &NodeTypeDesktopMicrophone;
1028 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE)
1029 return &NodeTypePersonalMicrophone;
1030 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE)
1031 return &NodeTypeOmmniMicrophone;
1032 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE)
1033 return &NodeTypeArrayMicrophone;
1034 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE)
1035 return &NodeTypeProcessingArrayMicrophone;
1036
1037 /* playback types */
1038 if (TerminalDescriptor->wTerminalType == USB_AUDIO_SPEAKER_TERMINAL_TYPE)
1039 return &NodeTypeSpeaker;
1040 else if (TerminalDescriptor->wTerminalType == USB_HEADPHONES_SPEAKER_TERMINAL_TYPE)
1041 return &NodeTypeHeadphonesSpeaker;
1042 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_HMDA_TERMINAL_TYPE)
1043 return &NodeTypeHMDA;
1044 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE)
1045 return &NodeTypeDesktopSpeaker;
1046 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE)
1047 return &NodeTypeRoomSpeaker;
1048 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE)
1049 return &NodeTypeCommunicationSpeaker;
1050 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_SUBWOOFER_TERMINAL_TYPE)
1051 return &NodeTypeSubwoofer;
1052
1053 if (TerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
1054 {
1055 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
1056 return &NodeTypeCapture;
1057 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
1058 return &NodeTypePlayback;
1059
1060 }
1061 return NULL;
1062 }
1063
1064 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
1065 UsbAudioGetStreamingTerminalDescriptorByIndex(
1066 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
1067 IN ULONG Index)
1068 {
1069 PUSB_INTERFACE_DESCRIPTOR Descriptor;
1070 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
1071 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
1072 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
1073 ULONG TerminalCount = 0;
1074
1075 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1076 Descriptor != NULL;
1077 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1078 {
1079 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
1080 {
1081 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1082 if (InterfaceHeaderDescriptor != NULL)
1083 {
1084 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1085 while (CommonDescriptor)
1086 {
1087 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
1088 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
1089 {
1090 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
1091 {
1092 if (TerminalCount == Index)
1093 {
1094 return InputTerminalDescriptor;
1095 }
1096 TerminalCount++;
1097 }
1098 }
1099 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
1100 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
1101 break;
1102 }
1103 }
1104 }
1105 }
1106 return NULL;
1107 }
1108
1109 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
1110 UsbAudioGetNonStreamingTerminalDescriptorByIndex(
1111 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
1112 IN ULONG Index)
1113 {
1114
1115 PUSB_INTERFACE_DESCRIPTOR Descriptor;
1116 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
1117 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
1118 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
1119 ULONG TerminalCount = 0;
1120
1121 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1122 Descriptor != NULL;
1123 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1124 {
1125 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
1126 {
1127 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1128 if (InterfaceHeaderDescriptor != NULL)
1129 {
1130 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1131 while (CommonDescriptor)
1132 {
1133 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
1134 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
1135 {
1136 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
1137 {
1138 if (TerminalCount == Index)
1139 {
1140 return InputTerminalDescriptor;
1141 }
1142 TerminalCount++;
1143 }
1144 }
1145 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
1146 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
1147 break;
1148 }
1149 }
1150 }
1151 }
1152 return NULL;
1153 }
1154
1155 VOID
1156 UsbAudioGetDataRanges(
1157 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
1158 IN UCHAR bTerminalID,
1159 OUT PKSDATARANGE** OutDataRanges,
1160 OUT PULONG OutDataRangesCount)
1161 {
1162 PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR StreamingInterfaceDescriptor;
1163 PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR StreamingFormatDescriptor;
1164 PUSB_INTERFACE_DESCRIPTOR Descriptor;
1165 PKSDATARANGE_AUDIO DataRangeAudio;
1166 PKSDATARANGE *DataRangeAudioArray;
1167 ULONG NumFrequency, DataRangeCount, DataRangeIndex, Index;
1168
1169 /* count all data ranges */
1170 DataRangeCount = 0;
1171 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1172 Descriptor != NULL;
1173 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1174 {
1175 if (Descriptor->bInterfaceSubClass == 0x02) /* AUDIO_STREAMING */
1176 {
1177 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1178 if (StreamingInterfaceDescriptor != NULL)
1179 {
1180 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01);
1181 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM);
1182 if (StreamingInterfaceDescriptor->bTerminalLink == bTerminalID)
1183 {
1184 DataRangeCount++;
1185 DPRINT1("StreamingInterfaceDescriptor %p TerminalID %x\n", StreamingInterfaceDescriptor, bTerminalID);
1186 }
1187 }
1188 Descriptor = (PUSB_INTERFACE_DESCRIPTOR)StreamingInterfaceDescriptor;
1189 }
1190 }
1191
1192 DataRangeAudioArray = AllocFunction(sizeof(PVOID) * DataRangeCount);
1193 if (DataRangeAudioArray == NULL)
1194 {
1195 /* no memory */
1196 return;
1197 }
1198
1199 DataRangeIndex = 0;
1200 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1201 Descriptor != NULL;
1202 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1203 {
1204 if (Descriptor->bInterfaceSubClass == 0x02) /* AUDIO_STREAMING */
1205 {
1206 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1207 if (StreamingInterfaceDescriptor != NULL)
1208 {
1209 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01);
1210 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM);
1211 if (StreamingInterfaceDescriptor->bTerminalLink == bTerminalID)
1212 {
1213 StreamingFormatDescriptor = (PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR)((ULONG_PTR)StreamingInterfaceDescriptor + StreamingInterfaceDescriptor->bLength);
1214 ASSERT(StreamingFormatDescriptor->bDescriptorType == 0x24);
1215 ASSERT(StreamingFormatDescriptor->bDescriptorSubtype == 0x02);
1216 ASSERT(StreamingFormatDescriptor->bFormatType == 0x01);
1217
1218 DataRangeAudio = AllocFunction(sizeof(KSDATARANGE_AUDIO));
1219 if (DataRangeAudio == NULL)
1220 {
1221 /* no memory*/
1222 return;
1223 }
1224
1225 DataRangeAudio->DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
1226 DataRangeAudio->DataRange.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
1227 DataRangeAudio->DataRange.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
1228 DataRangeAudio->DataRange.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
1229 DataRangeAudio->MaximumChannels = StreamingFormatDescriptor->bNrChannels;
1230 DataRangeAudio->MinimumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
1231 DataRangeAudio->MaximumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
1232 NumFrequency = StreamingFormatDescriptor->bSamFreqType;
1233 DataRangeAudio->MinimumSampleFrequency = MAXULONG;
1234 DataRangeAudio->MaximumSampleFrequency = 0;
1235 for (Index = 0; Index < NumFrequency; Index++)
1236 {
1237 DataRangeAudio->MinimumSampleFrequency = min(StreamingFormatDescriptor->tSamFreq[Index * 3] | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 1] << 8 | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 2] << 16, DataRangeAudio->MinimumSampleFrequency);
1238 DataRangeAudio->MaximumSampleFrequency = max(StreamingFormatDescriptor->tSamFreq[Index * 3] | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 1] << 8 | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 2] << 16, DataRangeAudio->MaximumSampleFrequency);
1239 }
1240 DataRangeAudioArray[DataRangeIndex] = (PKSDATARANGE)DataRangeAudio;
1241 DataRangeIndex++;
1242 }
1243 }
1244 Descriptor = (PUSB_INTERFACE_DESCRIPTOR)StreamingInterfaceDescriptor;
1245 }
1246 }
1247
1248 *OutDataRanges = DataRangeAudioArray;
1249 *OutDataRangesCount = DataRangeCount;
1250 }
1251
1252
1253 NTSTATUS
1254 USBAudioPinBuildDescriptors(
1255 PKSDEVICE Device,
1256 PKSPIN_DESCRIPTOR_EX *PinDescriptors,
1257 PULONG PinDescriptorsCount,
1258 PULONG PinDescriptorSize)
1259 {
1260 PDEVICE_EXTENSION DeviceExtension;
1261 PKSPIN_DESCRIPTOR_EX Pins;
1262 ULONG TotalTerminalDescriptorCount = 0;
1263 ULONG NonStreamingTerminalDescriptorCount = 0;
1264 ULONG Index = 0;
1265 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor = NULL;
1266
1267 /* get device extension */
1268 DeviceExtension = Device->Context;
1269
1270 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount);
1271 DPRINT("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu\n", TotalTerminalDescriptorCount, NonStreamingTerminalDescriptorCount);
1272
1273 /* allocate pins */
1274 Pins = AllocFunction(sizeof(KSPIN_DESCRIPTOR_EX) * TotalTerminalDescriptorCount);
1275 if (!Pins)
1276 {
1277 /* no memory*/
1278 return STATUS_INSUFFICIENT_RESOURCES;
1279 }
1280
1281 for (Index = 0; Index < TotalTerminalDescriptorCount; Index++)
1282 {
1283 if (Index < (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount))
1284 {
1285 /* irp sink pins*/
1286 TerminalDescriptor = UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index);
1287 ASSERT(TerminalDescriptor != NULL);
1288
1289 Pins[Index].Dispatch = &UsbAudioPinDispatch;
1290 Pins[Index].PinDescriptor.InterfacesCount = 1;
1291 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
1292 Pins[Index].PinDescriptor.MediumsCount = 1;
1293 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
1294 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
1295 UsbAudioGetDataRanges(DeviceExtension->ConfigurationDescriptor, TerminalDescriptor->bTerminalID, (PKSDATARANGE**)&Pins[Index].PinDescriptor.DataRanges, &Pins[Index].PinDescriptor.DataRangesCount);
1296
1297 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
1298 {
1299 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BOTH;
1300 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
1301
1302 /* pin flags */
1303 Pins[Index].Flags = KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSFILTER_FLAG_CRITICAL_PROCESSING;
1304 }
1305 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
1306 {
1307 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_SINK;
1308 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
1309
1310 /* pin flags */
1311 Pins[Index].Flags = KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSPIN_FLAG_GENERATE_EOS_EVENTS;
1312 }
1313
1314 /* data intersect handler */
1315 Pins[Index].IntersectHandler = UsbAudioPinDataIntersect;
1316
1317 /* irp sinks / sources can be instantiated */
1318 Pins[Index].InstancesPossible = 1;
1319 }
1320 else
1321 {
1322 /* bridge pins */
1323 TerminalDescriptor = UsbAudioGetNonStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index - (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount));
1324 Pins[Index].PinDescriptor.InterfacesCount = 1;
1325 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
1326 Pins[Index].PinDescriptor.MediumsCount = 1;
1327 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
1328 Pins[Index].PinDescriptor.DataRanges = BridgePinAudioFormats;
1329 Pins[Index].PinDescriptor.DataRangesCount = 1;
1330 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BRIDGE;
1331 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
1332
1333 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
1334 {
1335 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
1336 }
1337 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
1338 {
1339 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
1340 }
1341 }
1342
1343 }
1344
1345 *PinDescriptors = Pins;
1346 *PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR_EX);
1347 *PinDescriptorsCount = TotalTerminalDescriptorCount;
1348
1349 return STATUS_SUCCESS;
1350 }
1351
1352 NTSTATUS
1353 NTAPI
1354 USBAudioGetDescriptor(
1355 IN PDEVICE_OBJECT DeviceObject,
1356 IN UCHAR DescriptorType,
1357 IN ULONG DescriptorLength,
1358 IN UCHAR DescriptorIndex,
1359 IN LANGID LanguageId,
1360 OUT PVOID *OutDescriptor)
1361 {
1362 PURB Urb;
1363 NTSTATUS Status;
1364 PVOID Descriptor;
1365
1366 /* sanity checks */
1367 ASSERT(DeviceObject);
1368 ASSERT(OutDescriptor);
1369 ASSERT(DescriptorLength);
1370
1371 //
1372 // first allocate descriptor buffer
1373 //
1374 Descriptor = AllocFunction(DescriptorLength);
1375 if (!Descriptor)
1376 {
1377 /* no memory */
1378 return STATUS_INSUFFICIENT_RESOURCES;
1379 }
1380
1381 /* allocate urb */
1382 Urb = (PURB)AllocFunction(sizeof(URB));
1383 if (!Urb)
1384 {
1385 /* no memory */
1386 FreeFunction(Descriptor);
1387 return STATUS_INSUFFICIENT_RESOURCES;
1388 }
1389
1390 /* initialize urb */
1391 UsbBuildGetDescriptorRequest(Urb,
1392 sizeof(Urb->UrbControlDescriptorRequest),
1393 DescriptorType,
1394 DescriptorIndex,
1395 LanguageId,
1396 Descriptor,
1397 NULL,
1398 DescriptorLength,
1399 NULL);
1400
1401 /* submit urb */
1402 Status = SubmitUrbSync(DeviceObject, Urb);
1403
1404 /* free urb */
1405 FreeFunction(Urb);
1406
1407 if (NT_SUCCESS(Status))
1408 {
1409 /* store result */
1410 *OutDescriptor = Descriptor;
1411 }
1412 else
1413 {
1414 /* failed */
1415 FreeFunction(Descriptor);
1416 }
1417
1418 /* done */
1419 return Status;
1420 }
1421
1422 NTSTATUS
1423 NTAPI
1424 USBAudioGetStringDescriptor(
1425 IN PDEVICE_OBJECT DeviceObject,
1426 IN ULONG DescriptorLength,
1427 IN UCHAR DescriptorIndex,
1428 IN LANGID LanguageId,
1429 OUT PVOID *OutDescriptor)
1430 {
1431 NTSTATUS Status;
1432
1433 /* retrieve descriptor */
1434 Status = USBAudioGetDescriptor(DeviceObject, USB_STRING_DESCRIPTOR_TYPE, DescriptorLength, DescriptorIndex, LanguageId, OutDescriptor);
1435 if (!NT_SUCCESS(Status))
1436 {
1437 // failed
1438 return Status;
1439 }
1440 return STATUS_SUCCESS;
1441 }
1442
1443 NTSTATUS
1444 USBAudioRegCreateMediaCategoriesKey(
1445 IN PUNICODE_STRING Name,
1446 OUT PHANDLE OutHandle)
1447 {
1448 NTSTATUS Status;
1449 OBJECT_ATTRIBUTES ObjectAttributes;
1450 UNICODE_STRING DestinationString;
1451 HANDLE Handle;
1452
1453 /* initialize root name*/
1454 RtlInitUnicodeString(&DestinationString, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\");
1455
1456 /* initialize object attributes */
1457 InitializeObjectAttributes(&ObjectAttributes, &DestinationString, OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_KERNEL_HANDLE, NULL, NULL);
1458
1459 /* create the key */
1460 Status = ZwOpenKey(&Handle, KEY_ALL_ACCESS, &ObjectAttributes);
1461 if (NT_SUCCESS(Status))
1462 {
1463 /* initialize object attributes */
1464 InitializeObjectAttributes(&ObjectAttributes, Name, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, Handle, NULL);
1465
1466 Status = ZwCreateKey(OutHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, 0, NULL);
1467 ZwClose(Handle);
1468
1469 }
1470 return Status;
1471 }
1472
1473
1474 NTSTATUS
1475 USBAudioInitComponentId(
1476 PKSDEVICE Device,
1477 IN PKSCOMPONENTID ComponentId)
1478 {
1479 PDEVICE_EXTENSION DeviceExtension;
1480 NTSTATUS Status;
1481 LPWSTR DescriptionBuffer;
1482 UNICODE_STRING GuidString;
1483 UNICODE_STRING Name;
1484 HANDLE hKey;
1485 GUID TempGuid;
1486
1487 /* get device extension */
1488 DeviceExtension = Device->Context;
1489
1490 /* init component id */
1491 ComponentId->Component = KSCOMPONENTID_USBAUDIO;
1492 ComponentId->Version = HIBYTE(DeviceExtension->DeviceDescriptor->bcdDevice);
1493 ComponentId->Revision = LOBYTE(DeviceExtension->DeviceDescriptor->bcdDevice);
1494
1495 INIT_USBAUDIO_MID(&ComponentId->Manufacturer, DeviceExtension->DeviceDescriptor->idVendor);
1496 INIT_USBAUDIO_PID(&ComponentId->Product, DeviceExtension->DeviceDescriptor->idProduct);
1497 INIT_USBAUDIO_PRODUCT_NAME(&TempGuid, DeviceExtension->DeviceDescriptor->idVendor, DeviceExtension->DeviceDescriptor->idProduct, 0);
1498
1499 if (DeviceExtension->DeviceDescriptor->iProduct)
1500 {
1501 Status = USBAudioGetStringDescriptor(DeviceExtension->LowerDevice, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iProduct, 0x0409 /* FIXME */, (PVOID*)&DescriptionBuffer);
1502 if (NT_SUCCESS(Status))
1503 {
1504 Status = RtlStringFromGUID(&TempGuid, &GuidString);
1505 if (NT_SUCCESS(Status))
1506 {
1507 Status = USBAudioRegCreateMediaCategoriesKey(&GuidString, &hKey);
1508 if (NT_SUCCESS(Status))
1509 {
1510 RtlInitUnicodeString(&Name, L"Name");
1511 ZwSetValueKey(hKey, &Name, 0, REG_SZ, DescriptionBuffer, (wcslen(DescriptionBuffer) + 1) * sizeof(WCHAR));
1512 ZwClose(hKey);
1513
1514 INIT_USBAUDIO_PRODUCT_NAME(&ComponentId->Name, DeviceExtension->DeviceDescriptor->idVendor, DeviceExtension->DeviceDescriptor->idProduct, 0);
1515 }
1516 RtlFreeUnicodeString(&GuidString);
1517 }
1518 FreeFunction(DescriptionBuffer);
1519 }
1520 }
1521 return STATUS_SUCCESS;
1522 }
1523
1524
1525 NTSTATUS
1526 NTAPI
1527 USBAudioCreateFilterContext(
1528 PKSDEVICE Device)
1529 {
1530 PKSFILTER_DESCRIPTOR FilterDescriptor;
1531 PKSCOMPONENTID ComponentId;
1532 NTSTATUS Status;
1533
1534 /* allocate descriptor */
1535 FilterDescriptor = AllocFunction(sizeof(KSFILTER_DESCRIPTOR));
1536 if (!FilterDescriptor)
1537 {
1538 /* no memory */
1539 return USBD_STATUS_INSUFFICIENT_RESOURCES;
1540 }
1541
1542 /* init filter descriptor*/
1543 FilterDescriptor->Version = KSFILTER_DESCRIPTOR_VERSION;
1544 FilterDescriptor->Flags = 0;
1545 FilterDescriptor->ReferenceGuid = &KSNAME_Filter;
1546 FilterDescriptor->Dispatch = &USBAudioFilterDispatch;
1547 FilterDescriptor->CategoriesCount = 1;
1548 FilterDescriptor->Categories = &GUID_KSCATEGORY_AUDIO;
1549
1550 /* init component id*/
1551 ComponentId = AllocFunction(sizeof(KSCOMPONENTID));
1552 if (!ComponentId)
1553 {
1554 /* no memory */
1555 return STATUS_INSUFFICIENT_RESOURCES;
1556 }
1557 Status = USBAudioInitComponentId(Device, ComponentId);
1558 if (!NT_SUCCESS(Status))
1559 {
1560 /* failed*/
1561 FreeFunction(ComponentId);
1562 return Status;
1563 }
1564 FilterDescriptor->ComponentId = ComponentId;
1565
1566 /* build pin descriptors */
1567 Status = USBAudioPinBuildDescriptors(Device, (PKSPIN_DESCRIPTOR_EX *)&FilterDescriptor->PinDescriptors, &FilterDescriptor->PinDescriptorsCount, &FilterDescriptor->PinDescriptorSize);
1568 if (!NT_SUCCESS(Status))
1569 {
1570 /* failed*/
1571 FreeFunction(ComponentId);
1572 return Status;
1573 }
1574
1575 /* build topology */
1576 Status = BuildUSBAudioFilterTopology(Device, FilterDescriptor);
1577 if (!NT_SUCCESS(Status))
1578 {
1579 /* failed*/
1580 FreeFunction(ComponentId);
1581 return Status;
1582 }
1583
1584 /* lets create the filter */
1585 Status = KsCreateFilterFactory(Device->FunctionalDeviceObject, FilterDescriptor, ReferenceString, NULL, KSCREATE_ITEM_FREEONSTOP, NULL, NULL, NULL);
1586 DPRINT("KsCreateFilterFactory: %x\n", Status);
1587
1588 return Status;
1589 }
1590
1591