Author: janderwald
Date: Fri Dec 28 19:38:10 2012
New Revision: 58033
URL:
http://svn.reactos.org/svn/reactos?rev=58033&view=rev
Log:
[LIBUSBAUDIO]
- Start implementing a library which is used to parse USB configuration descriptors and
construct KSFILTER_DESCRIPTOR structure, which is used with the kernel streaming driver
(ks.sys)
- The library will be used in USBAUDIO driver
Added:
trunk/reactos/lib/drivers/sound/libusbaudio/ (with props)
trunk/reactos/lib/drivers/sound/libusbaudio/CMakeLists.txt (with props)
trunk/reactos/lib/drivers/sound/libusbaudio/format.c (with props)
trunk/reactos/lib/drivers/sound/libusbaudio/libusbaudio.c (with props)
trunk/reactos/lib/drivers/sound/libusbaudio/libusbaudio.h (with props)
trunk/reactos/lib/drivers/sound/libusbaudio/parser.c (with props)
trunk/reactos/lib/drivers/sound/libusbaudio/priv.h (with props)
Propchange: trunk/reactos/lib/drivers/sound/libusbaudio/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Fri Dec 28 19:38:10 2012
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange: trunk/reactos/lib/drivers/sound/libusbaudio/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange: trunk/reactos/lib/drivers/sound/libusbaudio/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Propchange: trunk/reactos/lib/drivers/sound/libusbaudio/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: trunk/reactos/lib/drivers/sound/libusbaudio/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/libusbau…
==============================================================================
--- trunk/reactos/lib/drivers/sound/libusbaudio/CMakeLists.txt (added)
+++ trunk/reactos/lib/drivers/sound/libusbaudio/CMakeLists.txt [iso-8859-1] Fri Dec 28
19:38:10 2012
@@ -1,0 +1,13 @@
+
+add_definitions(
+ -DUNICODE -D_UNICODE
+ -DNDEBUG=1)
+
+list(APPEND SOURCE
+ libusbaudio.c
+ parser.c
+ format.c)
+
+add_library(libusbaudio ${SOURCE})
+add_dependencies(libusbaudio bugcodes)
+
Propchange: trunk/reactos/lib/drivers/sound/libusbaudio/CMakeLists.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/drivers/sound/libusbaudio/format.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/libusbau…
==============================================================================
--- trunk/reactos/lib/drivers/sound/libusbaudio/format.c (added)
+++ trunk/reactos/lib/drivers/sound/libusbaudio/format.c [iso-8859-1] Fri Dec 28 19:38:10
2012
@@ -1,0 +1,155 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: lib/drivers/sound/libusbaudio/format.c
+ * PURPOSE: USB AUDIO Parser
+ * PROGRAMMER: Johannes Anderwald
+ */
+
+#include "priv.h"
+
+KSDATARANGE StandardDataRange =
+{
+ {
+ sizeof(KSDATARANGE),
+ 0,
+ 0,
+ 0,
+ {STATIC_KSDATAFORMAT_TYPE_AUDIO},
+ {STATIC_KSDATAFORMAT_SUBTYPE_ANALOG},
+ {STATIC_KSDATAFORMAT_SPECIFIER_NONE}
+ }
+};
+
+GUID DataFormatTypeAudio = {STATIC_KSDATAFORMAT_TYPE_AUDIO};
+GUID DataFormatSubTypePCM = {STATIC_KSDATAFORMAT_SUBTYPE_PCM};
+GUID DataFormatSpecifierWaveFormat = {STATIC_KSDATAFORMAT_SPECIFIER_WAVEFORMATEX};
+
+USBAUDIO_STATUS
+UsbAudio_AssignDataRanges(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorSize,
+ IN PKSFILTER_DESCRIPTOR FilterDescriptor,
+ IN PUSB_COMMON_DESCRIPTOR * InterfaceDescriptors,
+ IN ULONG InterfaceCount,
+ IN ULONG InterfaceIndex,
+ IN PULONG TerminalIds)
+{
+ ULONG Count, Index;
+ USBAUDIO_STATUS Status;
+ PUSB_COMMON_DESCRIPTOR * Descriptors;
+ PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR HeaderDescriptor;
+ PKSDATAFORMAT_WAVEFORMATEX WaveFormat;
+ PKSDATARANGE *DataRanges;
+ PKSPIN_DESCRIPTOR PinDescriptor;
+ PUSB_AUDIO_STREAMING_FORMAT_TYPE_1 FormatType;
+
+ /* count audio descriptors */
+ Status = UsbAudio_CountAudioDescriptors(ConfigurationDescriptor,
ConfigurationDescriptorSize, InterfaceDescriptors, InterfaceCount, InterfaceIndex,
&Count);
+ if (Status != UA_STATUS_SUCCESS || Count < 2)
+ {
+ /* ignore failure */
+ DPRINT1("[LIBUSBAUDIO] Failed to count descriptors with %x Count %lx for
InterfaceIndex %lx InterfaceCount %lx\n", Status, Count, InterfaceIndex,
InterfaceCount);
+ return UA_STATUS_SUCCESS;
+ }
+
+ /* create descriptor array */
+ Status = UsbAudio_CreateAudioDescriptorArray(Context, ConfigurationDescriptor,
ConfigurationDescriptorSize, InterfaceDescriptors, InterfaceCount, InterfaceIndex, Count,
&Descriptors);
+ if (Status != UA_STATUS_SUCCESS)
+ {
+ /* ignore failure */
+ DPRINT1("[LIBUSBAUDIO] Failed to create audio descriptor array Count %lx
Status %x\n", Count, Status);
+ return UA_STATUS_SUCCESS;
+ }
+
+ /* get header */
+ HeaderDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)Descriptors[0];
+ if (!HeaderDescriptor || HeaderDescriptor->bDescriptorType !=
USB_AUDIO_STREAMING_INTERFACE_INTERFACE_DESCRIPTOR_TYPE ||
+ HeaderDescriptor->bDescriptorSubtype != 0x01)
+ {
+ /* header missing or mis-aligned */
+ DPRINT1("[LIBUSBAUDIO] Failed to retrieve audio header %p\n",
HeaderDescriptor);
+ return UA_STATUS_SUCCESS;
+ }
+
+ /* FIXME: only PCM is supported */
+ if (HeaderDescriptor->wFormatTag != WAVE_FORMAT_PCM)
+ {
+ /* not supported */
+ DPRINT1("[LIBUSBAUDIO] Only PCM is currenly supported wFormatTag %x\n",
HTONS(HeaderDescriptor->wFormatTag));
+ return UA_STATUS_SUCCESS;
+ }
+
+ /* check format descriptor */
+ FormatType = (PUSB_AUDIO_STREAMING_FORMAT_TYPE_1)Descriptors[1];
+ if (!FormatType || FormatType->bDescriptorType !=
USB_AUDIO_STREAMING_INTERFACE_INTERFACE_DESCRIPTOR_TYPE ||
+ FormatType->bDescriptorSubtype != 0x02 || FormatType->bFormatType != 0x01
|| FormatType->bSamFreqType != 1)
+ {
+ /* unexpected format descriptor */
+ DPRINT1("[LIBUSBAUDIO] Unexpected format descriptor %p bDescriptorType %x
bDescriptorSubtype %x bFormatType %x bSamFreqType %x\n", FormatType,
+ FormatType->bDescriptorType, FormatType->bDescriptorSubtype,
FormatType->bFormatType, FormatType->bSamFreqType);
+ return UA_STATUS_SUCCESS;
+ }
+
+
+ /* now search pin position */
+ for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++)
+ {
+ //DPRINT("bTerminalLink %x Ids %lx\n",
HeaderDescriptor->bTerminalLink, TerminalIds[Index]);
+ if (HeaderDescriptor->bTerminalLink == TerminalIds[Index])
+ {
+ /* alloc wave format */
+ WaveFormat =
(PKSDATAFORMAT_WAVEFORMATEX)Context->Alloc(sizeof(KSDATAFORMAT_WAVEFORMATEX));
+ if (!WaveFormat)
+ return UA_STATUS_NO_MEMORY;
+
+ /* init wave format */
+ WaveFormat->WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
+ WaveFormat->WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
+ WaveFormat->WaveFormatEx.nChannels = FormatType->bNrChannels;
+ WaveFormat->WaveFormatEx.wBitsPerSample = FormatType->bBitResolution;
+ WaveFormat->WaveFormatEx.nSamplesPerSec = ((FormatType->tSamFreq[2]
& 0xFF) << 16) | ((FormatType->tSamFreq[1] & 0xFF)<< 8) |
(FormatType->tSamFreq[0] & 0xFF);
+ WaveFormat->WaveFormatEx.nBlockAlign =
(WaveFormat->WaveFormatEx.nChannels * WaveFormat->WaveFormatEx.wBitsPerSample) / 8;
+ WaveFormat->WaveFormatEx.nAvgBytesPerSec =
WaveFormat->WaveFormatEx.nSamplesPerSec * WaveFormat->WaveFormatEx.nBlockAlign;
+
+ /* FIXME apply padding */
+ WaveFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT_WAVEFORMATEX);
+ Context->Copy(&WaveFormat->DataFormat.MajorFormat,
&DataFormatTypeAudio, sizeof(GUID));
+ Context->Copy(&WaveFormat->DataFormat.SubFormat,
&DataFormatSubTypePCM, sizeof(GUID));
+ Context->Copy(&WaveFormat->DataFormat.Specifier,
&DataFormatSpecifierWaveFormat, sizeof(GUID));
+
+ //C_ASSERT(sizeof(WAVEFORMATEX) + sizeof(KSDATAFORMAT) == 82);
+
+ /* get corresponding pin descriptor */
+ PinDescriptor =
(PKSPIN_DESCRIPTOR)&FilterDescriptor->PinDescriptors[Index].PinDescriptor;
+
+ /* alloc data range */
+ DataRanges = (PKSDATARANGE*)Context->Alloc(sizeof(PKSDATARANGE) *
(PinDescriptor->DataRangesCount+1));
+ if (!DataRanges)
+ {
+ Context->Free(WaveFormat);
+ return UA_STATUS_NO_MEMORY;
+ }
+
+ if (PinDescriptor->DataRangesCount)
+ {
+ /* copy old range */
+ Context->Copy(DataRanges, (PVOID)PinDescriptor->DataRanges,
sizeof(PKSDATARANGE) * PinDescriptor->DataRangesCount);
+
+ /* free old range */
+ Context->Free((PVOID)PinDescriptor->DataRanges);
+ }
+
+ /* assign new range */
+ PinDescriptor->DataRanges = DataRanges;
+ DataRanges[PinDescriptor->DataRangesCount] = (PKSDATARANGE)WaveFormat;
+ PinDescriptor->DataRangesCount++;
+ return UA_STATUS_SUCCESS;
+ }
+
+ }
+ return UA_STATUS_SUCCESS;
+}
+
+
Propchange: trunk/reactos/lib/drivers/sound/libusbaudio/format.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/drivers/sound/libusbaudio/libusbaudio.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/libusbau…
==============================================================================
--- trunk/reactos/lib/drivers/sound/libusbaudio/libusbaudio.c (added)
+++ trunk/reactos/lib/drivers/sound/libusbaudio/libusbaudio.c [iso-8859-1] Fri Dec 28
19:38:10 2012
@@ -1,0 +1,364 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: lib/drivers/sound/libusbaudio/libusbaudio.c
+ * PURPOSE: USB AUDIO Parser
+ * PROGRAMMER: Johannes Anderwald
+ */
+#include "priv.h"
+
+GUID NodeTypeMicrophone = {STATIC_KSNODETYPE_MICROPHONE};
+GUID NodeTypeDesktopMicrophone = {STATIC_KSNODETYPE_DESKTOP_MICROPHONE};
+GUID NodeTypePersonalMicrophone = {STATIC_KSNODETYPE_PERSONAL_MICROPHONE};
+GUID NodeTypeOmmniMicrophone = {STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE};
+GUID NodeTypeArrayMicrophone = {STATIC_KSNODETYPE_MICROPHONE_ARRAY};
+GUID NodeTypeProcessingArrayMicrophone =
{STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY};
+GUID NodeTypeSpeaker = {STATIC_KSNODETYPE_SPEAKER};
+GUID NodeTypeHeadphonesSpeaker = {STATIC_KSNODETYPE_HEADPHONES};
+GUID NodeTypeHMDA = {STATIC_KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO};
+GUID NodeTypeDesktopSpeaker = {STATIC_KSNODETYPE_DESKTOP_SPEAKER};
+GUID NodeTypeRoomSpeaker = {STATIC_KSNODETYPE_ROOM_SPEAKER};
+GUID NodeTypeCommunicationSpeaker = {STATIC_KSNODETYPE_COMMUNICATION_SPEAKER};
+GUID NodeTypeSubwoofer = {STATIC_KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER};
+GUID NodeTypeCapture = {STATIC_PINNAME_CAPTURE};
+GUID NodeTypePlayback = {STATIC_KSCATEGORY_AUDIO};
+
+
+KSPIN_INTERFACE StandardPinInterface =
+{
+ {STATIC_KSINTERFACESETID_Standard},
+ KSINTERFACE_STANDARD_STREAMING,
+ 0
+};
+
+KSPIN_MEDIUM StandardPinMedium =
+{
+ {STATIC_KSMEDIUMSETID_Standard},
+ KSMEDIUM_TYPE_ANYINSTANCE,
+ 0
+};
+
+USBAUDIO_STATUS
+UsbAudio_InitializeContext(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUSBAUDIO_ALLOC Alloc,
+ IN PUSBAUDIO_FREE Free,
+ IN PUSBAUDIO_COPY Copy)
+{
+
+ /* verify parameters */
+ if (!Context || !Alloc || !Free || !Copy)
+ {
+ /* invalid parameter */
+ return UA_STATUS_INVALID_PARAMETER;
+ }
+
+ /* initialize context */
+ Context->Size = sizeof(USBAUDIO_CONTEXT);
+ Context->Alloc = Alloc;
+ Context->Free = Free;
+ Context->Copy = Copy;
+
+ /* done */
+ return UA_STATUS_SUCCESS;
+}
+
+LPGUID
+UsbAudio_GetPinCategoryFromTerminalDescriptor(
+ IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor)
+{
+ if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE)
+ return &NodeTypeMicrophone;
+ else if (TerminalDescriptor->wTerminalType ==
USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE)
+ return &NodeTypeDesktopMicrophone;
+ else if (TerminalDescriptor->wTerminalType ==
USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE)
+ return &NodeTypePersonalMicrophone;
+ else if (TerminalDescriptor->wTerminalType ==
USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE)
+ return &NodeTypeOmmniMicrophone;
+ else if (TerminalDescriptor->wTerminalType ==
USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE)
+ return &NodeTypeArrayMicrophone;
+ else if (TerminalDescriptor->wTerminalType ==
USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE)
+ return &NodeTypeProcessingArrayMicrophone;
+
+ /* playback types */
+ if (TerminalDescriptor->wTerminalType == USB_AUDIO_SPEAKER_TERMINAL_TYPE)
+ return &NodeTypeSpeaker;
+ else if (TerminalDescriptor->wTerminalType ==
USB_HEADPHONES_SPEAKER_TERMINAL_TYPE)
+ return &NodeTypeHeadphonesSpeaker;
+ else if (TerminalDescriptor->wTerminalType == USB_AUDIO_HMDA_TERMINAL_TYPE)
+ return &NodeTypeHMDA;
+ else if (TerminalDescriptor->wTerminalType ==
USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE)
+ return &NodeTypeDesktopSpeaker;
+ else if (TerminalDescriptor->wTerminalType ==
USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE)
+ return &NodeTypeRoomSpeaker;
+ else if (TerminalDescriptor->wTerminalType ==
USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE)
+ return &NodeTypeCommunicationSpeaker;
+ else if (TerminalDescriptor->wTerminalType == USB_AUDIO_SUBWOOFER_TERMINAL_TYPE)
+ return &NodeTypeSubwoofer;
+
+ if (TerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
+ {
+ if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
+ return &NodeTypeCapture;
+ else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
+ return &NodeTypePlayback;
+
+ }
+ return NULL;
+}
+
+USBAUDIO_STATUS
+UsbAudio_InitPinDescriptor(
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ IN PKSPIN_DESCRIPTOR_EX PinDescriptor,
+ IN ULONG TerminalCount,
+ IN PUSB_COMMON_DESCRIPTOR * Descriptors,
+ IN ULONG TerminalId)
+{
+ PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor;
+
+ TerminalDescriptor = UsbAudio_GetTerminalDescriptorById(Descriptors, TerminalCount,
TerminalId);
+ if (!TerminalDescriptor)
+ {
+ /* failed to find terminal descriptor */
+ return UA_STATUS_UNSUCCESSFUL;
+ }
+
+ /* init pin descriptor */
+ PinDescriptor->PinDescriptor.InterfacesCount = 1;
+ PinDescriptor->PinDescriptor.Interfaces = &StandardPinInterface;
+ PinDescriptor->PinDescriptor.MediumsCount = 1;
+ PinDescriptor->PinDescriptor.Mediums = &StandardPinMedium;
+ PinDescriptor->PinDescriptor.Category =
UsbAudio_GetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
+
+ if (TerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
+ {
+ if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
+ {
+ PinDescriptor->PinDescriptor.Communication = KSPIN_COMMUNICATION_SINK;
+ PinDescriptor->PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
+ }
+ else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
+ {
+ PinDescriptor->PinDescriptor.Communication = KSPIN_COMMUNICATION_SINK;
+ PinDescriptor->PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
+ }
+
+ /* irp sinks / sources can be instantiated */
+ PinDescriptor->InstancesPossible = 1;
+
+ }
+ else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
+ {
+ PinDescriptor->PinDescriptor.Communication = KSPIN_COMMUNICATION_BRIDGE;
+ PinDescriptor->PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
+ }
+ else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
+ {
+ PinDescriptor->PinDescriptor.Communication = KSPIN_COMMUNICATION_BRIDGE;
+ PinDescriptor->PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
+ }
+
+ return UA_STATUS_SUCCESS;
+}
+
+USBAUDIO_STATUS
+UsbAudio_ParseConfigurationDescriptor(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorSize)
+{
+ USBAUDIO_STATUS Status;
+ PKSFILTER_DESCRIPTOR FilterDescriptor;
+ PUSB_COMMON_DESCRIPTOR * Descriptors;
+ PUSB_COMMON_DESCRIPTOR * InterfaceDescriptors;
+ PULONG TerminalIds;
+ ULONG Index, AudioControlInterfaceIndex;
+ ULONG InterfaceCount, DescriptorCount, NewDescriptorCount;
+ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+
+
+ if (!Context || !ConfigurationDescriptor || !ConfigurationDescriptorSize)
+ {
+ /* invalid parameter */
+ return UA_STATUS_INVALID_PARAMETER;
+ }
+
+ /* count usb interface descriptors */
+ Status = UsbAudio_CountInterfaceDescriptors(ConfigurationDescriptor,
ConfigurationDescriptorSize, &InterfaceCount);
+ if (Status != UA_STATUS_SUCCESS || InterfaceCount == 0)
+ {
+ /* invalid parameter */
+ return UA_STATUS_INVALID_PARAMETER;
+ }
+
+ /* construct interface array */
+ Status = UsbAudio_CreateInterfaceDescriptorsArray(Context, ConfigurationDescriptor,
ConfigurationDescriptorSize, InterfaceCount, &InterfaceDescriptors);
+ if (Status != UA_STATUS_SUCCESS)
+ {
+ /* invalid parameter */
+ return UA_STATUS_INVALID_PARAMETER;
+ }
+
+ /* get audio control interface index */
+ AudioControlInterfaceIndex =
UsbAudio_GetAudioControlInterfaceIndex(InterfaceDescriptors, InterfaceCount);
+ if (AudioControlInterfaceIndex == MAXULONG)
+ {
+ /* invalid configuration descriptor */
+ Context->Free(InterfaceDescriptors);
+ return UA_STATUS_INVALID_PARAMETER;
+ }
+
+ /* count audio terminal descriptors */
+ Status = UsbAudio_CountAudioDescriptors(ConfigurationDescriptor,
ConfigurationDescriptorSize, InterfaceDescriptors, InterfaceCount,
AudioControlInterfaceIndex, &DescriptorCount);
+ if (Status != UA_STATUS_SUCCESS || DescriptorCount == 0)
+ {
+ /* invalid parameter */
+ Context->Free(InterfaceDescriptors);
+ return UA_STATUS_INVALID_PARAMETER;
+ }
+
+ /* construct terminal descriptor array */
+ Status = UsbAudio_CreateAudioDescriptorArray(Context, ConfigurationDescriptor,
ConfigurationDescriptorSize, InterfaceDescriptors, InterfaceCount,
AudioControlInterfaceIndex, DescriptorCount, &Descriptors);
+ if (Status != UA_STATUS_SUCCESS)
+ {
+ /* no memory */
+ Context->Free(InterfaceDescriptors);
+ //DPRINT("[LIBUSBAUDIO] Failed to create descriptor array with %x\n",
Status);
+ return Status;
+ }
+
+ /* construct filter */
+ FilterDescriptor =
(PKSFILTER_DESCRIPTOR)Context->Alloc(sizeof(KSFILTER_DESCRIPTOR));
+ if (!FilterDescriptor)
+ {
+ /* no memory */
+ Context->Free(InterfaceDescriptors);
+ Context->Free(Descriptors);
+ return UA_STATUS_NO_MEMORY;
+ }
+
+
+ /* construct pin id array */
+ TerminalIds = (PULONG)Context->Alloc(sizeof(ULONG) * DescriptorCount);
+ if (!TerminalIds)
+ {
+ /* no memory */
+ Context->Free(InterfaceDescriptors);
+ Context->Free(FilterDescriptor);
+ Context->Free(Descriptors);
+ return UA_STATUS_NO_MEMORY;
+ }
+
+ /* now assign terminal ids */
+ Status = UsbAudio_AssignTerminalIds(Context, DescriptorCount, Descriptors,
TerminalIds, &NewDescriptorCount);
+ if(Status != UA_STATUS_SUCCESS || NewDescriptorCount == 0)
+ {
+ /* failed to initialize */
+ Context->Free(InterfaceDescriptors);
+ Context->Free(FilterDescriptor);
+ Context->Free(Descriptors);
+ Context->Free(TerminalIds);
+ DPRINT1("[LIBUSBAUDIO] Failed to assign terminal ids with %x DescriptorCount
%lx\n", Status, DescriptorCount);
+ return UA_STATUS_UNSUCCESSFUL;
+ }
+
+
+ /* init filter */
+ FilterDescriptor->Version = KSFILTER_DESCRIPTOR_VERSION;
+ FilterDescriptor->Flags = 0; /* FIXME */
+ FilterDescriptor->PinDescriptorsCount = NewDescriptorCount;
+ FilterDescriptor->PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR_EX);
+ FilterDescriptor->PinDescriptors = Context->Alloc(sizeof(KSPIN_DESCRIPTOR_EX) *
FilterDescriptor->PinDescriptorsCount);
+ if (!FilterDescriptor->PinDescriptors)
+ {
+ /* no memory */
+ Context->Free(InterfaceDescriptors);
+ Context->Free(FilterDescriptor);
+ Context->Free(Descriptors);
+ Context->Free(TerminalIds);
+ return UA_STATUS_NO_MEMORY;
+ }
+
+ /* now init pin properties */
+ for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++)
+ {
+ /* now init every pin descriptor */
+ Status = UsbAudio_InitPinDescriptor(ConfigurationDescriptor,
ConfigurationDescriptorSize,
(PKSPIN_DESCRIPTOR_EX)&FilterDescriptor->PinDescriptors[Index], DescriptorCount,
Descriptors, TerminalIds[Index]);
+ if (Status != UA_STATUS_SUCCESS)
+ break;
+ }
+
+ if (Status != UA_STATUS_SUCCESS)
+ {
+ /* failed to init pin descriptor */
+ Context->Free(InterfaceDescriptors);
+ Context->Free((PVOID)FilterDescriptor->PinDescriptors);
+ Context->Free(FilterDescriptor);
+ Context->Free(Descriptors);
+ Context->Free(TerminalIds);
+ DPRINT1("[LIBUSBAUDIO] Failed to init pin with %x\n", Status);
+ return Status;
+ }
+
+
+ /* now assign data ranges to the pins */
+ for(Index = 0; Index < InterfaceCount; Index++)
+ {
+ /* get descriptor */
+ InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)InterfaceDescriptors[Index];
+
+ /* sanity check */
+ ASSERT(InterfaceDescriptor->bDescriptorType ==
USB_INTERFACE_DESCRIPTOR_TYPE);
+ DPRINT1("InterfaceNumber %d bInterfaceClass %x bInterfaceSubClass
%x\n", InterfaceDescriptor->bInterfaceNumber,
InterfaceDescriptor->bInterfaceClass, InterfaceDescriptor->bInterfaceSubClass);
+
+ if (InterfaceDescriptor->bInterfaceClass != 0x01 &&
InterfaceDescriptor->bInterfaceSubClass != 0x02)
+ continue;
+
+ /* assign data ranges */
+ Status = UsbAudio_AssignDataRanges(Context, ConfigurationDescriptor,
ConfigurationDescriptorSize, FilterDescriptor, InterfaceDescriptors, InterfaceCount,
Index, TerminalIds);
+ if (Status != UA_STATUS_SUCCESS)
+ break;
+ }
+
+ if (Status != UA_STATUS_SUCCESS)
+ {
+ /* failed to init pin descriptor */
+ Context->Free(InterfaceDescriptors);
+ Context->Free((PVOID)FilterDescriptor->PinDescriptors);
+ Context->Free(FilterDescriptor);
+ Context->Free(Descriptors);
+ Context->Free(TerminalIds);
+ return Status;
+ }
+
+
+
+ if (Status != UA_STATUS_SUCCESS)
+ {
+ /* failed to init pin descriptor */
+ Context->Free(InterfaceDescriptors);
+ Context->Free((PVOID)FilterDescriptor->PinDescriptors);
+ Context->Free(FilterDescriptor);
+ Context->Free(Descriptors);
+ Context->Free(TerminalIds);
+ return Status;
+ }
+
+ Context->Context = FilterDescriptor;
+ return Status;
+
+}
+
+USBAUDIO_STATUS
+UsbAudio_GetFilter(
+ IN PUSBAUDIO_CONTEXT Context,
+ OUT PVOID * OutFilterDescriptor)
+{
+ if (!OutFilterDescriptor)
+ return UA_STATUS_INVALID_PARAMETER;
+
+ *OutFilterDescriptor = Context->Context;
+ return UA_STATUS_SUCCESS;
+}
Propchange: trunk/reactos/lib/drivers/sound/libusbaudio/libusbaudio.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/drivers/sound/libusbaudio/libusbaudio.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/libusbau…
==============================================================================
--- trunk/reactos/lib/drivers/sound/libusbaudio/libusbaudio.h (added)
+++ trunk/reactos/lib/drivers/sound/libusbaudio/libusbaudio.h [iso-8859-1] Fri Dec 28
19:38:10 2012
@@ -1,0 +1,56 @@
+#pragma once
+
+typedef enum
+{
+ UA_STATUS_SUCCESS = 0,
+ UA_STATUS_NOTINITIALIZED,
+ UA_STATUS_NOT_IMPLEMENTED,
+ UA_STATUS_NO_MORE_DEVICES,
+ UA_STATUS_MORE_ENTRIES,
+ UA_STATUS_INVALID_PARAMETER,
+ UA_STATUS_UNSUCCESSFUL,
+ UA_STATUS_NO_MEMORY
+}USBAUDIO_STATUS;
+
+typedef PVOID (*PUSBAUDIO_ALLOC)(
+ IN ULONG NumberOfBytes);
+
+typedef VOID (*PUSBAUDIO_FREE)(
+ IN PVOID Block);
+
+typedef VOID (*PUSBAUDIO_COPY)(
+ IN PVOID Dst,
+ IN PVOID Src,
+ IN ULONG Length);
+
+typedef struct
+{
+ ULONG Size;
+ PVOID Context;
+
+ PUSBAUDIO_ALLOC Alloc;
+ PUSBAUDIO_FREE Free;
+ PUSBAUDIO_COPY Copy;
+
+
+}USBAUDIO_CONTEXT, *PUSBAUDIO_CONTEXT;
+
+USBAUDIO_STATUS
+UsbAudio_InitializeContext(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUSBAUDIO_ALLOC Alloc,
+ IN PUSBAUDIO_FREE Free,
+ IN PUSBAUDIO_COPY Copy);
+
+
+USBAUDIO_STATUS
+UsbAudio_ParseConfigurationDescriptor(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorSize);
+
+USBAUDIO_STATUS
+UsbAudio_GetFilter(
+ IN PUSBAUDIO_CONTEXT Context,
+ OUT PVOID * OutFilterDescriptor);
+
Propchange: trunk/reactos/lib/drivers/sound/libusbaudio/libusbaudio.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/drivers/sound/libusbaudio/parser.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/libusbau…
==============================================================================
--- trunk/reactos/lib/drivers/sound/libusbaudio/parser.c (added)
+++ trunk/reactos/lib/drivers/sound/libusbaudio/parser.c [iso-8859-1] Fri Dec 28 19:38:10
2012
@@ -1,0 +1,390 @@
+/*
+* COPYRIGHT: See COPYING in the top level directory
+* PROJECT: ReactOS Kernel Streaming
+* FILE: lib/drivers/sound/libusbaudio/libusbaudio.c
+* PURPOSE: USB AUDIO Parser
+* PROGRAMMER: Johannes Anderwald
+*/
+
+#include "priv.h"
+
+USBAUDIO_STATUS
+UsbAudio_CountDescriptors(
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ IN UCHAR DescriptorType,
+ IN PUSB_COMMON_DESCRIPTOR StartPosition,
+ IN PUSB_COMMON_DESCRIPTOR EndPosition,
+ OUT PULONG DescriptorCount)
+{
+ PUSB_COMMON_DESCRIPTOR Descriptor;
+ ULONG Count = 0;
+
+ /* init result */
+ *DescriptorCount = 0;
+
+ /* enumerate descriptors */
+ Descriptor = StartPosition;
+ if (Descriptor == NULL)
+ Descriptor = (PUSB_COMMON_DESCRIPTOR)ConfigurationDescriptor;
+
+ if (EndPosition == NULL)
+ EndPosition = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)ConfigurationDescriptor +
ConfigurationDescriptorLength);
+
+
+ while((ULONG_PTR)Descriptor < ((ULONG_PTR)EndPosition))
+ {
+ if (!Descriptor->bLength || !Descriptor->bDescriptorType)
+ {
+ /* bogus descriptor */
+ return UA_STATUS_UNSUCCESSFUL;
+ }
+
+ if (Descriptor->bDescriptorType == DescriptorType)
+ {
+ /* found descriptor */
+ Count++;
+ }
+
+ /* move to next descriptor */
+ Descriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)Descriptor +
Descriptor->bLength);
+
+ }
+
+ /* store result */
+ *DescriptorCount = Count;
+ return UA_STATUS_SUCCESS;
+}
+
+USBAUDIO_STATUS
+UsbAudio_GetDescriptors(
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ IN UCHAR DescriptorType,
+ IN ULONG DescriptorCount,
+ IN PUSB_COMMON_DESCRIPTOR StartPosition,
+ IN PUSB_COMMON_DESCRIPTOR EndPosition,
+ OUT PUSB_COMMON_DESCRIPTOR *Descriptors)
+{
+ PUSB_COMMON_DESCRIPTOR Descriptor;
+ ULONG Count = 0;
+
+ /* enumerate descriptors */
+ Descriptor = StartPosition;
+ if (Descriptor == NULL)
+ Descriptor = (PUSB_COMMON_DESCRIPTOR)ConfigurationDescriptor;
+
+ if (EndPosition == NULL)
+ EndPosition = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)ConfigurationDescriptor +
ConfigurationDescriptorLength);
+
+ while((ULONG_PTR)Descriptor < ((ULONG_PTR)EndPosition))
+ {
+ if (!Descriptor->bLength || !Descriptor->bDescriptorType)
+ {
+ /* bogus descriptor */
+ return UA_STATUS_UNSUCCESSFUL;
+ }
+
+ if (Descriptor->bDescriptorType == DescriptorType)
+ {
+ /* found descriptor */
+ if (Count >= DescriptorCount)
+ break;
+
+ /* store result */
+ Descriptors[Count] = Descriptor;
+ Count++;
+ }
+
+ /* move to next descriptor */
+ Descriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)Descriptor +
Descriptor->bLength);
+ }
+
+ /* done */
+ return UA_STATUS_SUCCESS;
+}
+
+USBAUDIO_STATUS
+UsbAudio_CountInterfaceDescriptors(
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ OUT PULONG DescriptorCount)
+{
+ return UsbAudio_CountDescriptors(ConfigurationDescriptor,
ConfigurationDescriptorLength, USB_INTERFACE_DESCRIPTOR_TYPE, NULL, NULL,
DescriptorCount);
+}
+
+USBAUDIO_STATUS
+UsbAudio_CreateDescriptorArray(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ IN ULONG ArrayLength,
+ IN ULONG DescriptorType,
+ IN PUSB_COMMON_DESCRIPTOR StartPosition,
+ IN PUSB_COMMON_DESCRIPTOR EndPosition,
+ OUT PUSB_COMMON_DESCRIPTOR ** Array)
+{
+ USBAUDIO_STATUS Status;
+ PUSB_COMMON_DESCRIPTOR * Descriptors;
+
+ /* zero result */
+ *Array = NULL;
+
+ /* first allocate descriptor array */
+ Descriptors =
(PUSB_COMMON_DESCRIPTOR*)Context->Alloc(sizeof(PUSB_COMMON_DESCRIPTOR) * ArrayLength);
+ if (!Descriptors)
+ {
+ /* no memory */
+ return UA_STATUS_NO_MEMORY;
+ }
+
+ /* extract control terminal descriptors */
+ Status = UsbAudio_GetDescriptors(ConfigurationDescriptor,
ConfigurationDescriptorLength, DescriptorType, ArrayLength, StartPosition, EndPosition,
Descriptors);
+ if (Status != UA_STATUS_SUCCESS)
+ {
+ /* failed */
+ Context->Free(Descriptors);
+ return Status;
+ }
+
+ /* store result */
+ *Array = Descriptors;
+ return UA_STATUS_SUCCESS;
+}
+
+USBAUDIO_STATUS
+UsbAudio_CountAudioDescriptors(
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ IN PUSB_COMMON_DESCRIPTOR * InterfaceDescriptors,
+ IN ULONG InterfaceDescriptorCount,
+ IN ULONG InterfaceDescriptorIndex,
+ OUT PULONG DescriptorCount)
+{
+ if (InterfaceDescriptorIndex + 1 == InterfaceDescriptorCount)
+ return UsbAudio_CountDescriptors(ConfigurationDescriptor,
ConfigurationDescriptorLength, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE,
InterfaceDescriptors[InterfaceDescriptorIndex], NULL, DescriptorCount);
+ else
+ return UsbAudio_CountDescriptors(ConfigurationDescriptor,
ConfigurationDescriptorLength, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE,
InterfaceDescriptors[InterfaceDescriptorIndex],
InterfaceDescriptors[InterfaceDescriptorIndex + 1], DescriptorCount);
+}
+
+USBAUDIO_STATUS
+UsbAudio_CreateInterfaceDescriptorsArray(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ IN ULONG ArrayLength,
+ OUT PUSB_COMMON_DESCRIPTOR ** Array)
+{
+ return UsbAudio_CreateDescriptorArray(Context, ConfigurationDescriptor,
ConfigurationDescriptorLength, ArrayLength, USB_INTERFACE_DESCRIPTOR_TYPE, NULL, NULL,
Array);
+}
+
+USBAUDIO_STATUS
+UsbAudio_CreateAudioDescriptorArray(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ IN PUSB_COMMON_DESCRIPTOR * InterfaceDescriptors,
+ IN ULONG InterfaceDescriptorCount,
+ IN ULONG InterfaceDescriptorIndex,
+ IN ULONG ArrayLength,
+ OUT PUSB_COMMON_DESCRIPTOR ** Array)
+{
+ if (InterfaceDescriptorIndex + 1 == InterfaceDescriptorCount)
+ return UsbAudio_CreateDescriptorArray(Context, ConfigurationDescriptor,
ConfigurationDescriptorLength, ArrayLength, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE,
InterfaceDescriptors[InterfaceDescriptorIndex], NULL, Array);
+ else
+ return UsbAudio_CreateDescriptorArray(Context, ConfigurationDescriptor,
ConfigurationDescriptorLength, ArrayLength, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE,
+
InterfaceDescriptors[InterfaceDescriptorIndex],
InterfaceDescriptors[InterfaceDescriptorIndex + 1], Array);
+}
+
+PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
+UsbAudio_GetTerminalDescriptorById(
+ IN PUSB_COMMON_DESCRIPTOR *Descriptors,
+ IN ULONG DescriptorCount,
+ IN ULONG TerminalId)
+{
+ ULONG Index;
+ PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR Descriptor;
+
+ for(Index = 0; Index < DescriptorCount; Index++)
+ {
+ /* get descriptor */
+ Descriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)Descriptors[Index];
+
+ /* is it an input / output terminal */
+ DPRINT("Descriptor %p Type %x SubType %x TerminalID %x\n", Descriptor,
Descriptor->bDescriptorType, Descriptor->bDescriptorSubtype,
Descriptor->bTerminalID);
+ if (Descriptor->bDescriptorSubtype != USB_AUDIO_INPUT_TERMINAL &&
Descriptor->bDescriptorSubtype != USB_AUDIO_OUTPUT_TERMINAL)
+ continue;
+
+ if (Descriptor->bTerminalID == TerminalId)
+ return Descriptor;
+ }
+ return NULL;
+}
+
+ULONG
+UsbAudio_GetAudioControlInterfaceIndex(
+ IN PUSB_COMMON_DESCRIPTOR * InterfaceDescriptors,
+ IN ULONG DescriptorCount)
+{
+ ULONG Index;
+ PUSB_INTERFACE_DESCRIPTOR Descriptor;
+
+
+ for(Index = 0; Index < DescriptorCount; Index++)
+ {
+ /* get descriptor */
+ Descriptor = (PUSB_INTERFACE_DESCRIPTOR)InterfaceDescriptors[Index];
+ ASSERT(Descriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
+ ASSERT(Descriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
+
+ /* compare interface class */
+ if (Descriptor->bInterfaceClass == 0x01 &&
Descriptor->bInterfaceSubClass == 0x01)
+ {
+ /* found audio control class */
+ return Index;
+ }
+ }
+
+ /* not found */
+ return MAXULONG;
+}
+
+
+USBAUDIO_STATUS
+UsbAudio_FindTerminalDescriptorAtIndexWithSubtypeAndTerminalType(
+ IN ULONG DescriptorCount,
+ IN PUSB_COMMON_DESCRIPTOR *Descriptors,
+ IN ULONG DescriptorIndex,
+ IN UCHAR Subtype,
+ IN USHORT TerminalType,
+ OUT PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR * OutDescriptor,
+ OUT PULONG OutDescriptorIndex)
+{
+ ULONG Index;
+ ULONG Count = 0;
+ PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR CurrentDescriptor;
+
+ for(Index = 0; Index < DescriptorCount; Index++)
+ {
+ /* get current descriptor */
+ CurrentDescriptor =
(PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)Descriptors[Index];
+ ASSERT(CurrentDescriptor->bDescriptorType ==
USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
+
+ if (CurrentDescriptor->bDescriptorSubtype == Subtype &&
+ (TerminalType == USB_AUDIO_UNDEFINED_TERMINAL_TYPE ||
CurrentDescriptor->wTerminalType == TerminalType))
+ {
+ /* found descriptor */
+ if (Count == DescriptorIndex)
+ {
+ /* store result */
+ *OutDescriptor = CurrentDescriptor;
+ *OutDescriptorIndex = Index;
+ return UA_STATUS_SUCCESS;
+ }
+
+ Count++;
+ }
+ }
+
+ /* not found */
+ return UA_STATUS_UNSUCCESSFUL;
+}
+
+USBAUDIO_STATUS
+UsbAudio_AssignTerminalIds(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN ULONG TerminalIdsLength,
+ IN PUSB_COMMON_DESCRIPTOR * TerminalIds,
+ OUT PULONG PinArray,
+ OUT PULONG PinArrayCount)
+{
+ ULONG Consumed = 0;
+ ULONG PinIndex = 0;
+ ULONG Index, DescriptorIndex;
+ PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR Descriptor;
+ USBAUDIO_STATUS Status;
+
+ /* FIXME: support more than 32 terminals */
+ ASSERT(TerminalIdsLength <= 32);
+
+ /* first search for an output terminal with streaming type */
+ Status =
UsbAudio_FindTerminalDescriptorAtIndexWithSubtypeAndTerminalType(TerminalIdsLength,
TerminalIds, 0, USB_AUDIO_OUTPUT_TERMINAL, USB_AUDIO_STREAMING_TERMINAL_TYPE,
&Descriptor, &DescriptorIndex);
+ if (Status == UA_STATUS_SUCCESS)
+ {
+ /* found output terminal */
+ PinArray[PinIndex] = Descriptor->bTerminalID;
+ Consumed |= 1 << DescriptorIndex;
+ DPRINT("Assigned TerminalId %x to PinIndex %lx Consumed %lx DescriptorIndex
%lx\n", Descriptor->bTerminalID, PinIndex, Consumed, DescriptorIndex);
+ PinIndex++;
+ }
+
+ /* now search for an input terminal with streaming type */
+ Status =
UsbAudio_FindTerminalDescriptorAtIndexWithSubtypeAndTerminalType(TerminalIdsLength,
TerminalIds, 0, USB_AUDIO_INPUT_TERMINAL, USB_AUDIO_STREAMING_TERMINAL_TYPE,
&Descriptor, &DescriptorIndex);
+ if (Status == UA_STATUS_SUCCESS)
+ {
+ /* found output terminal */
+ PinArray[PinIndex] = Descriptor->bTerminalID;
+ Consumed |= 1 << DescriptorIndex;
+ PinIndex++;
+ }
+
+ /* now assign all other input terminals */
+ Index = 0;
+ do
+ {
+ /* find an input terminal */
+ Status =
UsbAudio_FindTerminalDescriptorAtIndexWithSubtypeAndTerminalType(TerminalIdsLength,
TerminalIds, Index, USB_AUDIO_INPUT_TERMINAL, USB_AUDIO_UNDEFINED_TERMINAL_TYPE,
&Descriptor, &DescriptorIndex);
+ if (Status != UA_STATUS_SUCCESS)
+ {
+ /* no more items */
+ break;
+ }
+
+ if (Consumed & (1 << DescriptorIndex))
+ {
+ /* terminal has already been assigned to an pin */
+ Index++;
+ continue;
+ }
+
+ /* assign terminal */
+ PinArray[PinIndex] = Descriptor->bTerminalID;
+ Consumed |= 1 << DescriptorIndex;
+ PinIndex++;
+ Index++;
+
+ }while(Status == UA_STATUS_SUCCESS);
+
+
+ /* now assign all other output terminals */
+ Index = 0;
+ do
+ {
+ /* find an input terminal */
+ Status =
UsbAudio_FindTerminalDescriptorAtIndexWithSubtypeAndTerminalType(TerminalIdsLength,
TerminalIds, Index, USB_AUDIO_OUTPUT_TERMINAL, USB_AUDIO_UNDEFINED_TERMINAL_TYPE,
&Descriptor, &DescriptorIndex);
+ if (Status != UA_STATUS_SUCCESS)
+ {
+ /* no more items */
+ break;
+ }
+
+ if (Consumed & (1 << DescriptorIndex))
+ {
+ /* terminal has already been assigned to an pin */
+ Index++;
+ continue;
+ }
+
+ /* assign terminal */
+ PinArray[PinIndex] = Descriptor->bTerminalID;
+ Consumed |= 1 << DescriptorIndex;
+ PinIndex++;
+ Index++;
+
+ }while(Status == UA_STATUS_SUCCESS);
+
+ /* store pin count */
+ DPRINT("Consumed %lx PinIndex %lu\n", Consumed, PinIndex);
+ *PinArrayCount = PinIndex;
+ return UA_STATUS_SUCCESS;
+}
Propchange: trunk/reactos/lib/drivers/sound/libusbaudio/parser.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/drivers/sound/libusbaudio/priv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/libusbau…
==============================================================================
--- trunk/reactos/lib/drivers/sound/libusbaudio/priv.h (added)
+++ trunk/reactos/lib/drivers/sound/libusbaudio/priv.h [iso-8859-1] Fri Dec 28 19:38:10
2012
@@ -1,0 +1,182 @@
+#pragma once
+
+#include <pseh/pseh2.h>
+#include <ntddk.h>
+
+#include <windef.h>
+#define NOBITMAP
+#include <mmreg.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include <mmreg.h>
+#include <mmsystem.h>
+#include "Usb100.h"
+#include <debug.h>
+
+#include "libusbaudio.h"
+
+#define USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE (0x24)
+#define USB_AUDIO_STREAMING_INTERFACE_INTERFACE_DESCRIPTOR_TYPE (0x24)
+
+#define USB_AUDIO_INPUT_TERMINAL (0x02)
+#define USB_AUDIO_OUTPUT_TERMINAL (0x03)
+
+/* Universal Serial Bus Device Class Definition for Terminal Types Section A 1.1 */
+#define USB_AUDIO_PCM_DATA_FORMAT (0x01)
+#define USB_AUDIO_PCM8_DATA_FORMAT (0x02)
+#define USB_AUDIO_IEEE_FLOAT_DATA_FORMAT (0x03)
+#define USB_AUDIO_ALAW_DATA_FORMAT (0x04)
+#define USB_AUDIO_MULAW_DATA_FORMAT (0x05)
+
+/* Universal Serial Bus Device Class Definition for Terminal Types Section A 1.1 */
+#define USB_AUDIO_DATA_FORMAT_TYPE_1 (0x01)
+#define USB_AUDIO_DATA_FORMAT_TYPE_2 (0x02)
+#define USB_AUDIO_DATA_FORMAT_TYPE_3 (0x03)
+
+
+
+/* Universal Serial Bus Device Class Definition for Terminal Types Section 2.2 */
+#define USB_AUDIO_STREAMING_TERMINAL_TYPE (0x0101)
+
+#define USB_AUDIO_MICROPHONE_TERMINAL_TYPE (0x0201)
+#define USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE (0x0202)
+#define USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE (0x0203)
+#define USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE (0x0204)
+#define USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE (0x0205)
+#define USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE (0x0206)
+
+#define USB_AUDIO_SPEAKER_TERMINAL_TYPE (0x0301)
+#define USB_HEADPHONES_SPEAKER_TERMINAL_TYPE (0x0302)
+#define USB_AUDIO_HMDA_TERMINAL_TYPE (0x0303)
+#define USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE (0x0304)
+#define USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE (0x0305)
+#define USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE (0x0306)
+#define USB_AUDIO_SUBWOOFER_TERMINAL_TYPE (0x0307)
+#define USB_AUDIO_UNDEFINED_TERMINAL_TYPE (0xFFFF)
+
+#define HTONS(x) ( ( (((unsigned short)(x)) >>8) & 0xff) | \
+ ((((unsigned short)(x)) & 0xff)<<8) )
+
+#include <pshpack1.h>
+
+typedef struct
+{
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR bDescriptorSubtype;
+ UCHAR bTerminalID;
+ USHORT wTerminalType;
+ UCHAR bAssocTerminal;
+ UCHAR bSourceID;
+ UCHAR iTerminal;
+}USB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR,
*PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR;
+
+
+typedef struct
+{
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR bDescriptorSubtype;
+ UCHAR bTerminalID;
+ USHORT wTerminalType;
+ UCHAR bAssocTerminal;
+ UCHAR bNrChannels;
+ USHORT wChannelConfig;
+ UCHAR iChannelNames;
+ UCHAR iTerminal;
+}USB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR,
*PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR;
+
+typedef struct
+{
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR bDescriptorSubtype;
+ UCHAR bTerminalLink;
+ UCHAR bDelay;
+ USHORT wFormatTag;
+}USB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR, *PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR;
+C_ASSERT(sizeof(USB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR) == 0x07);
+
+typedef struct
+{
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR bDescriptorSubtype;
+ UCHAR bFormatType;
+ UCHAR bNrChannels;
+ UCHAR bSubframeSize;
+ UCHAR bBitResolution;
+ UCHAR bSamFreqType;
+ UCHAR tSamFreq[3];
+}USB_AUDIO_STREAMING_FORMAT_TYPE_1, *PUSB_AUDIO_STREAMING_FORMAT_TYPE_1;
+C_ASSERT(sizeof(USB_AUDIO_STREAMING_FORMAT_TYPE_1) == 0x0B);
+
+/* format.c */
+
+USBAUDIO_STATUS
+UsbAudio_AssignDataRanges(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorSize,
+ IN PKSFILTER_DESCRIPTOR FilterDescriptor,
+ IN PUSB_COMMON_DESCRIPTOR * InterfaceDescriptors,
+ IN ULONG InterfaceCount,
+ IN ULONG InterfaceIndex,
+ IN PULONG TerminalIds);
+
+
+/* parser.c */
+
+USBAUDIO_STATUS
+UsbAudio_CountInterfaceDescriptors(
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ OUT PULONG DescriptorCount);
+
+USBAUDIO_STATUS
+UsbAudio_CreateInterfaceDescriptorsArray(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ IN ULONG ArrayLength,
+ OUT PUSB_COMMON_DESCRIPTOR ** Array);
+
+ULONG
+UsbAudio_GetAudioControlInterfaceIndex(
+ IN PUSB_COMMON_DESCRIPTOR * InterfaceDescriptors,
+ IN ULONG DescriptorCount);
+
+USBAUDIO_STATUS
+UsbAudio_CountAudioDescriptors(
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ IN PUSB_COMMON_DESCRIPTOR * InterfaceDescriptors,
+ IN ULONG InterfaceDescriptorCount,
+ IN ULONG InterfaceDescriptorIndex,
+ OUT PULONG DescriptorCount);
+
+USBAUDIO_STATUS
+UsbAudio_CreateAudioDescriptorArray(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN PUCHAR ConfigurationDescriptor,
+ IN ULONG ConfigurationDescriptorLength,
+ IN PUSB_COMMON_DESCRIPTOR * InterfaceDescriptors,
+ IN ULONG InterfaceDescriptorCount,
+ IN ULONG InterfaceDescriptorIndex,
+ IN ULONG ArrayLength,
+ OUT PUSB_COMMON_DESCRIPTOR ** Array);
+
+USBAUDIO_STATUS
+UsbAudio_AssignTerminalIds(
+ IN PUSBAUDIO_CONTEXT Context,
+ IN ULONG TerminalIdsLength,
+ IN PUSB_COMMON_DESCRIPTOR * TerminalIds,
+ OUT PULONG PinArray,
+ OUT PULONG PinArrayCount);
+
+PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
+UsbAudio_GetTerminalDescriptorById(
+ IN PUSB_COMMON_DESCRIPTOR *Descriptors,
+ IN ULONG DescriptorCount,
+ IN ULONG TerminalId);
+
Propchange: trunk/reactos/lib/drivers/sound/libusbaudio/priv.h
------------------------------------------------------------------------------
svn:eol-style = native