93ad7687b947fde6c5bd080b377cf2afd1d11789
[reactos.git] / reactos / 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
94 NTSTATUS
95 BuildUSBAudioFilterTopology(
96 PKSDEVICE Device)
97 {
98 UNIMPLEMENTED
99 return STATUS_NOT_IMPLEMENTED;
100 }
101
102 NTSTATUS
103 NTAPI
104 USBAudioFilterCreate(
105 PKSFILTER Filter,
106 PIRP Irp)
107 {
108 PKSFILTERFACTORY FilterFactory;
109 PKSDEVICE Device;
110 PFILTER_CONTEXT FilterContext;
111
112 FilterFactory = KsGetParent(Filter);
113 if (FilterFactory == NULL)
114 {
115 /* invalid parameter */
116 return STATUS_INVALID_PARAMETER;
117 }
118
119 Device = KsGetParent(FilterFactory);
120 if (Device == NULL)
121 {
122 /* invalid parameter */
123 return STATUS_INVALID_PARAMETER;
124 }
125
126 /* alloc filter context */
127 FilterContext = AllocFunction(sizeof(FILTER_CONTEXT));
128 if (FilterContext == NULL)
129 {
130 /* no memory */
131 return STATUS_INSUFFICIENT_RESOURCES;
132 }
133
134 /* init context */
135 FilterContext->DeviceExtension = Device->Context;
136 FilterContext->LowerDevice = Device->NextDeviceObject;
137 Filter->Context = FilterContext;
138
139 DPRINT("USBAudioFilterCreate FilterContext %p LowerDevice %p DeviceExtension %p\n", FilterContext, FilterContext->LowerDevice, FilterContext->DeviceExtension);
140 KsAddItemToObjectBag(Filter->Bag, FilterContext, ExFreePool);
141 return STATUS_SUCCESS;
142 }
143
144
145 VOID
146 CountTerminalUnits(
147 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
148 OUT PULONG NonStreamingTerminalDescriptorCount,
149 OUT PULONG TotalTerminalDescriptorCount)
150 {
151 PUSB_INTERFACE_DESCRIPTOR Descriptor;
152 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
153 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
154 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
155 ULONG NonStreamingTerminalCount = 0;
156 ULONG TotalTerminalCount = 0;
157
158 for(Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
159 Descriptor != NULL;
160 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
161 {
162 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
163 {
164 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
165 if (InterfaceHeaderDescriptor != NULL)
166 {
167 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
168 while (CommonDescriptor)
169 {
170 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
171 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
172 {
173 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
174 {
175 NonStreamingTerminalCount++;
176 }
177 TotalTerminalCount++;
178 }
179 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
180 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
181 break;
182 }
183 }
184 }
185 else if (Descriptor->bInterfaceSubClass == 0x03) /* MIDI_STREAMING */
186 {
187 UNIMPLEMENTED
188 }
189 }
190 *NonStreamingTerminalDescriptorCount = NonStreamingTerminalCount;
191 *TotalTerminalDescriptorCount = TotalTerminalCount;
192 }
193
194 LPGUID
195 UsbAudioGetPinCategoryFromTerminalDescriptor(
196 IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor)
197 {
198 if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE)
199 return &NodeTypeMicrophone;
200 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE)
201 return &NodeTypeDesktopMicrophone;
202 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE)
203 return &NodeTypePersonalMicrophone;
204 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE)
205 return &NodeTypeOmmniMicrophone;
206 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE)
207 return &NodeTypeArrayMicrophone;
208 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE)
209 return &NodeTypeProcessingArrayMicrophone;
210
211 /* playback types */
212 if (TerminalDescriptor->wTerminalType == USB_AUDIO_SPEAKER_TERMINAL_TYPE)
213 return &NodeTypeSpeaker;
214 else if (TerminalDescriptor->wTerminalType == USB_HEADPHONES_SPEAKER_TERMINAL_TYPE)
215 return &NodeTypeHeadphonesSpeaker;
216 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_HMDA_TERMINAL_TYPE)
217 return &NodeTypeHMDA;
218 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE)
219 return &NodeTypeDesktopSpeaker;
220 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE)
221 return &NodeTypeRoomSpeaker;
222 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE)
223 return &NodeTypeCommunicationSpeaker;
224 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_SUBWOOFER_TERMINAL_TYPE)
225 return &NodeTypeSubwoofer;
226
227 if (TerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
228 {
229 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
230 return &NodeTypeCapture;
231 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
232 return &NodeTypePlayback;
233
234 }
235 return NULL;
236 }
237
238 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
239 UsbAudioGetStreamingTerminalDescriptorByIndex(
240 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
241 IN ULONG Index)
242 {
243 PUSB_INTERFACE_DESCRIPTOR Descriptor;
244 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
245 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
246 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
247 ULONG TerminalCount = 0;
248
249 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
250 Descriptor != NULL;
251 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
252 {
253 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
254 {
255 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
256 if (InterfaceHeaderDescriptor != NULL)
257 {
258 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
259 while (CommonDescriptor)
260 {
261 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
262 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
263 {
264 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
265 {
266 if (TerminalCount == Index)
267 {
268 return InputTerminalDescriptor;
269 }
270 TerminalCount++;
271 }
272 }
273 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
274 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
275 break;
276 }
277 }
278 }
279 }
280 return NULL;
281 }
282
283 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
284 UsbAudioGetNonStreamingTerminalDescriptorByIndex(
285 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
286 IN ULONG Index)
287 {
288
289 PUSB_INTERFACE_DESCRIPTOR Descriptor;
290 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
291 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
292 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
293 ULONG TerminalCount = 0;
294
295 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
296 Descriptor != NULL;
297 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
298 {
299 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
300 {
301 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
302 if (InterfaceHeaderDescriptor != NULL)
303 {
304 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
305 while (CommonDescriptor)
306 {
307 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
308 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
309 {
310 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
311 {
312 if (TerminalCount == Index)
313 {
314 return InputTerminalDescriptor;
315 }
316 TerminalCount++;
317 }
318 }
319 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
320 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
321 break;
322 }
323 }
324 }
325 }
326 return NULL;
327 }
328
329 VOID
330 UsbAudioGetDataRanges(
331 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
332 IN UCHAR bTerminalID,
333 OUT PKSDATARANGE** OutDataRanges,
334 OUT PULONG OutDataRangesCount)
335 {
336 PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR StreamingInterfaceDescriptor;
337 PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR StreamingFormatDescriptor;
338 PUSB_INTERFACE_DESCRIPTOR Descriptor;
339 PKSDATARANGE_AUDIO DataRangeAudio;
340 PKSDATARANGE *DataRangeAudioArray;
341 ULONG NumFrequency;
342
343 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
344 Descriptor != NULL;
345 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
346 {
347 if (Descriptor->bInterfaceSubClass == 0x02) /* AUDIO_STREAMING */
348 {
349 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
350 if (StreamingInterfaceDescriptor != NULL)
351 {
352 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01);
353 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM);
354 if (StreamingInterfaceDescriptor->bTerminalLink == bTerminalID)
355 {
356 StreamingFormatDescriptor = (PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR)((ULONG_PTR)StreamingInterfaceDescriptor + StreamingInterfaceDescriptor->bLength);
357 ASSERT(StreamingFormatDescriptor->bDescriptorType == 0x24);
358 ASSERT(StreamingFormatDescriptor->bDescriptorSubtype == 0x02);
359 ASSERT(StreamingFormatDescriptor->bFormatType == 0x01);
360
361 DataRangeAudio = AllocFunction(sizeof(KSDATARANGE_AUDIO));
362 if (DataRangeAudio == NULL)
363 {
364 /* no memory*/
365 return;
366 }
367
368 DataRangeAudio->DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
369 DataRangeAudio->DataRange.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
370 DataRangeAudio->DataRange.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
371 DataRangeAudio->DataRange.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
372 DataRangeAudio->MaximumChannels = 1;
373 DataRangeAudio->MinimumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
374 DataRangeAudio->MaximumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
375 NumFrequency = StreamingFormatDescriptor->bSamFreqType - 1;
376 DataRangeAudio->MinimumSampleFrequency = StreamingFormatDescriptor->tSamFreq[0] | StreamingFormatDescriptor->tSamFreq[1] << 8 | StreamingFormatDescriptor->tSamFreq[2] << 16;
377 DataRangeAudio->MaximumSampleFrequency = StreamingFormatDescriptor->tSamFreq[NumFrequency*3] | StreamingFormatDescriptor->tSamFreq[NumFrequency * 3+1] << 8 | StreamingFormatDescriptor->tSamFreq[NumFrequency * 3+2]<<16;
378 DataRangeAudioArray = AllocFunction(sizeof(PKSDATARANGE_AUDIO));
379 if (DataRangeAudioArray == NULL)
380 {
381 /* no memory */
382 FreeFunction(DataRangeAudio);
383 return;
384 }
385 DataRangeAudioArray[0] = (PKSDATARANGE)DataRangeAudio;
386 *OutDataRanges = DataRangeAudioArray;
387 *OutDataRangesCount = 1;
388 return;
389 }
390 }
391 }
392 }
393 }
394
395
396 NTSTATUS
397 USBAudioPinBuildDescriptors(
398 PKSDEVICE Device,
399 PKSPIN_DESCRIPTOR_EX *PinDescriptors,
400 PULONG PinDescriptorsCount,
401 PULONG PinDescriptorSize)
402 {
403 PDEVICE_EXTENSION DeviceExtension;
404 PKSPIN_DESCRIPTOR_EX Pins;
405 ULONG TotalTerminalDescriptorCount = 0;
406 ULONG NonStreamingTerminalDescriptorCount = 0;
407 ULONG Index = 0;
408 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor = NULL;
409
410 /* get device extension */
411 DeviceExtension = Device->Context;
412
413 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount);
414 DPRINT1("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu", TotalTerminalDescriptorCount, NonStreamingTerminalDescriptorCount);
415
416 /* allocate pins */
417 Pins = AllocFunction(sizeof(KSPIN_DESCRIPTOR_EX) * TotalTerminalDescriptorCount);
418 if (!Pins)
419 {
420 /* no memory*/
421 return STATUS_INSUFFICIENT_RESOURCES;
422 }
423
424 for (Index = 0; Index < TotalTerminalDescriptorCount; Index++)
425 {
426 if (Index < (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount))
427 {
428 /* irp sink pins*/
429 TerminalDescriptor = UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index);
430 ASSERT(TerminalDescriptor != NULL);
431
432 Pins[Index].Dispatch = &UsbAudioPinDispatch;
433 Pins[Index].PinDescriptor.InterfacesCount = 1;
434 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
435 Pins[Index].PinDescriptor.MediumsCount = 1;
436 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
437 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
438 UsbAudioGetDataRanges(DeviceExtension->ConfigurationDescriptor, TerminalDescriptor->bTerminalID, (PKSDATARANGE**)&Pins[Index].PinDescriptor.DataRanges, &Pins[Index].PinDescriptor.DataRangesCount);
439
440 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
441 {
442 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BOTH;
443 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
444 }
445 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
446 {
447 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_SINK;
448 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
449 }
450
451
452 Pins[Index].Flags = KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSFILTER_FLAG_CRITICAL_PROCESSING;
453
454 /* irp sinks / sources can be instantiated */
455 Pins[Index].InstancesPossible = 1;
456 Pins[Index].InstancesNecessary = 1;
457 }
458 else
459 {
460 /* bridge pins */
461 TerminalDescriptor = UsbAudioGetNonStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index - (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount));
462 Pins[Index].PinDescriptor.InterfacesCount = 1;
463 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
464 Pins[Index].PinDescriptor.MediumsCount = 1;
465 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
466 Pins[Index].PinDescriptor.DataRanges = BridgePinAudioFormats;
467 Pins[Index].PinDescriptor.DataRangesCount = 1;
468 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BRIDGE;
469 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
470
471 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
472 {
473 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
474 }
475 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
476 {
477 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
478 }
479 }
480
481 }
482
483 *PinDescriptors = Pins;
484 *PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR_EX);
485 *PinDescriptorsCount = TotalTerminalDescriptorCount;
486
487 return STATUS_SUCCESS;
488 }
489
490 NTSTATUS
491 USBAudioInitComponentId(
492 PKSDEVICE Device,
493 IN PKSCOMPONENTID ComponentId)
494 {
495 PDEVICE_EXTENSION DeviceExtension;
496
497 /* get device extension */
498 DeviceExtension = Device->Context;
499
500 INIT_USBAUDIO_MID(&ComponentId->Manufacturer, DeviceExtension->DeviceDescriptor->idVendor);
501 INIT_USBAUDIO_PID(&ComponentId->Product, DeviceExtension->DeviceDescriptor->idProduct);
502
503 //ComponentId->Component = KSCOMPONENTID_USBAUDIO;
504 UNIMPLEMENTED
505 return STATUS_NOT_IMPLEMENTED;
506 }
507
508
509 NTSTATUS
510 NTAPI
511 USBAudioCreateFilterContext(
512 PKSDEVICE Device)
513 {
514 PKSFILTER_DESCRIPTOR FilterDescriptor;
515 PKSCOMPONENTID ComponentId;
516 NTSTATUS Status;
517
518 /* allocate descriptor */
519 FilterDescriptor = AllocFunction(sizeof(KSFILTER_DESCRIPTOR));
520 if (!FilterDescriptor)
521 {
522 /* no memory */
523 return USBD_STATUS_INSUFFICIENT_RESOURCES;
524 }
525
526 /* init filter descriptor*/
527 FilterDescriptor->Version = KSFILTER_DESCRIPTOR_VERSION;
528 FilterDescriptor->Flags = 0;
529 FilterDescriptor->ReferenceGuid = &KSNAME_Filter;
530 FilterDescriptor->Dispatch = &USBAudioFilterDispatch;
531 FilterDescriptor->CategoriesCount = 1;
532 FilterDescriptor->Categories = &GUID_KSCATEGORY_AUDIO;
533
534 /* init component id*/
535 ComponentId = AllocFunction(sizeof(KSCOMPONENTID));
536 if (!ComponentId)
537 {
538 /* no memory */
539 return STATUS_INSUFFICIENT_RESOURCES;
540 }
541 Status = USBAudioInitComponentId(Device, ComponentId);
542 if (!NT_SUCCESS(Status))
543 {
544 /* failed*/
545 //FreeFunction(ComponentId);
546 //return Status;
547 }
548 FilterDescriptor->ComponentId = ComponentId;
549
550 /* build pin descriptors */
551 Status = USBAudioPinBuildDescriptors(Device, (PKSPIN_DESCRIPTOR_EX *)&FilterDescriptor->PinDescriptors, &FilterDescriptor->PinDescriptorsCount, &FilterDescriptor->PinDescriptorSize);
552 if (!NT_SUCCESS(Status))
553 {
554 /* failed*/
555 FreeFunction(ComponentId);
556 return Status;
557 }
558
559 /* build topology */
560 Status = BuildUSBAudioFilterTopology(Device);
561 if (!NT_SUCCESS(Status))
562 {
563 /* failed*/
564 //FreeFunction(ComponentId);
565 //return Status;
566 }
567
568 /* lets create the filter */
569 Status = KsCreateFilterFactory(Device->FunctionalDeviceObject, FilterDescriptor, ReferenceString, NULL, KSCREATE_ITEM_FREEONSTOP, NULL, NULL, NULL);
570 DPRINT1("KsCreateFilterFactory: %x\n", Status);
571
572 return Status;
573 }
574
575