2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: lib/drivers/sound/libusbaudio/format.c
5 * PURPOSE: USB AUDIO Parser
6 * PROGRAMMER: Johannes Anderwald
11 KSDATARANGE StandardDataRange
=
18 {STATIC_KSDATAFORMAT_TYPE_AUDIO
},
19 {STATIC_KSDATAFORMAT_SUBTYPE_ANALOG
},
20 {STATIC_KSDATAFORMAT_SPECIFIER_NONE
}
24 GUID DataFormatTypeAudio
= {STATIC_KSDATAFORMAT_TYPE_AUDIO
};
25 GUID DataFormatSubTypePCM
= {STATIC_KSDATAFORMAT_SUBTYPE_PCM
};
26 GUID DataFormatSpecifierWaveFormat
= {STATIC_KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
};
29 UsbAudio_AssignDataRanges(
30 IN PUSBAUDIO_CONTEXT Context
,
31 IN PUCHAR ConfigurationDescriptor
,
32 IN ULONG ConfigurationDescriptorSize
,
33 IN PKSFILTER_DESCRIPTOR FilterDescriptor
,
34 IN PUSB_COMMON_DESCRIPTOR
* InterfaceDescriptors
,
35 IN ULONG InterfaceCount
,
36 IN ULONG InterfaceIndex
,
37 IN PULONG TerminalIds
)
40 USBAUDIO_STATUS Status
;
41 PUSB_COMMON_DESCRIPTOR
* Descriptors
;
42 PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR HeaderDescriptor
;
43 PKSDATAFORMAT_WAVEFORMATEX WaveFormat
;
44 PKSDATARANGE
*DataRanges
;
45 PKSPIN_DESCRIPTOR PinDescriptor
;
46 PUSB_AUDIO_STREAMING_FORMAT_TYPE_1 FormatType
;
48 /* count audio descriptors */
49 Status
= UsbAudio_CountAudioDescriptors(ConfigurationDescriptor
, ConfigurationDescriptorSize
, InterfaceDescriptors
, InterfaceCount
, InterfaceIndex
, &Count
);
50 if (Status
!= UA_STATUS_SUCCESS
|| Count
< 2)
53 DPRINT1("[LIBUSBAUDIO] Failed to count descriptors with %x Count %lx for InterfaceIndex %lx InterfaceCount %lx\n", Status
, Count
, InterfaceIndex
, InterfaceCount
);
54 return UA_STATUS_SUCCESS
;
57 /* create descriptor array */
58 Status
= UsbAudio_CreateAudioDescriptorArray(Context
, ConfigurationDescriptor
, ConfigurationDescriptorSize
, InterfaceDescriptors
, InterfaceCount
, InterfaceIndex
, Count
, &Descriptors
);
59 if (Status
!= UA_STATUS_SUCCESS
)
62 DPRINT1("[LIBUSBAUDIO] Failed to create audio descriptor array Count %lx Status %x\n", Count
, Status
);
63 return UA_STATUS_SUCCESS
;
67 HeaderDescriptor
= (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR
)Descriptors
[0];
68 if (!HeaderDescriptor
|| HeaderDescriptor
->bDescriptorType
!= USB_AUDIO_STREAMING_INTERFACE_INTERFACE_DESCRIPTOR_TYPE
||
69 HeaderDescriptor
->bDescriptorSubtype
!= 0x01)
71 /* header missing or mis-aligned */
72 DPRINT1("[LIBUSBAUDIO] Failed to retrieve audio header %p\n", HeaderDescriptor
);
73 return UA_STATUS_SUCCESS
;
76 /* FIXME: only PCM is supported */
77 if (HeaderDescriptor
->wFormatTag
!= WAVE_FORMAT_PCM
)
80 DPRINT1("[LIBUSBAUDIO] Only PCM is currenly supported wFormatTag %x\n", HTONS(HeaderDescriptor
->wFormatTag
));
81 return UA_STATUS_SUCCESS
;
84 /* check format descriptor */
85 FormatType
= (PUSB_AUDIO_STREAMING_FORMAT_TYPE_1
)Descriptors
[1];
86 if (!FormatType
|| FormatType
->bDescriptorType
!= USB_AUDIO_STREAMING_INTERFACE_INTERFACE_DESCRIPTOR_TYPE
||
87 FormatType
->bDescriptorSubtype
!= 0x02 || FormatType
->bFormatType
!= 0x01 || FormatType
->bSamFreqType
!= 1)
89 /* unexpected format descriptor */
90 DPRINT1("[LIBUSBAUDIO] Unexpected format descriptor %p bDescriptorType %x bDescriptorSubtype %x bFormatType %x bSamFreqType %x\n", FormatType
,
91 FormatType
->bDescriptorType
, FormatType
->bDescriptorSubtype
, FormatType
->bFormatType
, FormatType
->bSamFreqType
);
92 return UA_STATUS_SUCCESS
;
96 /* now search pin position */
97 for(Index
= 0; Index
< FilterDescriptor
->PinDescriptorsCount
; Index
++)
99 //DPRINT("bTerminalLink %x Ids %lx\n", HeaderDescriptor->bTerminalLink, TerminalIds[Index]);
100 if (HeaderDescriptor
->bTerminalLink
== TerminalIds
[Index
])
102 /* alloc wave format */
103 WaveFormat
= (PKSDATAFORMAT_WAVEFORMATEX
)Context
->Alloc(sizeof(KSDATAFORMAT_WAVEFORMATEX
));
105 return UA_STATUS_NO_MEMORY
;
107 /* init wave format */
108 WaveFormat
->WaveFormatEx
.cbSize
= sizeof(WAVEFORMATEX
);
109 WaveFormat
->WaveFormatEx
.wFormatTag
= WAVE_FORMAT_PCM
;
110 WaveFormat
->WaveFormatEx
.nChannels
= FormatType
->bNrChannels
;
111 WaveFormat
->WaveFormatEx
.wBitsPerSample
= FormatType
->bBitResolution
;
112 WaveFormat
->WaveFormatEx
.nSamplesPerSec
= ((FormatType
->tSamFreq
[2] & 0xFF) << 16) | ((FormatType
->tSamFreq
[1] & 0xFF)<< 8) | (FormatType
->tSamFreq
[0] & 0xFF);
113 WaveFormat
->WaveFormatEx
.nBlockAlign
= (WaveFormat
->WaveFormatEx
.nChannels
* WaveFormat
->WaveFormatEx
.wBitsPerSample
) / 8;
114 WaveFormat
->WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->WaveFormatEx
.nSamplesPerSec
* WaveFormat
->WaveFormatEx
.nBlockAlign
;
116 /* FIXME apply padding */
117 WaveFormat
->DataFormat
.FormatSize
= sizeof(KSDATAFORMAT_WAVEFORMATEX
);
118 Context
->Copy(&WaveFormat
->DataFormat
.MajorFormat
, &DataFormatTypeAudio
, sizeof(GUID
));
119 Context
->Copy(&WaveFormat
->DataFormat
.SubFormat
, &DataFormatSubTypePCM
, sizeof(GUID
));
120 Context
->Copy(&WaveFormat
->DataFormat
.Specifier
, &DataFormatSpecifierWaveFormat
, sizeof(GUID
));
122 //C_ASSERT(sizeof(WAVEFORMATEX) + sizeof(KSDATAFORMAT) == 82);
124 /* get corresponding pin descriptor */
125 PinDescriptor
= (PKSPIN_DESCRIPTOR
)&FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
;
127 /* alloc data range */
128 DataRanges
= (PKSDATARANGE
*)Context
->Alloc(sizeof(PKSDATARANGE
) * (PinDescriptor
->DataRangesCount
+1));
131 Context
->Free(WaveFormat
);
132 return UA_STATUS_NO_MEMORY
;
135 if (PinDescriptor
->DataRangesCount
)
138 Context
->Copy(DataRanges
, (PVOID
)PinDescriptor
->DataRanges
, sizeof(PKSDATARANGE
) * PinDescriptor
->DataRangesCount
);
141 Context
->Free((PVOID
)PinDescriptor
->DataRanges
);
144 /* assign new range */
145 PinDescriptor
->DataRanges
= DataRanges
;
146 DataRanges
[PinDescriptor
->DataRangesCount
] = (PKSDATARANGE
)WaveFormat
;
147 PinDescriptor
->DataRangesCount
++;
148 return UA_STATUS_SUCCESS
;
152 return UA_STATUS_SUCCESS
;