1/*
2 *	Driver for USB Audio Device Class devices.
3 *	Copyright (c) 2009,10,12 S.Zharski <imker@gmx.li>
4 *	Distributed under the tems of the MIT license.
5 *
6 */
7
8#include "AudioStreamingInterface.h"
9#include "Settings.h"
10#include "Device.h"
11#include "audio.h"
12
13
14//
15//	Audio Stream information entities
16//
17//
18ASInterfaceDescriptor::ASInterfaceDescriptor(/*Device* device, size_t interface,*/
19					usb_as_interface_descriptor_r1*	Descriptor)
20			:
21//			_AudioFunctionEntity(device, interface),
22			fTerminalLink(0),
23			fDelay(0),
24			fFormatTag(0)
25{
26	fTerminalLink = Descriptor->terminal_link;
27	fDelay = Descriptor->delay;
28	fFormatTag = Descriptor->format_tag;
29
30	TRACE("fTerminalLink:%d\n", fTerminalLink);
31	TRACE("fDelay:%d\n", fDelay);
32	TRACE("fFormatTag:%#06x\n", fFormatTag);
33
34	// fStatus = B_OK;
35}
36
37
38ASInterfaceDescriptor::~ASInterfaceDescriptor()
39{
40
41}
42
43
44ASEndpointDescriptor::ASEndpointDescriptor(usb_endpoint_descriptor* Endpoint,
45					usb_as_cs_endpoint_descriptor* Descriptor)
46			:
47			fAttributes(0),
48			fLockDelayUnits(0),
49			fLockDelay(0),
50			fMaxPacketSize(0),
51			fEndpointAddress(0)
52{
53//	usb_audiocontrol_header_descriptor *Header
54//		= (usb_audiocontrol_header_descriptor *)Interface->generic[i];
55
56	fAttributes = Descriptor->attributes;
57	fLockDelayUnits = Descriptor->lock_delay_units;
58	fLockDelay = Descriptor->lock_delay;
59
60//	usb_endpoint_descriptor* endpoint = Interface->endpoint[0]->descr;
61	fEndpointAddress = Endpoint->endpoint_address;
62	fMaxPacketSize = Endpoint->max_packet_size;
63
64	TRACE("fAttributes:%d\n", fAttributes);
65	TRACE("fLockDelayUnits:%d\n", fLockDelayUnits);
66	TRACE("fLockDelay:%d\n", fLockDelay);
67	TRACE("fMaxPacketSize:%d\n", fMaxPacketSize);
68	TRACE("fEndpointAddress:%#02x\n", fEndpointAddress);
69}
70
71
72ASEndpointDescriptor::~ASEndpointDescriptor()
73{
74}
75
76
77_ASFormatDescriptor::_ASFormatDescriptor(usb_type_I_format_descriptor* Descriptor)
78			:
79			/*_AudioFunctionEntity(device, interface)*/
80			fFormatType(UAF_FORMAT_TYPE_UNDEFINED)
81{
82	fFormatType = Descriptor->format_type;
83}
84
85
86_ASFormatDescriptor::~_ASFormatDescriptor()
87{
88}
89
90
91uint32
92_ASFormatDescriptor::GetSamFreq(uint8* freq)
93{
94	return freq[0] | freq[1] << 8 | freq[2] << 16;
95}
96
97
98TypeIFormatDescriptor::TypeIFormatDescriptor(/*Device* device, size_t interface,*/
99					usb_type_I_format_descriptor* Descriptor)
100			:
101			_ASFormatDescriptor(Descriptor),
102			fNumChannels(0),
103			fSubframeSize(0),
104			fBitResolution(0),
105			fSampleFrequencyType(0)
106{
107	/*fStatus =*/ Init(Descriptor);
108}
109
110
111TypeIFormatDescriptor::~TypeIFormatDescriptor()
112{
113}
114
115
116status_t
117TypeIFormatDescriptor::Init(usb_type_I_format_descriptor* Descriptor)
118{
119	fNumChannels = Descriptor->nr_channels;
120	fSubframeSize = Descriptor->subframe_size;
121	fBitResolution = Descriptor->bit_resolution;
122	fSampleFrequencyType = Descriptor->sam_freq_type;
123
124	if (fSampleFrequencyType == 0) {
125		fSampleFrequencies.PushBack(
126				GetSamFreq(Descriptor->sf.cont.lower_sam_freq));
127		fSampleFrequencies.PushBack(
128				GetSamFreq(Descriptor->sf.cont.upper_sam_freq));
129	} else {
130		for (size_t i = 0; i < fSampleFrequencyType; i++) {
131			fSampleFrequencies.PushBack(
132				GetSamFreq(Descriptor->sf.discr.sam_freq[i]));
133		}
134	}
135
136	TRACE("fNumChannels:%d\n", fNumChannels);
137	TRACE("fSubframeSize:%d\n", fSubframeSize);
138	TRACE("fBitResolution:%d\n", fBitResolution);
139	TRACE("fSampleFrequencyType:%d\n", fSampleFrequencyType);
140
141	for (int32 i = 0; i < fSampleFrequencies.Count(); i++) {
142		TRACE("Frequency #%d: %d\n", i, fSampleFrequencies[i]);
143	}
144
145	return B_OK;
146}
147
148
149TypeIIFormatDescriptor::TypeIIFormatDescriptor(/*Device* device, size_t interface,*/
150					usb_type_II_format_descriptor* Descriptor)
151			:
152			_ASFormatDescriptor((usb_type_I_format_descriptor*)Descriptor),
153			fMaxBitRate(0),
154			fSamplesPerFrame(0),
155			fSampleFrequencyType(0),
156			fSampleFrequencies(0)
157{
158}
159
160
161TypeIIFormatDescriptor::~TypeIIFormatDescriptor()
162{
163}
164
165
166TypeIIIFormatDescriptor::TypeIIIFormatDescriptor(/*Device* device, size_t interface,*/
167					usb_type_III_format_descriptor* Descriptor)
168			:
169			TypeIFormatDescriptor(/*device, interface, */
170			(usb_type_I_format_descriptor*) Descriptor)
171{
172
173}
174
175
176TypeIIIFormatDescriptor::~TypeIIIFormatDescriptor()
177{
178}
179
180
181AudioStreamAlternate::AudioStreamAlternate(size_t alternate,
182					ASInterfaceDescriptor* interface,
183					ASEndpointDescriptor* endpoint,
184					_ASFormatDescriptor* format)
185			:
186			fAlternate(alternate),
187			fInterface(interface),
188			fEndpoint(endpoint),
189			fFormat(format)
190{
191}
192
193
194AudioStreamAlternate::~AudioStreamAlternate()
195{
196	delete fInterface;
197	delete fEndpoint;
198	delete fFormat;
199}
200
201
202AudioStreamingInterface::AudioStreamingInterface(
203					AudioControlInterface*	controlInterface,
204					size_t interface, usb_interface_list *List)
205			:
206			fInterface(interface),
207			fControlInterface(controlInterface),
208			fIsInput(false),
209			fActiveAlternate(0)
210{
211	TRACE_ALWAYS("if[%d]:alt_count:%d\n", interface, List->alt_count);
212
213	for (size_t alt = 0; alt < List->alt_count; alt++) {
214		ASInterfaceDescriptor*	ASInterface	= NULL;
215		ASEndpointDescriptor*	ASEndpoint	= NULL;
216		_ASFormatDescriptor*	ASFormat	= NULL;
217
218		usb_interface_info *Interface = &List->alt[alt];
219
220		TRACE_ALWAYS("if[%d]:alt[%d]:descrs_count:%d\n",
221									interface, alt, Interface->generic_count);
222		for (size_t i = 0; i < Interface->generic_count; i++) {
223			usb_audiocontrol_header_descriptor *Header
224				= (usb_audiocontrol_header_descriptor *)Interface->generic[i];
225
226			if (Header->descriptor_type == AC_CS_INTERFACE) {
227				switch(Header->descriptor_subtype) {
228					case UAS_AS_GENERAL:
229						if (ASInterface == 0) {
230							ASInterface = new ASInterfaceDescriptor(
231									/*this, interface, */
232									(usb_as_interface_descriptor_r1*) Header);
233						} else
234							TRACE_ALWAYS("Duplicate AStream interface ignored.\n");
235						break;
236					case UAS_FORMAT_TYPE:
237						if (ASFormat == 0) {
238							ASFormat = new TypeIFormatDescriptor(
239										(usb_type_I_format_descriptor*) Header);
240						} else
241							TRACE_ALWAYS("Duplicate AStream format ignored.\n");
242						break;
243					default:
244						TRACE_ALWAYS("Ignore AStream descr subtype %#04x\n",
245										Header->descriptor_subtype);
246						break;
247				}
248				continue;
249			}
250
251			if (Header->descriptor_type == AC_CS_ENDPOINT) {
252				if (ASEndpoint == 0) {
253					usb_endpoint_descriptor* Endpoint
254							= Interface->endpoint[0].descr;
255					ASEndpoint = new ASEndpointDescriptor(Endpoint,
256							(usb_as_cs_endpoint_descriptor*)Header);
257				} else
258					TRACE_ALWAYS("Duplicate AStream endpoint ignored.\n");
259				continue;
260			}
261
262			TRACE_ALWAYS("Ignore Audio Stream of "
263				"unknown descriptor type %#04x.\n",	Header->descriptor_type);
264		}
265
266		fAlternates.Add(new AudioStreamAlternate(alt, ASInterface,
267							ASEndpoint, ASFormat));
268	}
269}
270
271
272AudioStreamingInterface::~AudioStreamingInterface()
273{
274		// alternates of the streams
275//		StreamAlternatesVector	fAlternates;
276//		size_t				fActiveAlternate;
277	// we own stream header objects too, so free them
278	for (StreamAlternatesIterator I = fAlternates.Begin();
279								I != fAlternates.End(); I++) {
280		delete *I;
281	}
282	fAlternates.MakeEmpty();
283}
284
285
286uint8
287AudioStreamingInterface::TerminalLink()
288{
289	if (fAlternates[fActiveAlternate]->Interface() != 0) {
290		return fAlternates[fActiveAlternate]->Interface()->fTerminalLink;
291	}
292
293	return 0;
294}
295
296
297AudioChannelCluster*
298AudioStreamingInterface::ChannelCluster()
299{
300	_AudioControl* control = fControlInterface->Find(TerminalLink());
301	if (control == 0) {
302		TRACE_ALWAYS("Control was not found for terminal id:%d.\n",
303			TerminalLink());
304		return NULL;
305	}
306
307	return control->OutCluster();
308}
309
310
311/*
312ASInterfaceDescriptor*
313Stream::ASInterface()
314{
315	return fAlternates[fActiveAlternate]->Interface();
316}
317
318
319_ASFormatDescriptor*
320Stream::ASFormat()
321{
322	return fAlternates[fActiveAlternate]->Format();
323} */
324
325void
326AudioStreamingInterface::GetFormatsAndRates(multi_description *Description)
327{
328	// TODO: fIsInput ??????
329	Description->interface_flags
330		|= fIsInput ? B_MULTI_INTERFACE_RECORD : B_MULTI_INTERFACE_PLAYBACK;
331
332	uint32 rates = 0;
333	uint32 formats = 0;
334
335	TypeIFormatDescriptor* format
336		= static_cast<TypeIFormatDescriptor*>(
337				fAlternates[fActiveAlternate]->Format());
338
339	if (format == NULL || fAlternates[fActiveAlternate]->Interface() == NULL) {
340		TRACE_ALWAYS("Ignore alternate %d due format "
341				"%#08x or interface %#08x null.\n", fActiveAlternate, format,
342				fAlternates[fActiveAlternate]->Interface());
343	}
344
345	if (format->fSampleFrequencyType == 0) { // continuous frequencies
346		rates = B_SR_CVSR;
347		Description->min_cvsr_rate = float(format->fSampleFrequencies[0]);
348		Description->max_cvsr_rate = float(format->fSampleFrequencies[1]);
349	} else {
350		for (int i = 0; i < format->fSampleFrequencies.Count(); i++) {
351			switch(format->fSampleFrequencies[i]) {
352				case 8000:		rates |= B_SR_8000;		break;
353				case 11025:		rates |= B_SR_11025;	break;
354				case 12000:		rates |= B_SR_12000;	break;
355				case 16000:		rates |= B_SR_16000;	break;
356				case 22050:		rates |= B_SR_22050;	break;
357				case 24000:		rates |= B_SR_24000;	break;
358				case 32000:		rates |= B_SR_32000;	break;
359				case 44100:		rates |= B_SR_44100;	break;
360				case 48000:		rates |= B_SR_48000;	break;
361				case 64000:		rates |= B_SR_64000;	break;
362				case 88200:		rates |= B_SR_88200;	break;
363				case 96000:		rates |= B_SR_96000;	break;
364				case 176400:	rates |= B_SR_176400;	break;
365				case 192000:	rates |= B_SR_192000;	break;
366				case 384000:	rates |= B_SR_384000;	break;
367				case 1536000:	rates |= B_SR_1536000;	break;
368				default:
369					TRACE_ALWAYS("Ignore unsupported "
370						"sample rate %d for alternate %d.\n",
371						format->fSampleFrequencies[i], fActiveAlternate);
372					break;
373			}
374		}
375	}
376
377	switch (fAlternates[fActiveAlternate]->Interface()->fFormatTag) {
378		case UAF_PCM8:			formats = B_FMT_8BIT_U;	break;
379		case UAF_IEEE_FLOAT:	formats = B_FMT_FLOAT;	break;
380		case UAF_PCM:
381			switch(format->fBitResolution) {
382				case 8: formats = B_FMT_8BIT_S; break;
383				case 16: formats = B_FMT_16BIT; break;
384				case 18: formats = B_FMT_18BIT; break;
385				case 20: formats = B_FMT_20BIT; break;
386				case 24: formats = B_FMT_24BIT; break;
387				case 32: formats = B_FMT_32BIT; break;
388					break;
389				default:
390					TRACE_ALWAYS("Ignore unsupported "
391							"bit resolution %d for alternate %d.\n",
392						format->fBitResolution, fActiveAlternate);
393					break;
394			}
395			break;
396	}
397
398	if (fIsInput) {
399		Description->input_rates = rates;
400		Description->input_formats = formats;
401	} else {
402		Description->output_rates = rates;
403		Description->output_formats = formats;
404	}
405}
406
407