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