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.
7 * Johannes Anderwald (johannes.anderwald@reactos.org)
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
};
29 KSPIN_INTERFACE StandardPinInterface
=
31 {STATIC_KSINTERFACESETID_Standard
},
32 KSINTERFACE_STANDARD_STREAMING
,
36 KSPIN_MEDIUM StandardPinMedium
=
38 {STATIC_KSMEDIUMSETID_Standard
},
39 KSMEDIUM_TYPE_ANYINSTANCE
,
43 KSDATARANGE BridgePinAudioFormat
[] =
51 {STATIC_KSDATAFORMAT_TYPE_AUDIO
},
52 {STATIC_KSDATAFORMAT_SUBTYPE_ANALOG
},
53 {STATIC_KSDATAFORMAT_SPECIFIER_NONE
}
58 static PKSDATARANGE BridgePinAudioFormats
[] =
60 &BridgePinAudioFormat
[0]
63 static LPWSTR ReferenceString
= L
"global";
71 static KSFILTER_DISPATCH USBAudioFilterDispatch
=
79 static KSPIN_DISPATCH UsbAudioPinDispatch
=
85 USBAudioPinSetDataFormat
,
86 USBAudioPinSetDeviceState
,
95 BuildUSBAudioFilterTopology(
99 return STATUS_NOT_IMPLEMENTED
;
104 USBAudioFilterCreate(
108 PKSFILTERFACTORY FilterFactory
;
110 PFILTER_CONTEXT FilterContext
;
112 FilterFactory
= KsGetParent(Filter
);
113 if (FilterFactory
== NULL
)
115 /* invalid parameter */
116 return STATUS_INVALID_PARAMETER
;
119 Device
= KsGetParent(FilterFactory
);
122 /* invalid parameter */
123 return STATUS_INVALID_PARAMETER
;
126 /* alloc filter context */
127 FilterContext
= AllocFunction(sizeof(FILTER_CONTEXT
));
128 if (FilterContext
== NULL
)
131 return STATUS_INSUFFICIENT_RESOURCES
;
135 FilterContext
->DeviceExtension
= Device
->Context
;
136 FilterContext
->LowerDevice
= Device
->NextDeviceObject
;
137 Filter
->Context
= FilterContext
;
139 KsAddItemToObjectBag(Filter
->Bag
, FilterContext
, ExFreePool
);
140 return STATUS_SUCCESS
;
146 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
147 OUT PULONG NonStreamingTerminalDescriptorCount
,
148 OUT PULONG TotalTerminalDescriptorCount
)
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;
157 for(Descriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, ConfigurationDescriptor
, -1, -1, USB_DEVICE_CLASS_AUDIO
, -1, -1);
159 Descriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, (PVOID
)((ULONG_PTR
)Descriptor
+ Descriptor
->bLength
), -1, -1, USB_DEVICE_CLASS_AUDIO
, -1, -1))
161 if (Descriptor
->bInterfaceSubClass
== 0x01) /* AUDIO_CONTROL */
163 InterfaceHeaderDescriptor
= (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR
)USBD_ParseDescriptors(ConfigurationDescriptor
, ConfigurationDescriptor
->wTotalLength
, Descriptor
, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
);
164 if (InterfaceHeaderDescriptor
!= NULL
)
166 CommonDescriptor
= USBD_ParseDescriptors(InterfaceHeaderDescriptor
, InterfaceHeaderDescriptor
->wTotalLength
, (PVOID
)((ULONG_PTR
)InterfaceHeaderDescriptor
+ InterfaceHeaderDescriptor
->bLength
), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
);
167 while (CommonDescriptor
)
169 InputTerminalDescriptor
= (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
)CommonDescriptor
;
170 if (InputTerminalDescriptor
->bDescriptorSubtype
== 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor
->bDescriptorSubtype
== 0x03 /* OUTPUT_TERMINAL*/)
172 if (InputTerminalDescriptor
->wTerminalType
!= USB_AUDIO_STREAMING_TERMINAL_TYPE
)
174 NonStreamingTerminalCount
++;
176 TotalTerminalCount
++;
178 CommonDescriptor
= (PUSB_COMMON_DESCRIPTOR
)((ULONG_PTR
)CommonDescriptor
+ CommonDescriptor
->bLength
);
179 if ((ULONG_PTR
)CommonDescriptor
>= ((ULONG_PTR
)InterfaceHeaderDescriptor
+ InterfaceHeaderDescriptor
->wTotalLength
))
184 else if (Descriptor
->bInterfaceSubClass
== 0x03) /* MIDI_STREAMING */
189 *NonStreamingTerminalDescriptorCount
= NonStreamingTerminalCount
;
190 *TotalTerminalDescriptorCount
= TotalTerminalCount
;
194 UsbAudioGetPinCategoryFromTerminalDescriptor(
195 IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor
)
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
;
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
;
226 if (TerminalDescriptor
->wTerminalType
== USB_AUDIO_STREAMING_TERMINAL_TYPE
)
228 if (TerminalDescriptor
->bDescriptorSubtype
== USB_AUDIO_OUTPUT_TERMINAL
)
229 return &NodeTypeCapture
;
230 else if (TerminalDescriptor
->bDescriptorSubtype
== USB_AUDIO_INPUT_TERMINAL
)
231 return &NodeTypePlayback
;
237 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
238 UsbAudioGetStreamingTerminalDescriptorByIndex(
239 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
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;
248 for (Descriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, ConfigurationDescriptor
, -1, -1, USB_DEVICE_CLASS_AUDIO
, -1, -1);
250 Descriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, (PVOID
)((ULONG_PTR
)Descriptor
+ Descriptor
->bLength
), -1, -1, USB_DEVICE_CLASS_AUDIO
, -1, -1))
252 if (Descriptor
->bInterfaceSubClass
== 0x01) /* AUDIO_CONTROL */
254 InterfaceHeaderDescriptor
= (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR
)USBD_ParseDescriptors(ConfigurationDescriptor
, ConfigurationDescriptor
->wTotalLength
, Descriptor
, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
);
255 if (InterfaceHeaderDescriptor
!= NULL
)
257 CommonDescriptor
= USBD_ParseDescriptors(InterfaceHeaderDescriptor
, InterfaceHeaderDescriptor
->wTotalLength
, (PVOID
)((ULONG_PTR
)InterfaceHeaderDescriptor
+ InterfaceHeaderDescriptor
->bLength
), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
);
258 while (CommonDescriptor
)
260 InputTerminalDescriptor
= (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
)CommonDescriptor
;
261 if (InputTerminalDescriptor
->bDescriptorSubtype
== 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor
->bDescriptorSubtype
== 0x03 /* OUTPUT_TERMINAL*/)
263 if (InputTerminalDescriptor
->wTerminalType
== USB_AUDIO_STREAMING_TERMINAL_TYPE
)
265 if (TerminalCount
== Index
)
267 return InputTerminalDescriptor
;
272 CommonDescriptor
= (PUSB_COMMON_DESCRIPTOR
)((ULONG_PTR
)CommonDescriptor
+ CommonDescriptor
->bLength
);
273 if ((ULONG_PTR
)CommonDescriptor
>= ((ULONG_PTR
)InterfaceHeaderDescriptor
+ InterfaceHeaderDescriptor
->wTotalLength
))
282 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
283 UsbAudioGetNonStreamingTerminalDescriptorByIndex(
284 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
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;
294 for (Descriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, ConfigurationDescriptor
, -1, -1, USB_DEVICE_CLASS_AUDIO
, -1, -1);
296 Descriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, (PVOID
)((ULONG_PTR
)Descriptor
+ Descriptor
->bLength
), -1, -1, USB_DEVICE_CLASS_AUDIO
, -1, -1))
298 if (Descriptor
->bInterfaceSubClass
== 0x01) /* AUDIO_CONTROL */
300 InterfaceHeaderDescriptor
= (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR
)USBD_ParseDescriptors(ConfigurationDescriptor
, ConfigurationDescriptor
->wTotalLength
, Descriptor
, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
);
301 if (InterfaceHeaderDescriptor
!= NULL
)
303 CommonDescriptor
= USBD_ParseDescriptors(InterfaceHeaderDescriptor
, InterfaceHeaderDescriptor
->wTotalLength
, (PVOID
)((ULONG_PTR
)InterfaceHeaderDescriptor
+ InterfaceHeaderDescriptor
->bLength
), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
);
304 while (CommonDescriptor
)
306 InputTerminalDescriptor
= (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
)CommonDescriptor
;
307 if (InputTerminalDescriptor
->bDescriptorSubtype
== 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor
->bDescriptorSubtype
== 0x03 /* OUTPUT_TERMINAL*/)
309 if (InputTerminalDescriptor
->wTerminalType
!= USB_AUDIO_STREAMING_TERMINAL_TYPE
)
311 if (TerminalCount
== Index
)
313 return InputTerminalDescriptor
;
318 CommonDescriptor
= (PUSB_COMMON_DESCRIPTOR
)((ULONG_PTR
)CommonDescriptor
+ CommonDescriptor
->bLength
);
319 if ((ULONG_PTR
)CommonDescriptor
>= ((ULONG_PTR
)InterfaceHeaderDescriptor
+ InterfaceHeaderDescriptor
->wTotalLength
))
329 UsbAudioGetDataRanges(
330 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
331 IN UCHAR bTerminalID
,
332 OUT PKSDATARANGE
** OutDataRanges
,
333 OUT PULONG OutDataRangesCount
)
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
;
342 for (Descriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, ConfigurationDescriptor
, -1, -1, USB_DEVICE_CLASS_AUDIO
, -1, -1);
344 Descriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, (PVOID
)((ULONG_PTR
)Descriptor
+ Descriptor
->bLength
), -1, -1, USB_DEVICE_CLASS_AUDIO
, -1, -1))
346 if (Descriptor
->bInterfaceSubClass
== 0x02) /* AUDIO_STREAMING */
348 StreamingInterfaceDescriptor
= (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR
)USBD_ParseDescriptors(ConfigurationDescriptor
, ConfigurationDescriptor
->wTotalLength
, Descriptor
, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
);
349 if (StreamingInterfaceDescriptor
!= NULL
)
351 ASSERT(StreamingInterfaceDescriptor
->bDescriptorSubtype
== 0x01);
352 ASSERT(StreamingInterfaceDescriptor
->wFormatTag
== WAVE_FORMAT_PCM
);
353 if (StreamingInterfaceDescriptor
->bTerminalLink
== bTerminalID
)
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);
360 DataRangeAudio
= AllocFunction(sizeof(KSDATARANGE_AUDIO
));
361 if (DataRangeAudio
== NULL
)
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
)
381 FreeFunction(DataRangeAudio
);
384 DataRangeAudioArray
[0] = (PKSDATARANGE
)DataRangeAudio
;
385 *OutDataRanges
= DataRangeAudioArray
;
386 *OutDataRangesCount
= 1;
396 USBAudioPinBuildDescriptors(
398 PKSPIN_DESCRIPTOR_EX
*PinDescriptors
,
399 PULONG PinDescriptorsCount
,
400 PULONG PinDescriptorSize
)
402 PDEVICE_EXTENSION DeviceExtension
;
403 PKSPIN_DESCRIPTOR_EX Pins
;
404 ULONG TotalTerminalDescriptorCount
= 0;
405 ULONG NonStreamingTerminalDescriptorCount
= 0;
407 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor
= NULL
;
409 /* get device extension */
410 DeviceExtension
= Device
->Context
;
412 CountTerminalUnits(DeviceExtension
->ConfigurationDescriptor
, &NonStreamingTerminalDescriptorCount
, &TotalTerminalDescriptorCount
);
413 DPRINT1("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu", TotalTerminalDescriptorCount
, NonStreamingTerminalDescriptorCount
);
416 Pins
= AllocFunction(sizeof(KSPIN_DESCRIPTOR_EX
) * TotalTerminalDescriptorCount
);
420 return STATUS_INSUFFICIENT_RESOURCES
;
423 for (Index
= 0; Index
< TotalTerminalDescriptorCount
; Index
++)
425 if (Index
< (TotalTerminalDescriptorCount
- NonStreamingTerminalDescriptorCount
))
428 TerminalDescriptor
= UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension
->ConfigurationDescriptor
, Index
);
429 ASSERT(TerminalDescriptor
!= NULL
);
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
);
439 if (TerminalDescriptor
->bDescriptorSubtype
== USB_AUDIO_OUTPUT_TERMINAL
)
441 Pins
[Index
].PinDescriptor
.Communication
= KSPIN_COMMUNICATION_BOTH
;
442 Pins
[Index
].PinDescriptor
.DataFlow
= KSPIN_DATAFLOW_OUT
;
444 else if (TerminalDescriptor
->bDescriptorSubtype
== USB_AUDIO_INPUT_TERMINAL
)
446 Pins
[Index
].PinDescriptor
.Communication
= KSPIN_COMMUNICATION_SINK
;
447 Pins
[Index
].PinDescriptor
.DataFlow
= KSPIN_DATAFLOW_IN
;
450 /* irp sinks / sources can be instantiated */
451 Pins
[Index
].InstancesPossible
= 1;
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
);
466 if (TerminalDescriptor
->bDescriptorSubtype
== USB_AUDIO_INPUT_TERMINAL
)
468 Pins
[Index
].PinDescriptor
.DataFlow
= KSPIN_DATAFLOW_IN
;
470 else if (TerminalDescriptor
->bDescriptorSubtype
== USB_AUDIO_OUTPUT_TERMINAL
)
472 Pins
[Index
].PinDescriptor
.DataFlow
= KSPIN_DATAFLOW_OUT
;
478 *PinDescriptors
= Pins
;
479 *PinDescriptorSize
= sizeof(KSPIN_DESCRIPTOR_EX
);
480 *PinDescriptorsCount
= TotalTerminalDescriptorCount
;
482 return STATUS_SUCCESS
;
486 USBAudioInitComponentId(
488 IN PKSCOMPONENTID ComponentId
)
490 PDEVICE_EXTENSION DeviceExtension
;
492 /* get device extension */
493 DeviceExtension
= Device
->Context
;
495 INIT_USBAUDIO_MID(&ComponentId
->Manufacturer
, DeviceExtension
->DeviceDescriptor
->idVendor
);
496 INIT_USBAUDIO_PID(&ComponentId
->Product
, DeviceExtension
->DeviceDescriptor
->idProduct
);
498 //ComponentId->Component = KSCOMPONENTID_USBAUDIO;
500 return STATUS_NOT_IMPLEMENTED
;
506 USBAudioCreateFilterContext(
509 PKSFILTER_DESCRIPTOR FilterDescriptor
;
510 PKSCOMPONENTID ComponentId
;
513 /* allocate descriptor */
514 FilterDescriptor
= AllocFunction(sizeof(KSFILTER_DESCRIPTOR
));
515 if (!FilterDescriptor
)
518 return USBD_STATUS_INSUFFICIENT_RESOURCES
;
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
;
529 /* init component id*/
530 ComponentId
= AllocFunction(sizeof(KSCOMPONENTID
));
534 return STATUS_INSUFFICIENT_RESOURCES
;
536 Status
= USBAudioInitComponentId(Device
, ComponentId
);
537 if (!NT_SUCCESS(Status
))
540 //FreeFunction(ComponentId);
543 FilterDescriptor
->ComponentId
= ComponentId
;
545 /* build pin descriptors */
546 Status
= USBAudioPinBuildDescriptors(Device
, (PKSPIN_DESCRIPTOR_EX
*)&FilterDescriptor
->PinDescriptors
, &FilterDescriptor
->PinDescriptorsCount
, &FilterDescriptor
->PinDescriptorSize
);
547 if (!NT_SUCCESS(Status
))
550 FreeFunction(ComponentId
);
555 Status
= BuildUSBAudioFilterTopology(Device
);
556 if (!NT_SUCCESS(Status
))
559 //FreeFunction(ComponentId);
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
);