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