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