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/libusbaud... ============================================================================== --- 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/libusbaud... ============================================================================== --- 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/libusbaud... ============================================================================== --- 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/libusbaud... ============================================================================== --- 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/libusbaud... ============================================================================== --- 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/libusbaud... ============================================================================== --- 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