[USBAUDIO]
[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 GUID GUID_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
29 GUID GUID_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
30 GUID GUID_KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SPECIFIER_WAVEFORMATEX };
31 KSPIN_INTERFACE StandardPinInterface =
32 {
33 {STATIC_KSINTERFACESETID_Standard},
34 KSINTERFACE_STANDARD_STREAMING,
35 0
36 };
37
38 KSPIN_MEDIUM StandardPinMedium =
39 {
40 {STATIC_KSMEDIUMSETID_Standard},
41 KSMEDIUM_TYPE_ANYINSTANCE,
42 0
43 };
44
45 KSDATARANGE BridgePinAudioFormat[] =
46 {
47 {
48 {
49 sizeof(KSDATAFORMAT),
50 0,
51 0,
52 0,
53 {STATIC_KSDATAFORMAT_TYPE_AUDIO},
54 {STATIC_KSDATAFORMAT_SUBTYPE_ANALOG},
55 {STATIC_KSDATAFORMAT_SPECIFIER_NONE}
56 }
57 }
58 };
59
60 static PKSDATARANGE BridgePinAudioFormats[] =
61 {
62 &BridgePinAudioFormat[0]
63 };
64
65 static LPWSTR ReferenceString = L"global";
66
67 NTSTATUS
68 NTAPI
69 USBAudioFilterCreate(
70 PKSFILTER Filter,
71 PIRP Irp);
72
73 static KSFILTER_DISPATCH USBAudioFilterDispatch =
74 {
75 USBAudioFilterCreate,
76 NULL,
77 NULL,
78 NULL
79 };
80
81 NTSTATUS
82 BuildUSBAudioFilterTopology(
83 PKSDEVICE Device)
84 {
85 UNIMPLEMENTED
86 return STATUS_NOT_IMPLEMENTED;
87 }
88
89 NTSTATUS
90 NTAPI
91 USBAudioFilterCreate(
92 PKSFILTER Filter,
93 PIRP Irp)
94 {
95 UNIMPLEMENTED
96 return STATUS_SUCCESS;
97 }
98
99
100 VOID
101 CountTerminalUnits(
102 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
103 OUT PULONG NonStreamingTerminalDescriptorCount,
104 OUT PULONG TotalTerminalDescriptorCount)
105 {
106 PUSB_INTERFACE_DESCRIPTOR Descriptor;
107 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
108 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
109 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
110 ULONG NonStreamingTerminalCount = 0;
111 ULONG TotalTerminalCount = 0;
112
113 for(Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
114 Descriptor != NULL;
115 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
116 {
117 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
118 {
119 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
120 if (InterfaceHeaderDescriptor != NULL)
121 {
122 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
123 while (CommonDescriptor)
124 {
125 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
126 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
127 {
128 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
129 {
130 NonStreamingTerminalCount++;
131 }
132 TotalTerminalCount++;
133 }
134 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
135 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
136 break;
137 }
138 }
139 }
140 else if (Descriptor->bInterfaceSubClass == 0x03) /* MIDI_STREAMING */
141 {
142 UNIMPLEMENTED
143 }
144 }
145 *NonStreamingTerminalDescriptorCount = NonStreamingTerminalCount;
146 *TotalTerminalDescriptorCount = TotalTerminalCount;
147 }
148
149 LPGUID
150 UsbAudioGetPinCategoryFromTerminalDescriptor(
151 IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor)
152 {
153 if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE)
154 return &NodeTypeMicrophone;
155 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE)
156 return &NodeTypeDesktopMicrophone;
157 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE)
158 return &NodeTypePersonalMicrophone;
159 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE)
160 return &NodeTypeOmmniMicrophone;
161 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE)
162 return &NodeTypeArrayMicrophone;
163 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE)
164 return &NodeTypeProcessingArrayMicrophone;
165
166 /* playback types */
167 if (TerminalDescriptor->wTerminalType == USB_AUDIO_SPEAKER_TERMINAL_TYPE)
168 return &NodeTypeSpeaker;
169 else if (TerminalDescriptor->wTerminalType == USB_HEADPHONES_SPEAKER_TERMINAL_TYPE)
170 return &NodeTypeHeadphonesSpeaker;
171 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_HMDA_TERMINAL_TYPE)
172 return &NodeTypeHMDA;
173 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE)
174 return &NodeTypeDesktopSpeaker;
175 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE)
176 return &NodeTypeRoomSpeaker;
177 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE)
178 return &NodeTypeCommunicationSpeaker;
179 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_SUBWOOFER_TERMINAL_TYPE)
180 return &NodeTypeSubwoofer;
181
182 if (TerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
183 {
184 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
185 return &NodeTypeCapture;
186 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
187 return &NodeTypePlayback;
188
189 }
190 return NULL;
191 }
192
193 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
194 UsbAudioGetStreamingTerminalDescriptorByIndex(
195 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
196 IN ULONG Index)
197 {
198 PUSB_INTERFACE_DESCRIPTOR Descriptor;
199 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
200 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
201 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
202 ULONG TerminalCount = 0;
203
204 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
205 Descriptor != NULL;
206 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
207 {
208 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
209 {
210 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
211 if (InterfaceHeaderDescriptor != NULL)
212 {
213 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
214 while (CommonDescriptor)
215 {
216 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
217 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
218 {
219 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
220 {
221 if (TerminalCount == Index)
222 {
223 return InputTerminalDescriptor;
224 }
225 TerminalCount++;
226 }
227 }
228 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
229 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
230 break;
231 }
232 }
233 }
234 }
235 return NULL;
236 }
237
238 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
239 UsbAudioGetNonStreamingTerminalDescriptorByIndex(
240 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
241 IN ULONG Index)
242 {
243
244 PUSB_INTERFACE_DESCRIPTOR Descriptor;
245 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
246 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
247 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
248 ULONG TerminalCount = 0;
249
250 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
251 Descriptor != NULL;
252 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
253 {
254 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
255 {
256 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
257 if (InterfaceHeaderDescriptor != NULL)
258 {
259 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
260 while (CommonDescriptor)
261 {
262 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
263 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
264 {
265 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
266 {
267 if (TerminalCount == Index)
268 {
269 return InputTerminalDescriptor;
270 }
271 TerminalCount++;
272 }
273 }
274 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
275 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
276 break;
277 }
278 }
279 }
280 }
281 return NULL;
282 }
283
284 VOID
285 UsbAudioGetDataRanges(
286 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
287 IN UCHAR bTerminalID,
288 OUT PKSDATARANGE** OutDataRanges,
289 OUT PULONG OutDataRangesCount)
290 {
291 PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR StreamingInterfaceDescriptor;
292 PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR StreamingFormatDescriptor;
293 PUSB_INTERFACE_DESCRIPTOR Descriptor;
294 PKSDATARANGE_AUDIO DataRangeAudio;
295 PKSDATARANGE *DataRangeAudioArray;
296 ULONG NumFrequency;
297
298 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
299 Descriptor != NULL;
300 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
301 {
302 if (Descriptor->bInterfaceSubClass == 0x02) /* AUDIO_STREAMING */
303 {
304 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
305 if (StreamingInterfaceDescriptor != NULL)
306 {
307 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01);
308 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM);
309 if (StreamingInterfaceDescriptor->bTerminalLink == bTerminalID)
310 {
311 StreamingFormatDescriptor = (PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR)((ULONG_PTR)StreamingInterfaceDescriptor + StreamingInterfaceDescriptor->bLength);
312 ASSERT(StreamingFormatDescriptor->bDescriptorType == 0x24);
313 ASSERT(StreamingFormatDescriptor->bDescriptorSubtype == 0x02);
314 ASSERT(StreamingFormatDescriptor->bFormatType == 0x01);
315
316 DataRangeAudio = AllocFunction(sizeof(KSDATARANGE_AUDIO));
317 if (DataRangeAudio == NULL)
318 {
319 /* no memory*/
320 return;
321 }
322
323 DataRangeAudio->DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
324 DataRangeAudio->DataRange.MajorFormat = GUID_KSDATAFORMAT_TYPE_AUDIO;
325 DataRangeAudio->DataRange.SubFormat = GUID_KSDATAFORMAT_SUBTYPE_PCM;
326 DataRangeAudio->DataRange.Specifier = GUID_KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
327 DataRangeAudio->MaximumChannels = 1;
328 DataRangeAudio->MinimumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
329 DataRangeAudio->MaximumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
330 NumFrequency = StreamingFormatDescriptor->bSamFreqType - 1;
331 DataRangeAudio->MinimumSampleFrequency = StreamingFormatDescriptor->tSamFreq[0] | StreamingFormatDescriptor->tSamFreq[1] << 8 | StreamingFormatDescriptor->tSamFreq[2] << 16;
332 DataRangeAudio->MaximumSampleFrequency = StreamingFormatDescriptor->tSamFreq[NumFrequency*3] | StreamingFormatDescriptor->tSamFreq[NumFrequency * 3+1] << 8 | StreamingFormatDescriptor->tSamFreq[NumFrequency * 3+2]<<16;
333 DataRangeAudioArray = AllocFunction(sizeof(PKSDATARANGE_AUDIO));
334 if (DataRangeAudioArray == NULL)
335 {
336 /* no memory */
337 FreeFunction(DataRangeAudio);
338 return;
339 }
340 DataRangeAudioArray[0] = (PKSDATARANGE)DataRangeAudio;
341 *OutDataRanges = DataRangeAudioArray;
342 *OutDataRangesCount = 1;
343 return;
344 }
345 }
346 }
347 }
348 }
349
350
351 NTSTATUS
352 USBAudioPinBuildDescriptors(
353 PKSDEVICE Device,
354 PKSPIN_DESCRIPTOR_EX *PinDescriptors,
355 PULONG PinDescriptorsCount,
356 PULONG PinDescriptorSize)
357 {
358 PDEVICE_EXTENSION DeviceExtension;
359 PKSPIN_DESCRIPTOR_EX Pins;
360 ULONG TotalTerminalDescriptorCount = 0;
361 ULONG NonStreamingTerminalDescriptorCount = 0;
362 ULONG Index = 0;
363 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor = NULL;
364
365 /* get device extension */
366 DeviceExtension = Device->Context;
367
368 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount);
369 DPRINT1("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu", TotalTerminalDescriptorCount, NonStreamingTerminalDescriptorCount);
370
371 /* allocate pins */
372 Pins = AllocFunction(sizeof(KSPIN_DESCRIPTOR_EX) * TotalTerminalDescriptorCount);
373 if (!Pins)
374 {
375 /* no memory*/
376 return STATUS_INSUFFICIENT_RESOURCES;
377 }
378
379 for (Index = 0; Index < TotalTerminalDescriptorCount; Index++)
380 {
381 if (Index < (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount))
382 {
383 /* irp sink pins*/
384 TerminalDescriptor = UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index);
385 Pins[Index].PinDescriptor.InterfacesCount = 1;
386 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
387 Pins[Index].PinDescriptor.MediumsCount = 1;
388 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
389 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
390 UsbAudioGetDataRanges(DeviceExtension->ConfigurationDescriptor, TerminalDescriptor->bTerminalID, (PKSDATARANGE**)&Pins[Index].PinDescriptor.DataRanges, &Pins[Index].PinDescriptor.DataRangesCount);
391
392 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
393 {
394 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BOTH;
395 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
396 }
397 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
398 {
399 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_SINK;
400 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
401 }
402
403 /* irp sinks / sources can be instantiated */
404 Pins[Index].InstancesPossible = 1;
405 }
406 else
407 {
408 /* bridge pins */
409 TerminalDescriptor = UsbAudioGetNonStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index - (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount));
410 Pins[Index].PinDescriptor.InterfacesCount = 1;
411 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
412 Pins[Index].PinDescriptor.MediumsCount = 1;
413 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
414 Pins[Index].PinDescriptor.DataRanges = BridgePinAudioFormats;
415 Pins[Index].PinDescriptor.DataRangesCount = 1;
416 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BRIDGE;
417 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
418
419 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
420 {
421 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
422 }
423 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
424 {
425 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
426 }
427 }
428
429 }
430
431 *PinDescriptors = Pins;
432 *PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR_EX);
433 *PinDescriptorsCount = TotalTerminalDescriptorCount;
434
435 return STATUS_SUCCESS;
436 }
437
438 NTSTATUS
439 USBAudioInitComponentId(
440 PKSDEVICE Device,
441 IN PKSCOMPONENTID ComponentId)
442 {
443 PDEVICE_EXTENSION DeviceExtension;
444
445 /* get device extension */
446 DeviceExtension = Device->Context;
447
448 INIT_USBAUDIO_MID(&ComponentId->Manufacturer, DeviceExtension->DeviceDescriptor->idVendor);
449 INIT_USBAUDIO_PID(&ComponentId->Product, DeviceExtension->DeviceDescriptor->idProduct);
450
451 //ComponentId->Component = KSCOMPONENTID_USBAUDIO;
452 UNIMPLEMENTED
453 return STATUS_NOT_IMPLEMENTED;
454 }
455
456
457 NTSTATUS
458 NTAPI
459 USBAudioCreateFilterContext(
460 PKSDEVICE Device)
461 {
462 KSFILTER_DESCRIPTOR FilterDescriptor;
463 PKSCOMPONENTID ComponentId;
464 NTSTATUS Status;
465
466 /* clear filter descriptor */
467 RtlZeroMemory(&FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
468
469 /* init filter descriptor*/
470 FilterDescriptor.Version = KSFILTER_DESCRIPTOR_VERSION;
471 FilterDescriptor.Flags = 0;
472 FilterDescriptor.ReferenceGuid = &KSNAME_Filter;
473 FilterDescriptor.Dispatch = &USBAudioFilterDispatch;
474 FilterDescriptor.CategoriesCount = 1;
475 FilterDescriptor.Categories = &GUID_KSCATEGORY_AUDIO;
476
477 /* init component id*/
478 ComponentId = AllocFunction(sizeof(KSCOMPONENTID));
479 if (!ComponentId)
480 {
481 /* no memory */
482 return STATUS_INSUFFICIENT_RESOURCES;
483 }
484 Status = USBAudioInitComponentId(Device, ComponentId);
485 if (!NT_SUCCESS(Status))
486 {
487 /* failed*/
488 //FreeFunction(ComponentId);
489 //return Status;
490 }
491 FilterDescriptor.ComponentId = ComponentId;
492
493 /* build pin descriptors */
494 Status = USBAudioPinBuildDescriptors(Device, (PKSPIN_DESCRIPTOR_EX *)&FilterDescriptor.PinDescriptors, &FilterDescriptor.PinDescriptorsCount, &FilterDescriptor.PinDescriptorSize);
495 if (!NT_SUCCESS(Status))
496 {
497 /* failed*/
498 FreeFunction(ComponentId);
499 return Status;
500 }
501
502 DbgBreakPoint();
503 /* build topology */
504 Status = BuildUSBAudioFilterTopology(Device);
505 if (!NT_SUCCESS(Status))
506 {
507 /* failed*/
508 //FreeFunction(ComponentId);
509 //return Status;
510 }
511
512 /* lets create the filter */
513 Status = KsCreateFilterFactory(Device->FunctionalDeviceObject, &FilterDescriptor, ReferenceString, NULL, KSCREATE_ITEM_FREEONSTOP, NULL, NULL, NULL);
514 DPRINT1("KsCreateFilterFactory: %x\n", Status);
515
516 return Status;
517 }
518
519