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