1 /* 2 * Driver for USB Audio Device Class devices. 3 * Copyright (c) 2009-13 S.Zharski <imker@gmx.li> 4 * Distributed under the tems of the MIT license. 5 * 6 */ 7 8 #include "AudioControlInterface.h" 9 10 #include <usb/USB_audio.h> 11 12 #include "Device.h" 13 #include "Driver.h" 14 #include "Settings.h" 15 16 17 // control id is encoded in following way 18 // CS CN ID IF where: 19 // CS - control selector 20 // CN - channel 21 // ID - id of this feature unit 22 // IF - interface 23 24 #define CTL_ID(_CS, _CN, _ID, _IF) \ 25 (((_CS) << 24) | ((_CN) << 16) | ((_ID) << 8) | (_IF)) 26 27 #define CS_FROM_CTLID(_ID) (0xff & ((_ID) >> 24)) 28 #define CN_FROM_CTLID(_ID) (0xff & ((_ID) >> 16)) 29 #define ID_FROM_CTLID(_ID) (0xff & ((_ID) >> 8)) 30 31 #define REQ_VALUE(_ID) (0xffff & ((_ID) >> 16)) 32 #define REQ_INDEX(_ID) (0xffff & (_ID)) 33 34 35 struct _Designation { 36 uint32 ch; 37 uint32 bus; 38 } gDesignations[AudioControlInterface::kChannels] = { 39 { B_CHANNEL_LEFT, B_CHANNEL_STEREO_BUS }, 40 { B_CHANNEL_RIGHT, B_CHANNEL_STEREO_BUS }, 41 { B_CHANNEL_CENTER, B_CHANNEL_SURROUND_BUS }, 42 { B_CHANNEL_SUB, B_CHANNEL_SURROUND_BUS }, 43 { B_CHANNEL_REARLEFT, B_CHANNEL_STEREO_BUS }, 44 { B_CHANNEL_REARRIGHT, B_CHANNEL_STEREO_BUS }, 45 { B_CHANNEL_FRONT_LEFT_CENTER, B_CHANNEL_STEREO_BUS }, 46 { B_CHANNEL_FRONT_RIGHT_CENTER, B_CHANNEL_STEREO_BUS }, 47 { B_CHANNEL_BACK_CENTER, B_CHANNEL_SURROUND_BUS }, 48 { B_CHANNEL_SIDE_LEFT, B_CHANNEL_STEREO_BUS }, 49 { B_CHANNEL_SIDE_RIGHT, B_CHANNEL_STEREO_BUS }, 50 { B_CHANNEL_TOP_CENTER, B_CHANNEL_SURROUND_BUS }, 51 { B_CHANNEL_TOP_FRONT_LEFT, B_CHANNEL_STEREO_BUS }, 52 { B_CHANNEL_TOP_FRONT_CENTER, B_CHANNEL_SURROUND_BUS }, 53 { B_CHANNEL_TOP_FRONT_RIGHT, B_CHANNEL_STEREO_BUS }, 54 { B_CHANNEL_TOP_BACK_LEFT, B_CHANNEL_STEREO_BUS }, 55 { B_CHANNEL_TOP_BACK_CENTER, B_CHANNEL_SURROUND_BUS }, 56 { B_CHANNEL_TOP_BACK_RIGHT, B_CHANNEL_STEREO_BUS } 57 }; 58 59 60 struct _MixPageCollector : public Vector<multi_mix_control> { 61 _MixPageCollector(const char* pageName) { 62 multi_mix_control page; 63 memset(&page, 0, sizeof(multi_mix_control)); 64 page.flags = B_MULTI_MIX_GROUP; 65 strlcpy(page.name, pageName, sizeof(page.name)); 66 PushBack(page); 67 } 68 }; 69 70 71 _AudioControl::_AudioControl(AudioControlInterface* interface, 72 usb_audiocontrol_header_descriptor* Header) 73 : 74 fStatus(B_NO_INIT), 75 fInterface(interface), 76 fSubType(Header->descriptor_subtype), 77 fID(0), 78 fSourceID(0), 79 fStringIndex(0) 80 { 81 } 82 83 84 _AudioControl::~_AudioControl() 85 { 86 } 87 88 89 AudioChannelCluster* 90 _AudioControl::OutCluster() 91 { 92 if (SourceID() == 0 || fInterface == NULL) 93 return NULL; 94 95 _AudioControl* control = fInterface->Find(SourceID()); 96 if (control == NULL) 97 return NULL; 98 99 return control->OutCluster(); 100 } 101 102 103 AudioChannelCluster::AudioChannelCluster() 104 : 105 fOutChannelsNumber(0), 106 fChannelsConfig(0), 107 fChannelNames(0) 108 { 109 } 110 111 112 AudioChannelCluster::~AudioChannelCluster() 113 { 114 } 115 116 117 bool 118 AudioChannelCluster::HasChannel(uint32 location) 119 { 120 return (fChannelsConfig & location) == location; 121 } 122 123 124 _Terminal::_Terminal(AudioControlInterface* interface, 125 usb_audiocontrol_header_descriptor* Header) 126 : 127 _AudioControl(interface, Header), 128 fTerminalType(0), 129 fAssociatedTerminal(0), 130 fClockSourceId(0), 131 fControlsBitmap(0) 132 { 133 } 134 135 136 _Terminal::~_Terminal() 137 { 138 } 139 140 141 const char* 142 _Terminal::Name() 143 { 144 return _GetTerminalDescription(fTerminalType); 145 } 146 147 148 bool 149 _Terminal::IsUSBIO() 150 { 151 return (fTerminalType & 0xff00) == USB_AUDIO_UNDEFINED_USB_IO; 152 } 153 154 155 const char* 156 _Terminal::_GetTerminalDescription(uint16 TerminalType) 157 { 158 static struct _pair { 159 uint16 type; 160 const char* description; 161 } termInfoPairs[] = { 162 // USB Terminal Types 163 { USB_AUDIO_UNDEFINED_USB_IO, "USB I/O" }, 164 { USB_AUDIO_STREAMING_USB_IO, "USB I/O" }, 165 { USB_AUDIO_VENDOR_USB_IO, "Vendor USB I/O" }, 166 // Input Terminal Types 167 { USB_AUDIO_UNDEFINED_IN, "Undefined Input" }, 168 { USB_AUDIO_MICROPHONE_IN, "Microphone" }, 169 { USB_AUDIO_DESKTOPMIC_IN, "Desktop Microphone" }, 170 { USB_AUDIO_PERSONALMIC_IN, "Personal Microphone" }, 171 { USB_AUDIO_OMNI_MIC_IN, "Omni-directional Mic" }, 172 { USB_AUDIO_MICS_ARRAY_IN, "Microphone Array" }, 173 { USB_AUDIO_PROC_MICS_ARRAY_IN, "Processing Mic Array" }, 174 // Output Terminal Types 175 { USB_AUDIO_UNDEFINED_OUT, "Undefined Output" }, 176 { USB_AUDIO_SPEAKER_OUT, "Speaker" }, 177 { USB_AUDIO_HEAD_PHONES_OUT, "Headphones" }, 178 { USB_AUDIO_HMD_AUDIO_OUT, "Head Mounted Disp.Audio" }, 179 { USB_AUDIO_DESKTOP_SPEAKER, "Desktop Speaker" }, 180 { USB_AUDIO_ROOM_SPEAKER, "Room Speaker" }, 181 { USB_AUDIO_COMM_SPEAKER, "Communication Speaker" }, 182 { USB_AUDIO_LFE_SPEAKER, "LFE Speaker" }, 183 // Bi-directional Terminal Types 184 { USB_AUDIO_UNDEFINED_IO, "Undefined I/O" }, 185 { USB_AUDIO_HANDSET_IO, "Handset" }, 186 { USB_AUDIO_HEADSET_IO, "Headset" }, 187 { USB_AUDIO_SPEAKER_PHONE_IO, "Speakerphone" }, 188 { USB_AUDIO_SPEAKER_PHONEES_IO, "Echo-supp Speakerphone" }, 189 { USB_AUDIO_SPEAKER_PHONEEC_IO, "Echo-cancel Speakerphone" }, 190 // Telephony Terminal Types 191 { USB_AUDIO_UNDEF_TELEPHONY_IO, "Undefined Telephony" }, 192 { USB_AUDIO_PHONE_LINE_IO, "Phone Line" }, 193 { USB_AUDIO_TELEPHONE_IO, "Telephone" }, 194 { USB_AUDIO_DOWNLINE_PHONE_IO, "Down Line Phone" }, 195 // External Terminal Types 196 { USB_AUDIO_UNDEFINEDEXT_IO, "Undefined External I/O" }, 197 { USB_AUDIO_ANALOG_CONNECTOR_IO, "Analog Connector" }, 198 { USB_AUDIO_DAINTERFACE_IO, "Digital Audio Interface" }, 199 { USB_AUDIO_LINE_CONNECTOR_IO, "Line Connector" }, 200 { USB_AUDIO_LEGACY_CONNECTOR_IO, "LegacyAudioConnector" }, 201 { USB_AUDIO_SPDIF_INTERFACE_IO, "S/PDIF Interface" }, 202 { USB_AUDIO_DA1394_STREAM_IO, "1394 DA Stream" }, 203 { USB_AUDIO_DV1394_STREAMSOUND_IO, "1394 DV Stream Soundtrack" }, 204 { USB_AUDIO_ADAT_LIGHTPIPE_IO, "Alesis DAT Stream" }, 205 { USB_AUDIO_TDIF_IO, "Tascam Digital Interface" }, 206 { USB_AUDIO_MADI_IO, "AES Multi-channel interface" }, 207 // Embedded Terminal Types 208 { USB_AUDIO_UNDEF_EMBEDDED_IO, "Undefined Embedded I/O" }, 209 { USB_AUDIO_LC_NOISE_SOURCE_OUT, "Level Calibration Noise Source" }, 210 { USB_AUDIO_EQUALIZATION_NOISE_OUT, "Equalization Noise" }, 211 { USB_AUDIO_CDPLAYER_IN, "CD Player" }, 212 { USB_AUDIO_DAT_IO, "DAT" }, 213 { USB_AUDIO_DCC_IO, "DCC" }, 214 { USB_AUDIO_MINI_DISK_IO, "Mini Disk" }, 215 { USB_AUDIO_ANALOG_TAPE_IO, "Analog Tape" }, 216 { USB_AUDIO_PHONOGRAPH_IN, "Phonograph" }, 217 { USB_AUDIO_VCR_AUDIO_IN, "VCR Audio" }, 218 { USB_AUDIO_VIDEO_DISC_AUDIO_IN, "Video Disc Audio" }, 219 { USB_AUDIO_DVD_AUDIO_IN, "DVD Audio" }, 220 { USB_AUDIO_TV_TUNER_AUDIO_IN, "TV Tuner Audio" }, 221 { USB_AUDIO_SAT_RECEIVER_AUDIO_IN, "Satellite Receiver Audio" }, 222 { USB_AUDIO_CABLE_TUNER_AUDIO_IN, "Cable Tuner Audio" }, 223 { USB_AUDIO_DSS_AUDIO_IN, "DSS Audio" }, 224 { USB_AUDIO_RADIO_RECEIVER_IN, "Radio Receiver" }, 225 { USB_AUDIO_RADIO_TRANSMITTER_IN, "Radio Transmitter" }, 226 { USB_AUDIO_MULTI_TRACK_RECORDER_IO,"Multi-track Recorder" }, 227 { USB_AUDIO_SYNTHESIZER_IO, "Synthesizer" }, 228 { USB_AUDIO_PIANO_IO, "Piano" }, 229 { USB_AUDIO_GUITAR_IO, "Guitar" }, 230 { USB_AUDIO_DRUMS_IO, "Percussion Instrument" }, 231 { USB_AUDIO_INSTRUMENT_IO, "Musical Instrument" } 232 }; 233 234 for (size_t i = 0; B_COUNT_OF(termInfoPairs); i++) 235 if (termInfoPairs[i].type == TerminalType) 236 return termInfoPairs[i].description; 237 238 TRACE(ERR, "Unknown Terminal Type: %#06x", TerminalType); 239 return "Unknown"; 240 } 241 242 243 InputTerminal::InputTerminal(AudioControlInterface* interface, 244 usb_audiocontrol_header_descriptor* Header) 245 : 246 _AudioChannelCluster<_Terminal>(interface, Header) 247 { 248 usb_audio_input_terminal_descriptor* Terminal 249 = (usb_audio_input_terminal_descriptor*) Header; 250 fID = Terminal->terminal_id; 251 fTerminalType = Terminal->terminal_type; 252 fAssociatedTerminal = Terminal->assoc_terminal; 253 254 TRACE(UAC, "Input Terminal ID:%d >>>\n", fID); 255 TRACE(UAC, "Terminal type:%s (%#06x)\n", 256 _GetTerminalDescription(fTerminalType), fTerminalType); 257 TRACE(UAC, "Assoc.terminal:%d\n", fAssociatedTerminal); 258 259 if (fInterface->SpecReleaseNumber() < 0x200) { 260 fOutChannelsNumber = Terminal->r1.num_channels; 261 fChannelsConfig = Terminal->r1.channel_config; 262 fChannelNames = Terminal->r1.channel_names; 263 fStringIndex = Terminal->r1.terminal; 264 } else { 265 fClockSourceId = Terminal->r2.clock_source_id; 266 fOutChannelsNumber = Terminal->r2.num_channels; 267 fChannelsConfig = Terminal->r2.channel_config; 268 fChannelNames = Terminal->r2.channel_names; 269 fControlsBitmap = Terminal->r2.bm_controls; 270 fStringIndex = Terminal->r2.terminal; 271 272 TRACE(UAC, "Clock Source ID:%d\n", fClockSourceId); 273 TRACE(UAC, "Controls Bitmap:%#04x\n", fControlsBitmap); 274 } 275 276 TRACE(UAC, "Out.channels num:%d\n", fOutChannelsNumber); 277 TRACE(UAC, "Channels config:%#06x\n", fChannelsConfig); 278 TRACE(UAC, "Channels names:%d\n", fChannelNames); 279 TRACE(UAC, "StringIndex:%d\n", fStringIndex); 280 281 fStatus = B_OK; 282 } 283 284 285 InputTerminal::~InputTerminal() 286 { 287 } 288 289 290 const char* 291 InputTerminal::Name() 292 { 293 if (fTerminalType == USB_AUDIO_STREAMING_USB_IO) 294 return "USB Input"; 295 return _Terminal::Name(); 296 } 297 298 299 OutputTerminal::OutputTerminal(AudioControlInterface* interface, 300 usb_audiocontrol_header_descriptor* Header) 301 : 302 _Terminal(interface, Header) 303 { 304 usb_audio_output_terminal_descriptor* Terminal 305 = (usb_audio_output_terminal_descriptor*) Header; 306 307 fID = Terminal->terminal_id; 308 fTerminalType = Terminal->terminal_type; 309 fAssociatedTerminal = Terminal->assoc_terminal; 310 fSourceID = Terminal->source_id; 311 312 TRACE(UAC, "Output Terminal ID:%d >>>\n", fID); 313 TRACE(UAC, "Terminal type:%s (%#06x)\n", 314 _GetTerminalDescription(fTerminalType), fTerminalType); 315 TRACE(UAC, "Assoc.terminal:%d\n", fAssociatedTerminal); 316 TRACE(UAC, "Source ID:%d\n", fSourceID); 317 318 if (fInterface->SpecReleaseNumber() < 0x200) { 319 fStringIndex = Terminal->r1.terminal; 320 } else { 321 fClockSourceId = Terminal->r2.clock_source_id; 322 fControlsBitmap = Terminal->r2.bm_controls; 323 fStringIndex = Terminal->r2.terminal; 324 325 TRACE(UAC, "Clock Source ID:%d\n", fClockSourceId); 326 TRACE(UAC, "Controls Bitmap:%#04x\n", fControlsBitmap); 327 } 328 329 TRACE(UAC, "StringIndex:%d\n", fStringIndex); 330 331 fStatus = B_OK; 332 } 333 334 335 OutputTerminal::~OutputTerminal() 336 { 337 } 338 339 340 const char* 341 OutputTerminal::Name() 342 { 343 if (fTerminalType == USB_AUDIO_STREAMING_USB_IO) 344 return "USB Output"; 345 return _Terminal::Name(); 346 } 347 348 349 MixerUnit::MixerUnit(AudioControlInterface* interface, 350 usb_audiocontrol_header_descriptor* Header) 351 : 352 _AudioChannelCluster<_AudioControl>(interface, Header), 353 fBmControlsR2(0) 354 { 355 usb_audio_mixer_unit_descriptor* Mixer 356 = (usb_audio_mixer_unit_descriptor*) Header; 357 358 fID = Mixer->unit_id; 359 TRACE(UAC, "Mixer ID:%d >>>\n", fID); 360 361 TRACE(UAC, "Number of input pins:%d\n", Mixer->num_input_pins); 362 for (size_t i = 0; i < Mixer->num_input_pins; i++) { 363 fInputPins.PushBack(Mixer->input_pins[i]); 364 TRACE(UAC, "Input pin #%d:%d\n", i, fInputPins[i]); 365 } 366 367 uint8* mixerControlsData = NULL; 368 uint8 mixerControlsSize = 0; 369 370 if (fInterface->SpecReleaseNumber() < 0x200) { 371 usb_audio_output_channels_descriptor_r1* OutChannels 372 = (usb_audio_output_channels_descriptor_r1*) 373 &Mixer->input_pins[Mixer->num_input_pins]; 374 375 fOutChannelsNumber = OutChannels->num_output_pins; 376 fChannelsConfig = OutChannels->channel_config; 377 fChannelNames = OutChannels->channel_names; 378 379 mixerControlsData = (uint8*) ++OutChannels; 380 mixerControlsSize = Mixer->length - 10 - Mixer->num_input_pins; 381 fStringIndex = *(mixerControlsData + mixerControlsSize); 382 383 #if 0 // TEST 384 if (fOutChannelsNumber > 2) { 385 // fOutChannelsNumber = 2; 386 // fChannelsConfig = 0x03; 387 mixerControlsData[0] = 0x80; 388 mixerControlsData[1] = 0x40; 389 mixerControlsData[2] = 0x20; 390 mixerControlsData[3] = 0x10; 391 mixerControlsData[4] = 0x08; 392 mixerControlsData[5] = 0x04; 393 mixerControlsData[6] = 0x02; 394 mixerControlsData[7] = 0x01; 395 mixerControlsData[8] = 0x80; 396 mixerControlsData[9] = 0x40; 397 mixerControlsData[10] = 0x02; 398 mixerControlsData[11] = 0x01; 399 } 400 #endif 401 402 } else { 403 usb_audio_output_channels_descriptor* OutChannels 404 = (usb_audio_output_channels_descriptor*) 405 &Mixer->input_pins[Mixer->num_input_pins]; 406 407 fOutChannelsNumber = OutChannels->num_output_pins; 408 fChannelsConfig = OutChannels->channel_config; 409 fChannelNames = OutChannels->channel_names; 410 411 mixerControlsData = (uint8*) ++OutChannels; 412 mixerControlsSize = Mixer->length - 13 - Mixer->num_input_pins; 413 fBmControlsR2 = *(mixerControlsData + mixerControlsSize); 414 fStringIndex = *(mixerControlsData + mixerControlsSize + 1); 415 416 TRACE(UAC, "Control Bitmap:%#04x\n", fBmControlsR2); 417 } 418 419 TRACE(UAC, "Out channels number:%d\n", fOutChannelsNumber); 420 TRACE(UAC, "Out channels config:%#06x\n", fChannelsConfig); 421 TRACE(UAC, "Out channels names:%d\n", fChannelNames); 422 TRACE(UAC, "Controls Size:%d\n", mixerControlsSize); 423 424 for (size_t i = 0; i < mixerControlsSize; i++) { 425 fControlsBitmap.PushBack(mixerControlsData[i]); 426 TRACE(UAC, "Controls Data[%d]:%#x\n", i, fControlsBitmap[i]); 427 } 428 429 TRACE(UAC, "StringIndex:%d\n", fStringIndex); 430 431 fStatus = B_OK; 432 } 433 434 435 MixerUnit::~MixerUnit() 436 { 437 } 438 439 440 bool 441 MixerUnit::HasProgrammableControls() 442 { 443 for (int i = 0; i < fControlsBitmap.Count(); i++) 444 if (fControlsBitmap[i] != 0) 445 return true; 446 return false; 447 } 448 449 450 bool 451 MixerUnit::IsControlProgrammable(int inChannel, int outChannel) 452 { 453 AudioChannelCluster* outCluster = OutCluster(); 454 if (outCluster == NULL) { 455 TRACE(ERR, "Output cluster is not valid.\n"); 456 return false; 457 } 458 459 bool result = false; 460 if (outChannel < outCluster->ChannelsCount()) { 461 int index = inChannel * outCluster->ChannelsCount()+ outChannel; 462 result = (fControlsBitmap[index >> 3] & (0x80 >> (index & 7))) != 0; 463 } 464 465 // TRACE(UAC, "in:%d out:%d is %s\n", 466 // inChannel, outChannel, result ? "on" : "off"); 467 return result; 468 } 469 470 471 SelectorUnit::SelectorUnit(AudioControlInterface* interface, 472 usb_audiocontrol_header_descriptor* Header) 473 : 474 _AudioControl(interface, Header), 475 fControlsBitmap(0) 476 { 477 usb_audio_selector_unit_descriptor* Selector 478 = (usb_audio_selector_unit_descriptor*) Header; 479 480 fID = Selector->unit_id; 481 TRACE(UAC, "Selector ID:%d >>>\n", fID); 482 483 TRACE(UAC, "Number of input pins:%d\n", Selector->num_input_pins); 484 for (size_t i = 0; i < Selector->num_input_pins; i++) { 485 fInputPins.PushBack(Selector->input_pins[i]); 486 TRACE(UAC, "Input pin #%d:%d\n", i, fInputPins[i]); 487 } 488 489 if (fInterface->SpecReleaseNumber() < 0x200) { 490 fStringIndex = Selector->input_pins[Selector->num_input_pins]; 491 } else { 492 fControlsBitmap = Selector->input_pins[Selector->num_input_pins]; 493 fStringIndex = Selector->input_pins[Selector->num_input_pins + 1]; 494 495 TRACE(UAC, "Controls Bitmap:%d\n", fControlsBitmap); 496 } 497 498 TRACE(UAC, "StringIndex:%d\n", fStringIndex); 499 500 fStatus = B_OK; 501 } 502 503 504 SelectorUnit::~SelectorUnit() 505 { 506 } 507 508 509 AudioChannelCluster* 510 SelectorUnit::OutCluster() 511 { 512 if (fInterface == NULL) 513 return NULL; 514 515 for (int i = 0; i < fInputPins.Count(); i++) { 516 _AudioControl* control = fInterface->Find(fInputPins[i]); 517 if (control == NULL) 518 continue; 519 // selector has the same channels number in the 520 // out cluster as anyone of his inputs 521 if (control->OutCluster() != NULL) 522 return control->OutCluster(); 523 } 524 525 return NULL; 526 } 527 528 529 FeatureUnit::FeatureUnit(AudioControlInterface* interface, 530 usb_audiocontrol_header_descriptor* Header) 531 : 532 _AudioControl(interface, Header) 533 { 534 usb_audio_feature_unit_descriptor* Feature 535 = (usb_audio_feature_unit_descriptor*) Header; 536 537 fID = Feature->unit_id; 538 TRACE(UAC, "Feature ID:%d >>>\n", fID); 539 540 fSourceID = Feature->source_id; 541 TRACE(UAC, "Source ID:%d\n", fSourceID); 542 543 uint8 controlSize = 4; 544 uint8 channelsCount = (Feature->length - 6) / controlSize; 545 uint8* ControlsBitmapPointer = (uint8*)&Feature->r2.bma_controls[0]; 546 547 if (fInterface->SpecReleaseNumber() < 0x200) { 548 controlSize = Feature->r1.control_size; 549 channelsCount = (Feature->length - 7) / Feature->r1.control_size; 550 ControlsBitmapPointer = &Feature->r1.bma_controls[0]; 551 } 552 553 TRACE(UAC, "Channel bitmap size:%d\n", controlSize); 554 TRACE(UAC, "Channels number:%d\n", channelsCount - 1); // not add master! 555 556 for (size_t i = 0; i < channelsCount; i++) { 557 uint8* controlPointer = &ControlsBitmapPointer[i* controlSize]; 558 switch(controlSize) { 559 case 1: fControlBitmaps.PushBack(*controlPointer); break; 560 case 2: fControlBitmaps.PushBack(*(uint16*)controlPointer); break; 561 case 4: fControlBitmaps.PushBack(*(uint32*)controlPointer); break; 562 default: 563 TRACE(ERR, "Feature control of unsupported size %d ignored\n", 564 controlSize); 565 continue; 566 } 567 568 NormalizeAndTraceChannel(i); 569 } 570 571 fStringIndex = ControlsBitmapPointer[channelsCount* controlSize]; 572 TRACE(UAC, "StringIndex:%d\n", fStringIndex); 573 574 fStatus = B_OK; 575 } 576 577 578 FeatureUnit::~FeatureUnit() 579 { 580 } 581 582 583 const char* 584 FeatureUnit::Name() 585 { 586 // first check if source of this FU is an input terminal 587 _AudioControl* control = fInterface->Find(fSourceID); 588 while (control != NULL) { 589 if (control->SubType() != USB_AUDIO_AC_INPUT_TERMINAL) 590 break; 591 592 // USB I/O terminal is a not good candidate to use it's name 593 if (static_cast<_Terminal*>(control)->IsUSBIO()) 594 break; 595 596 // use the name of source input terminal as name of this FU 597 return control->Name(); 598 } 599 600 // check if output of this FU is connected to output terminal 601 control = fInterface->FindOutputTerminal(fID); 602 while (control != NULL) { 603 if (control->SubType() != USB_AUDIO_AC_OUTPUT_TERMINAL) 604 break; 605 606 // USB I/O terminal is a not good candidate to use it's name 607 if (static_cast<_Terminal*>(control)->IsUSBIO()) 608 break; 609 610 // use the name of this output terminal as name of this FU 611 return control->Name(); 612 } 613 614 // otherwise get the generic name of this FU's source 615 control = fInterface->Find(fSourceID); 616 if (control != NULL && control->Name() != NULL 617 && strlen(control->Name()) > 0) 618 return control->Name(); 619 620 // I have no more ideas, have you one? 621 return "Unknown"; 622 } 623 624 625 bool 626 FeatureUnit::HasControl(int32 Channel, uint32 Control) 627 { 628 if (Channel >= fControlBitmaps.Count()) { 629 TRACE(ERR, "Out of limits error of retrieving control %#010x " 630 "for channel %d\n", Control, Channel); 631 return false; 632 } 633 634 return (Control & fControlBitmaps[Channel]) != 0; 635 } 636 637 638 void 639 FeatureUnit::NormalizeAndTraceChannel(int32 Channel) 640 { 641 if (Channel >= fControlBitmaps.Count()) { 642 TRACE(ERR, "Out of limits error of tracing channel %d\n", Channel); 643 return; 644 } 645 646 struct _RemapInfo { 647 uint32 rev1Bits; 648 uint32 rev2Bits; 649 const char* name; 650 } remapInfos[] = { 651 { BMA_CTL_MUTE_R1, BMA_CTL_MUTE, "Mute" }, 652 { BMA_CTL_VOLUME_R1, BMA_CTL_VOLUME, "Volume" }, 653 { BMA_CTL_BASS_R1, BMA_CTL_BASS, "Bass" }, 654 { BMA_CTL_MID_R1, BMA_CTL_MID, "Mid" }, 655 { BMA_CTL_TREBLE_R1, BMA_CTL_TREBLE, "Treble" }, 656 { BMA_CTL_GRAPHEQ_R1, BMA_CTL_GRAPHEQ, "Graphic Equalizer" }, 657 { BMA_CTL_AUTOGAIN_R1, BMA_CTL_AUTOGAIN, "Automatic Gain"}, 658 { BMA_CTL_DELAY_R1, BMA_CTL_DELAY, "Delay" }, 659 { BMA_CTL_BASSBOOST_R1, BMA_CTL_BASSBOOST, "Bass Boost" }, 660 { BMA_CTL_LOUDNESS_R1, BMA_CTL_LOUDNESS, "Loudness" }, 661 { 0, BMA_CTL_INPUTGAIN, "InputGain" }, 662 { 0, BMA_CTL_INPUTGAINPAD, "InputGainPad" }, 663 { 0, BMA_CTL_PHASEINVERTER, "PhaseInverter" }, 664 { 0, BMA_CTL_UNDERFLOW, "Underflow" }, 665 { 0, BMA_CTL_OVERFLOW, "Overflow" } 666 }; 667 668 if (Channel == 0) 669 TRACE(UAC, "Master channel bitmap:%#x\n", fControlBitmaps[Channel]); 670 else 671 TRACE(UAC, "Channel %d bitmap:%#x\n", Channel, fControlBitmaps[Channel]); 672 673 bool isRev1 = (fInterface->SpecReleaseNumber() < 0x200); 674 675 uint32 remappedBitmap = 0; 676 for (size_t i = 0; i < B_COUNT_OF(remapInfos); i++) { 677 uint32 bits = isRev1 ? remapInfos[i].rev1Bits : remapInfos[i].rev2Bits; 678 if ((fControlBitmaps[Channel] & bits) > 0) { 679 if (isRev1) 680 remappedBitmap |= remapInfos[i].rev2Bits; 681 TRACE(UAC, "\t%s\n", remapInfos[i].name); 682 } 683 } 684 685 if (isRev1) { 686 TRACE(UAC, "\t%#08x -> %#08x.\n", 687 fControlBitmaps[Channel], remappedBitmap); 688 fControlBitmaps[Channel] = remappedBitmap; 689 } 690 } 691 692 693 EffectUnit::EffectUnit(AudioControlInterface* interface, 694 usb_audiocontrol_header_descriptor* Header) 695 : 696 _AudioControl(interface, Header) 697 { 698 usb_audio_input_terminal_descriptor* descriptor 699 = (usb_audio_input_terminal_descriptor*) Header; 700 TRACE(UAC, "Effect Unit:%d >>>\n", descriptor->terminal_id); 701 } 702 703 704 EffectUnit::~EffectUnit() 705 { 706 } 707 708 709 ProcessingUnit::ProcessingUnit(AudioControlInterface* interface, 710 usb_audiocontrol_header_descriptor* Header) 711 : 712 _AudioChannelCluster<_AudioControl>(interface, Header), 713 fProcessType(0), 714 fControlsBitmap(0) 715 { 716 usb_audio_processing_unit_descriptor* Processing 717 = (usb_audio_processing_unit_descriptor*) Header; 718 719 fID = Processing->unit_id; 720 TRACE(UAC, "Processing ID:%d >>>\n", fID); 721 722 fProcessType = Processing->process_type; 723 TRACE(UAC, "Processing Type:%d\n", fProcessType); 724 725 TRACE(UAC, "Number of input pins:%d\n", Processing->num_input_pins); 726 for (size_t i = 0; i < Processing->num_input_pins; i++) { 727 fInputPins.PushBack(Processing->input_pins[i]); 728 TRACE(UAC, "Input pin #%d:%d\n", i, fInputPins[i]); 729 } 730 731 if (fInterface->SpecReleaseNumber() < 0x200) { 732 usb_audio_output_channels_descriptor_r1* OutChannels 733 = (usb_audio_output_channels_descriptor_r1*) 734 &Processing->input_pins[Processing->num_input_pins]; 735 736 fOutChannelsNumber = OutChannels->num_output_pins; 737 fChannelsConfig = OutChannels->channel_config; 738 fChannelNames = OutChannels->channel_names; 739 } else { 740 usb_audio_output_channels_descriptor* OutChannels 741 = (usb_audio_output_channels_descriptor*) 742 &Processing->input_pins[Processing->num_input_pins]; 743 744 fOutChannelsNumber = OutChannels->num_output_pins; 745 fChannelsConfig = OutChannels->channel_config; 746 fChannelNames = OutChannels->channel_names; 747 } 748 749 TRACE(UAC, "Out channels number:%d\n", fOutChannelsNumber); 750 TRACE(UAC, "Out channels config:%#06x\n", fChannelsConfig); 751 TRACE(UAC, "Out channels names:%d\n", fChannelNames); 752 /* 753 uint8 controlsSize = Processing->length - 10 - Processing->num_input_pins; 754 TRACE(UAC, "Controls Size:%d\n", controlsSize); 755 756 uint8* controlsData = (uint8*) ++OutChannels; 757 758 for (size_t i = 0; i < controlsSize; i++) { 759 fProgrammableControls.PushBack(controlsData[i]); 760 TRACE(UAC, "Controls Data[%d]:%#x\n", i, controlsData[i]); 761 } 762 763 fStringIndex = *(controlsData + controlsSize); 764 765 TRACE(UAC, "StringIndex:%d\n", fStringIndex); 766 */ 767 fStatus = B_OK; 768 } 769 770 771 ProcessingUnit::~ProcessingUnit() 772 { 773 } 774 775 776 ExtensionUnit::ExtensionUnit(AudioControlInterface* interface, 777 usb_audiocontrol_header_descriptor* Header) 778 : 779 _AudioChannelCluster<_AudioControl>(interface, Header), 780 fExtensionCode(0), 781 fControlsBitmap(0) 782 { 783 usb_audio_extension_unit_descriptor* Extension 784 = (usb_audio_extension_unit_descriptor*) Header; 785 786 fID = Extension->unit_id; 787 TRACE(UAC, "Extension ID:%d >>>\n", fID); 788 789 fExtensionCode = Extension->extension_code; 790 TRACE(UAC, "Extension Type:%d\n", fExtensionCode); 791 792 TRACE(UAC, "Number of input pins:%d\n", Extension->num_input_pins); 793 for (size_t i = 0; i < Extension->num_input_pins; i++) { 794 fInputPins.PushBack(Extension->input_pins[i]); 795 TRACE(UAC, "Input pin #%d:%d\n", i, fInputPins[i]); 796 } 797 798 if (fInterface->SpecReleaseNumber() < 0x200) { 799 usb_audio_output_channels_descriptor_r1* OutChannels 800 = (usb_audio_output_channels_descriptor_r1*) 801 &Extension->input_pins[Extension->num_input_pins]; 802 803 fOutChannelsNumber = OutChannels->num_output_pins; 804 fChannelsConfig = OutChannels->channel_config; 805 fChannelNames = OutChannels->channel_names; 806 } else { 807 usb_audio_output_channels_descriptor* OutChannels 808 = (usb_audio_output_channels_descriptor*) 809 &Extension->input_pins[Extension->num_input_pins]; 810 811 fOutChannelsNumber = OutChannels->num_output_pins; 812 fChannelsConfig = OutChannels->channel_config; 813 fChannelNames = OutChannels->channel_names; 814 } 815 816 TRACE(UAC, "Out channels number:%d\n", fOutChannelsNumber); 817 TRACE(UAC, "Out channels config:%#06x\n", fChannelsConfig); 818 TRACE(UAC, "Out channels names:%d\n", fChannelNames); 819 /* 820 uint8 controlsSize = Processing->length - 10 - Processing->num_input_pins; 821 TRACE(UAC, "Controls Size:%d\n", controlsSize); 822 823 uint8* controlsData = (uint8*) ++OutChannels; 824 825 for (size_t i = 0; i < controlsSize; i++) { 826 fProgrammableControls.PushBack(controlsData[i]); 827 TRACE(UAC, "Controls Data[%d]:%#x\n", i, controlsData[i]); 828 } 829 830 fStringIndex = *(controlsData + controlsSize); 831 832 TRACE(UAC, "StringIndex:%d\n", fStringIndex); 833 */ 834 fStatus = B_OK; 835 } 836 837 838 ExtensionUnit::~ExtensionUnit() 839 { 840 } 841 842 843 ClockSource::ClockSource(AudioControlInterface* interface, 844 usb_audiocontrol_header_descriptor* Header) 845 : 846 _AudioControl(interface, Header) 847 { 848 usb_audio_input_terminal_descriptor* descriptor 849 = (usb_audio_input_terminal_descriptor*) Header; 850 TRACE(UAC, "Clock Source:%d >>>\n", descriptor->terminal_id); 851 } 852 853 854 ClockSource::~ClockSource() 855 { 856 } 857 858 859 ClockSelector::ClockSelector(AudioControlInterface* interface, 860 usb_audiocontrol_header_descriptor* Header) 861 : 862 _AudioControl(interface, Header) 863 { 864 usb_audio_input_terminal_descriptor* descriptor 865 = (usb_audio_input_terminal_descriptor*) Header; 866 TRACE(UAC, "Clock Selector:%d >>>\n", descriptor->terminal_id); 867 } 868 869 870 ClockSelector::~ClockSelector() 871 { 872 } 873 874 875 ClockMultiplier::ClockMultiplier(AudioControlInterface* interface, 876 usb_audiocontrol_header_descriptor* Header) 877 : 878 _AudioControl(interface, Header) 879 { 880 usb_audio_input_terminal_descriptor* descriptor 881 = (usb_audio_input_terminal_descriptor*) Header; 882 TRACE(UAC, "Clock Multiplier:%d >>>\n", descriptor->terminal_id); 883 } 884 885 886 ClockMultiplier::~ClockMultiplier() 887 { 888 } 889 890 891 SampleRateConverter::SampleRateConverter(AudioControlInterface* interface, 892 usb_audiocontrol_header_descriptor* Header) 893 : 894 _AudioControl(interface, Header) 895 { 896 usb_audio_input_terminal_descriptor* descriptor 897 = (usb_audio_input_terminal_descriptor*) Header; 898 TRACE(UAC, "Sample Rate Converter:%d >>>\n", descriptor->terminal_id); 899 } 900 901 902 SampleRateConverter::~SampleRateConverter() 903 { 904 } 905 906 907 AudioControlInterface::AudioControlInterface(Device* device) 908 : 909 fInterface(0), 910 fStatus(B_NO_INIT), 911 fADCSpecification(0), 912 fFunctionCategory(0), 913 fControlsBitmap(0), 914 fDevice(device) 915 { 916 } 917 918 919 AudioControlInterface::~AudioControlInterface() 920 { 921 for (AudioControlsIterator I = fAudioControls.Begin(); 922 I != fAudioControls.End(); I++) 923 delete I->Value(); 924 925 fAudioControls.MakeEmpty(); 926 927 // object already freed. just purge the map 928 fOutputTerminals.MakeEmpty(); 929 930 // object already freed. just purge the map 931 fInputTerminals.MakeEmpty(); 932 } 933 934 935 status_t 936 AudioControlInterface::Init(size_t interface, usb_interface_info* Interface) 937 { 938 for (size_t i = 0; i < Interface->generic_count; i++) { 939 usb_audiocontrol_header_descriptor* Header 940 = (usb_audiocontrol_header_descriptor* )Interface->generic[i]; 941 942 if (Header->descriptor_type != USB_AUDIO_CS_INTERFACE) { 943 TRACE(ERR, "Ignore Audio Control of " 944 "unknown descriptor type %#04x.\n", Header->descriptor_type); 945 continue; 946 } 947 948 _AudioControl* control = NULL; 949 950 switch(Header->descriptor_subtype) { 951 default: 952 TRACE(ERR, "Ignore Audio Control of unknown " 953 "descriptor sub-type %#04x\n", Header->descriptor_subtype); 954 break; 955 case USB_AUDIO_AC_DESCRIPTOR_UNDEFINED: 956 TRACE(ERR, "Ignore Audio Control of undefined sub-type\n"); 957 break; 958 case USB_AUDIO_AC_HEADER: 959 InitACHeader(interface, Header); 960 break; 961 case USB_AUDIO_AC_INPUT_TERMINAL: 962 control = new(std::nothrow) InputTerminal(this, Header); 963 break; 964 case USB_AUDIO_AC_OUTPUT_TERMINAL: 965 control = new(std::nothrow) OutputTerminal(this, Header); 966 break; 967 case USB_AUDIO_AC_MIXER_UNIT: 968 control = new(std::nothrow) MixerUnit(this, Header); 969 break; 970 case USB_AUDIO_AC_SELECTOR_UNIT: 971 control = new(std::nothrow) SelectorUnit(this, Header); 972 break; 973 case USB_AUDIO_AC_FEATURE_UNIT: 974 control = new(std::nothrow) FeatureUnit(this, Header); 975 break; 976 case USB_AUDIO_AC_PROCESSING_UNIT: 977 if (SpecReleaseNumber() < 200) 978 control = new(std::nothrow) ProcessingUnit(this, Header); 979 else 980 control = new(std::nothrow) EffectUnit(this, Header); 981 break; 982 case USB_AUDIO_AC_EXTENSION_UNIT: 983 if (SpecReleaseNumber() < 200) 984 control = new(std::nothrow) ExtensionUnit(this, Header); 985 else 986 control = new(std::nothrow) ProcessingUnit(this, Header); 987 break; 988 case USB_AUDIO_AC_EXTENSION_UNIT_R2: 989 control = new(std::nothrow) ExtensionUnit(this, Header); 990 break; 991 case USB_AUDIO_AC_CLOCK_SOURCE_R2: 992 control = new(std::nothrow) ClockSource(this, Header); 993 break; 994 case USB_AUDIO_AC_CLOCK_SELECTOR_R2: 995 control = new(std::nothrow) ClockSelector(this, Header); 996 break; 997 case USB_AUDIO_AC_CLOCK_MULTIPLIER_R2: 998 control = new(std::nothrow) ClockMultiplier(this, Header); 999 break; 1000 case USB_AUDIO_AC_SAMPLE_RATE_CONVERTER_R2: 1001 control = new(std::nothrow) SampleRateConverter(this, Header); 1002 break; 1003 } 1004 1005 if (control != 0 && control->InitCheck() == B_OK) { 1006 switch(control->SubType()) { 1007 case USB_AUDIO_AC_OUTPUT_TERMINAL: 1008 fOutputTerminals.Put(control->SourceID(), control); 1009 break; 1010 case USB_AUDIO_AC_INPUT_TERMINAL: 1011 fInputTerminals.Put(control->ID(), control); 1012 break; 1013 } 1014 fAudioControls.Put(control->ID(), control); 1015 1016 } else 1017 delete control; 1018 } 1019 1020 return fStatus = B_OK; 1021 } 1022 1023 1024 _AudioControl* 1025 AudioControlInterface::Find(uint8 id) 1026 { 1027 return fAudioControls.Get(id); 1028 } 1029 1030 1031 _AudioControl* 1032 AudioControlInterface::FindOutputTerminal(uint8 id) 1033 { 1034 return fOutputTerminals.Get(id); 1035 } 1036 1037 1038 status_t 1039 AudioControlInterface::InitACHeader(size_t interface, 1040 usb_audiocontrol_header_descriptor* Header) 1041 { 1042 if (Header == NULL) 1043 return fStatus = B_NO_INIT; 1044 1045 fInterface = interface; 1046 1047 fADCSpecification = Header->bcd_release_no; 1048 TRACE(UAC, "ADCSpecification:%#06x\n", fADCSpecification); 1049 1050 if (fADCSpecification < 0x200) { 1051 TRACE(UAC, "InterfacesCount:%d\n", Header->r1.in_collection); 1052 for (size_t i = 0; i < Header->r1.in_collection; i++) { 1053 fStreams.PushBack(Header->r1.interface_numbers[i]); 1054 TRACE(UAC, "Interface[%d] number is %d\n", i, fStreams[i]); 1055 } 1056 } else { 1057 fFunctionCategory = Header->r2.function_category; 1058 fControlsBitmap = Header->r2.bm_controls; 1059 TRACE(UAC, "Function Category:%#04x\n", fFunctionCategory); 1060 TRACE(UAC, "Controls Bitmap:%#04x\n", fControlsBitmap); 1061 } 1062 1063 return B_OK; 1064 } 1065 1066 1067 uint32 1068 AudioControlInterface::GetChannelsDescription( 1069 Vector<multi_channel_info>& Channels, multi_description* Description, 1070 Vector<_AudioControl*>&Terminals) 1071 { 1072 uint32 addedChannels = 0; 1073 1074 for (int32 i = 0; i < Terminals.Count(); i++) { 1075 bool bIsInputTerminal 1076 = Terminals[i]->SubType() == USB_AUDIO_AC_INPUT_TERMINAL; 1077 1078 AudioChannelCluster* cluster = Terminals[i]->OutCluster(); 1079 if (cluster == 0 || cluster->ChannelsCount() <= 0) { 1080 TRACE(ERR, "Terminal #%d ignored due null " 1081 "channels cluster (%08x)\n", Terminals[i]->ID(), cluster); 1082 continue; 1083 } 1084 1085 uint32 channels = GetTerminalChannels(Channels, cluster, 1086 bIsInputTerminal ? B_MULTI_INPUT_CHANNEL : B_MULTI_OUTPUT_CHANNEL); 1087 1088 if (bIsInputTerminal) 1089 Description->input_channel_count += channels; 1090 else 1091 Description->output_channel_count += channels; 1092 1093 addedChannels += channels; 1094 } 1095 1096 return addedChannels; 1097 } 1098 1099 1100 uint32 1101 AudioControlInterface::GetTerminalChannels(Vector<multi_channel_info>& Channels, 1102 AudioChannelCluster* cluster, channel_kind kind, uint32 connectors) 1103 { 1104 if (cluster->ChannelsCount() < 2) { // mono channel 1105 multi_channel_info info; 1106 info.channel_id = Channels.Count(); 1107 info.kind = kind; 1108 info.designations= B_CHANNEL_MONO_BUS; 1109 info.connectors = connectors; 1110 Channels.PushBack(info); 1111 1112 return 1; 1113 } 1114 1115 uint32 startCount = Channels.Count(); 1116 1117 // Haiku multi-aduio designations have the same bits 1118 // as USB Audio 2.0 cluster spatial locations :-) 1119 for (size_t i = 0; i < kChannels; i++) { 1120 uint32 designation = 1 << i; 1121 if ((cluster->ChannelsConfig() & designation) == designation) { 1122 multi_channel_info info; 1123 info.channel_id = Channels.Count(); 1124 info.kind = kind; 1125 info.designations= gDesignations[i].ch | gDesignations[i].bus; 1126 info.connectors = connectors; 1127 Channels.PushBack(info); 1128 } 1129 } 1130 1131 return Channels.Count() - startCount; 1132 } 1133 1134 1135 uint32 1136 AudioControlInterface::GetBusChannelsDescription( 1137 Vector<multi_channel_info>& Channels, multi_description* Description) 1138 { 1139 uint32 addedChannels = 0; 1140 1141 // first iterate output channels 1142 for (AudioControlsIterator I = fOutputTerminals.Begin(); 1143 I != fOutputTerminals.End(); I++) { 1144 _AudioControl* control = I->Value(); 1145 if (static_cast<_Terminal*>(control)->IsUSBIO()) 1146 continue; 1147 1148 AudioChannelCluster* cluster = control->OutCluster(); 1149 if (cluster == 0 || cluster->ChannelsCount() <= 0) { 1150 TRACE(ERR, "Terminal #%d ignored due null " 1151 "channels cluster (%08x)\n", control->ID(), cluster); 1152 continue; 1153 } 1154 1155 uint32 channels = GetTerminalChannels(Channels, 1156 cluster, B_MULTI_OUTPUT_BUS); 1157 1158 Description->output_bus_channel_count += channels; 1159 addedChannels += channels; 1160 } 1161 1162 // input channels should follow too 1163 for (AudioControlsIterator I = fInputTerminals.Begin(); 1164 I != fInputTerminals.End(); I++) { 1165 _AudioControl* control = I->Value(); 1166 if (static_cast<_Terminal*>(control)->IsUSBIO()) 1167 continue; 1168 1169 AudioChannelCluster* cluster = control->OutCluster(); 1170 if (cluster == 0 || cluster->ChannelsCount() <= 0) { 1171 TRACE(ERR, "Terminal #%d ignored due null " 1172 "channels cluster (%08x)\n", control->ID(), cluster); 1173 continue; 1174 } 1175 1176 uint32 channels = GetTerminalChannels(Channels, 1177 cluster, B_MULTI_INPUT_BUS); 1178 1179 Description->input_bus_channel_count += channels; 1180 addedChannels += channels; 1181 } 1182 1183 return addedChannels; 1184 } 1185 1186 1187 void 1188 AudioControlInterface::_HarvestRecordFeatureUnits(_AudioControl* rootControl, 1189 AudioControlsMap& Map) 1190 { 1191 if (rootControl == 0) { 1192 TRACE(ERR, "Not processing due NULL root control.\n"); 1193 return; 1194 } 1195 1196 switch(rootControl->SubType()) { 1197 case USB_AUDIO_AC_SELECTOR_UNIT: 1198 { 1199 SelectorUnit* unit = static_cast<SelectorUnit*>(rootControl); 1200 for (int i = 0; i < unit->fInputPins.Count(); i++) 1201 _HarvestRecordFeatureUnits(Find(unit->fInputPins[i]), Map); 1202 Map.Put(rootControl->ID(), rootControl); 1203 } 1204 break; 1205 1206 case USB_AUDIO_AC_FEATURE_UNIT: 1207 Map.Put(rootControl->ID(), rootControl); 1208 break; 1209 } 1210 } 1211 1212 1213 void 1214 AudioControlInterface::_HarvestOutputFeatureUnits(_AudioControl* rootControl, 1215 AudioControlsMap& Map) 1216 { 1217 if (rootControl == 0) { 1218 TRACE(ERR, "Not processing due NULL root control.\n"); 1219 return; 1220 } 1221 1222 switch(rootControl->SubType()) { 1223 case USB_AUDIO_AC_MIXER_UNIT: 1224 { 1225 MixerUnit* unit = static_cast<MixerUnit*>(rootControl); 1226 for (int i = 0; i < unit->fInputPins.Count(); i++) 1227 _HarvestOutputFeatureUnits(Find(unit->fInputPins[i]), Map); 1228 Map.Put(rootControl->ID(), rootControl); 1229 } 1230 break; 1231 1232 case USB_AUDIO_AC_FEATURE_UNIT: 1233 Map.Put(rootControl->ID(), rootControl); 1234 break; 1235 } 1236 } 1237 1238 1239 bool 1240 AudioControlInterface::_InitGainLimits(multi_mix_control& Control) 1241 { 1242 bool canControl = false; 1243 float current = 0.; 1244 struct _GainInfo { 1245 uint8 request; 1246 int16 data; 1247 float& value; 1248 } gainInfos[] = { 1249 { USB_AUDIO_GET_CUR, 0, current }, 1250 { USB_AUDIO_GET_MIN, 0, Control.gain.min_gain }, 1251 { USB_AUDIO_GET_MAX, 0, Control.gain.max_gain }, 1252 { USB_AUDIO_GET_RES, 0, Control.gain.granularity } 1253 }; 1254 1255 Control.gain.min_gain = 0.; 1256 Control.gain.max_gain = 100.; 1257 Control.gain.granularity = 1.; 1258 1259 size_t actualLength = 0; 1260 for (size_t i = 0; i < B_COUNT_OF(gainInfos); i++) { 1261 status_t status = gUSBModule->send_request(fDevice->USBDevice(), 1262 USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_CLASS, 1263 gainInfos[i].request, REQ_VALUE(Control.id), 1264 REQ_INDEX(Control.id), sizeof(gainInfos[i].data), 1265 &gainInfos[i].data, &actualLength); 1266 1267 if (status != B_OK || actualLength != sizeof(gainInfos[i].data)) { 1268 TRACE(ERR, "Request %d (%04x:%04x) fail:%#08x; received %d of %d\n", 1269 i, REQ_VALUE(Control.id), REQ_INDEX(Control.id), status, 1270 actualLength, sizeof(gainInfos[i].data)); 1271 continue; 1272 } 1273 1274 if (i == 0) 1275 canControl = true; 1276 1277 gainInfos[i].value = static_cast<float>(gainInfos[i].data) / 256.; 1278 } 1279 1280 TRACE(ERR, "Control %s: %f dB, from %f to %f dB, step %f dB.\n", 1281 Control.name, current, Control.gain.min_gain, Control.gain.max_gain, 1282 Control.gain.granularity); 1283 return canControl; 1284 } 1285 1286 1287 uint32 1288 AudioControlInterface::_ListFeatureUnitOption(uint32 controlType, 1289 int32& index, int32 parentIndex, multi_mix_control_info* Info, 1290 FeatureUnit* unit, uint32 channel, uint32 channels) 1291 { 1292 int32 startIndex = index; 1293 uint32 id = 0; 1294 uint32 flags = 0; 1295 strind_id string = S_null; 1296 const char* name = NULL; 1297 bool initGainLimits = false; 1298 1299 switch(controlType) { 1300 case BMA_CTL_MUTE: 1301 id = USB_AUDIO_MUTE_CONTROL; 1302 flags = B_MULTI_MIX_ENABLE; 1303 string = S_MUTE; 1304 break; 1305 case BMA_CTL_VOLUME: 1306 id = USB_AUDIO_VOLUME_CONTROL; 1307 flags = B_MULTI_MIX_GAIN; 1308 string = S_GAIN; 1309 initGainLimits = true; 1310 break; 1311 case BMA_CTL_AUTOGAIN: 1312 id = USB_AUDIO_AUTOMATIC_GAIN_CONTROL; 1313 flags = B_MULTI_MIX_ENABLE; 1314 name = "Auto Gain"; 1315 break; 1316 default: 1317 TRACE(ERR, "Unsupported type %#08x ignored.\n", controlType); 1318 return 0; 1319 } 1320 1321 multi_mix_control* Controls = Info->controls; 1322 1323 if (unit->HasControl(channel, controlType)) { 1324 uint32 masterIndex = CTL_ID(id, channel, unit->ID(), fInterface); 1325 Controls[index].id = masterIndex; 1326 Controls[index].flags = flags; 1327 Controls[index].parent = parentIndex; 1328 Controls[index].string = string; 1329 if (name != NULL) 1330 strlcpy(Controls[index].name, name, sizeof(Controls[index].name)); 1331 if (initGainLimits) 1332 _InitGainLimits(Controls[index]); 1333 1334 index++; 1335 1336 if (channels == 2) { 1337 Controls[index].id = CTL_ID(id, channel + 1, unit->ID(), fInterface); 1338 Controls[index].flags = flags; 1339 Controls[index].parent = parentIndex; 1340 Controls[index].master = masterIndex; 1341 Controls[index].string = string; 1342 if (name != NULL) 1343 strlcpy(Controls[index].name, name, sizeof(Controls[index].name)); 1344 if (initGainLimits) 1345 _InitGainLimits(Controls[index]); 1346 index++; 1347 } 1348 } 1349 1350 return index - startIndex; 1351 } 1352 1353 1354 int32 1355 AudioControlInterface::_ListFeatureUnitControl(int32& index, int32 parentIndex, 1356 multi_mix_control_info* Info, _AudioControl* control) 1357 { 1358 FeatureUnit* unit = static_cast<FeatureUnit*>(control); 1359 if (unit == 0) { 1360 TRACE(ERR, "Feature Unit for null control ignored.\n"); 1361 return 0; 1362 } 1363 1364 if (index + 4 > Info->control_count) { 1365 TRACE(ERR, "Could not list feature control group." 1366 " Limit %d of %d has been reached.\n", 1367 index, Info->control_count); 1368 return 0; 1369 } 1370 1371 AudioChannelCluster* cluster = unit->OutCluster(); 1372 if (cluster == 0) { 1373 TRACE(ERR, "Control %s with null cluster ignored.\n", unit->Name()); 1374 return 0; 1375 } 1376 1377 struct _ChannelInfo { 1378 const char* Name; 1379 uint8 channels; 1380 uint32 Mask; 1381 } channelInfos[] = { 1382 { "", 1, 0 }, // Master channel entry - no bitmask 1383 { "", 2, B_CHANNEL_LEFT | B_CHANNEL_RIGHT }, 1384 { "Left", 1, B_CHANNEL_LEFT }, 1385 { "Right", 1, B_CHANNEL_RIGHT }, 1386 { "Center", 1, B_CHANNEL_CENTER }, 1387 { "L.F.E.", 1, B_CHANNEL_SUB }, 1388 { "Back", 2, B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT }, 1389 { "Back Left", 1, B_CHANNEL_REARLEFT }, 1390 { "Back Right", 1, B_CHANNEL_REARRIGHT }, 1391 { "Front of Center", 2, B_CHANNEL_FRONT_LEFT_CENTER 1392 | B_CHANNEL_FRONT_RIGHT_CENTER }, 1393 { "Front Left of Center", 1, B_CHANNEL_FRONT_LEFT_CENTER }, 1394 { "Front Right of Center", 1, B_CHANNEL_FRONT_RIGHT_CENTER }, 1395 { "Back Center", 1, B_CHANNEL_BACK_CENTER }, 1396 { "Side", 2, B_CHANNEL_SIDE_LEFT | B_CHANNEL_SIDE_RIGHT }, 1397 { "Side Left", 1, B_CHANNEL_SIDE_LEFT }, 1398 { "Side Right", 1, B_CHANNEL_SIDE_RIGHT }, 1399 { "Top Center", 1, B_CHANNEL_TOP_CENTER }, 1400 { "Top Front Left", 1, B_CHANNEL_TOP_FRONT_LEFT }, 1401 { "Top Front Center", 1, B_CHANNEL_TOP_FRONT_CENTER }, 1402 { "Top Front Right", 1, B_CHANNEL_TOP_FRONT_RIGHT }, 1403 { "Top Back Left", 1, B_CHANNEL_TOP_BACK_LEFT }, 1404 { "Top Back Center", 1, B_CHANNEL_TOP_BACK_CENTER }, 1405 { "Top Back Right", 1, B_CHANNEL_TOP_BACK_RIGHT } 1406 }; 1407 1408 multi_mix_control* Controls = Info->controls; 1409 1410 uint32 channelsConfig = cluster->ChannelsConfig(); 1411 int32 groupIndex = 0; 1412 int32 channel = 0; 1413 int32 masterIndex = 0; // in case master channel has no volume 1414 // control - add following "L+R" channels into it 1415 1416 for (size_t i = 0; i < B_COUNT_OF(channelInfos); i++) { 1417 if ((channelsConfig & channelInfos[i].Mask) != channelInfos[i].Mask) { 1418 // ignore non-listed and possibly non-paired stereo channels. 1419 // note that master channel with zero mask pass this check! ;-) 1420 continue; 1421 } 1422 1423 if (masterIndex == 0) { 1424 groupIndex = index; 1425 Controls[index].id = groupIndex; 1426 Controls[index].flags = B_MULTI_MIX_GROUP; 1427 Controls[index].parent = parentIndex; 1428 snprintf(Controls[index].name, sizeof(Controls[index].name), 1429 "%s %s", unit->Name(), channelInfos[i].Name); 1430 index++; 1431 } else { 1432 groupIndex = masterIndex; 1433 masterIndex = 0; 1434 } 1435 1436 // First list possible Mute controls 1437 _ListFeatureUnitOption(BMA_CTL_MUTE, index, groupIndex, Info, 1438 unit, channel, channelInfos[i].channels); 1439 1440 // Gain controls may be usefull too 1441 if (_ListFeatureUnitOption(BMA_CTL_VOLUME, index, groupIndex, Info, 1442 unit, channel, channelInfos[i].channels) == 0) { 1443 masterIndex = (i == 0) ? groupIndex : 0 ; 1444 TRACE(UAC, "channel:%d set master index to %d\n", 1445 channel, masterIndex); 1446 } 1447 1448 // Auto Gain checkbox will be listed too 1449 _ListFeatureUnitOption(BMA_CTL_AUTOGAIN, index, groupIndex, Info, 1450 unit, channel, channelInfos[i].channels); 1451 1452 // Now check if the group filled with something usefull. 1453 // In case no controls were added into it - "remove" it 1454 if (Controls[index - 1].flags == B_MULTI_MIX_GROUP) { 1455 Controls[index - 1].id = 0; 1456 index--; 1457 1458 masterIndex = 0; 1459 } 1460 1461 channel += channelInfos[i].channels; 1462 1463 // remove bits for already processed channels - this prevent from 1464 // duplication of the stereo channels as "orphaned" ones and optimize 1465 // exit from this iterations after all channels are processed. 1466 channelsConfig &= ~channelInfos[i].Mask; 1467 1468 if (0 == channelsConfig) 1469 break; 1470 } 1471 1472 if (channelsConfig > 0) 1473 TRACE(ERR, "Following channels were not processed: %#08x.\n", 1474 channelsConfig); 1475 1476 // return last group index to stick possible selector unit to it. ;-) 1477 return groupIndex; 1478 } 1479 1480 1481 void 1482 AudioControlInterface::_ListSelectorUnitControl(int32& index, int32 parentGroup, 1483 multi_mix_control_info* Info, _AudioControl* control) 1484 { 1485 SelectorUnit* selector = static_cast<SelectorUnit*>(control); 1486 if (selector == 0 || selector->SubType() != USB_AUDIO_AC_SELECTOR_UNIT) 1487 return; 1488 1489 if ((index + 1 + selector->fInputPins.Count()) > Info->control_count) { 1490 TRACE(ERR, "Could not list selector control." 1491 " Limit %d of %d has been reached.\n", 1492 index, Info->control_count); 1493 return; 1494 } 1495 1496 multi_mix_control* Controls = Info->controls; 1497 1498 int32 recordMUX = CTL_ID(0, 0, selector->ID(), fInterface); 1499 Controls[index].id = recordMUX; 1500 Controls[index].flags = B_MULTI_MIX_MUX; 1501 Controls[index].parent = parentGroup; 1502 Controls[index].string = S_null; 1503 strlcpy(Controls[index].name, "Source", sizeof(Controls[index].name)); 1504 index++; 1505 1506 for (int i = 0; i < selector->fInputPins.Count(); i++) { 1507 Controls[index].id = CTL_ID(0, 1, selector->ID(), fInterface); 1508 Controls[index].flags = B_MULTI_MIX_MUX_VALUE; 1509 Controls[index].master = 0; 1510 Controls[index].string = S_null; 1511 Controls[index].parent = recordMUX; 1512 _AudioControl* control = Find(selector->fInputPins[i]); 1513 if (control != NULL) 1514 strlcpy(Controls[index].name, 1515 control->Name(), sizeof(Controls[index].name)); 1516 else 1517 snprintf(Controls[index].name, 1518 sizeof(Controls[index].name), "Input #%d", i + 1); 1519 index++; 1520 } 1521 } 1522 1523 1524 size_t 1525 AudioControlInterface::_CollectMixerUnitControls( 1526 const uint32 controlIds[kChannels][kChannels], 1527 size_t inLeft, size_t outLeft, size_t inRight, size_t outRight, 1528 const char* inputName, const char* name, 1529 Vector<multi_mix_control>& Controls) 1530 { 1531 size_t count = 0; 1532 uint32 leftId = controlIds[inLeft][outLeft]; 1533 uint32 rightId = controlIds[inRight][outRight]; 1534 1535 // TRACE(UAC, "left:%d %d: %08x; right:%d %d: %08x\n", 1536 // inLeft, outLeft, leftId, inRight, outRight, rightId); 1537 1538 multi_mix_control control; 1539 memset(&control, 0, sizeof(multi_mix_control)); 1540 snprintf(control.name, sizeof(control.name), "%s %s", inputName, name); 1541 1542 for (size_t i = 0; i < 2; i++) { 1543 if (leftId != 0 || rightId != 0) { 1544 control.flags = B_MULTI_MIX_GROUP; 1545 control.string = S_null; 1546 Controls.PushBack(control); 1547 1548 int gainControls = 0; 1549 if (leftId != 0) { 1550 control.id = leftId; 1551 control.flags = B_MULTI_MIX_GAIN; 1552 control.string = S_GAIN; 1553 if (_InitGainLimits(control)) { 1554 gainControls++; 1555 Controls.PushBack(control); 1556 } 1557 } 1558 1559 if (rightId != 0) { 1560 control.id = rightId; 1561 control.flags = B_MULTI_MIX_GAIN; 1562 control.string = S_GAIN; 1563 control.master = leftId; 1564 if (_InitGainLimits(control)) { 1565 gainControls++; 1566 Controls.PushBack(control); 1567 } 1568 } 1569 1570 // remove empty mix group 1571 if (gainControls == 0) 1572 Controls.PopBack(); 1573 else 1574 count++; 1575 } 1576 1577 // take care about surround bus 1578 if (inLeft == inRight) 1579 break; 1580 // handle possible reverse controls 1581 leftId = controlIds[inLeft][outRight]; 1582 rightId = controlIds[inRight][outLeft]; 1583 snprintf(control.name, sizeof(control.name), 1584 "%s %s (Reverse)", inputName, name); 1585 } 1586 1587 return count; 1588 } 1589 1590 1591 void 1592 AudioControlInterface::_ListMixerUnitControls(int32& index, 1593 multi_mix_control_info* Info, Vector<multi_mix_control>& controls) 1594 { 1595 multi_mix_control* Controls = Info->controls; 1596 uint32 groupParent = 0; 1597 uint32 gainParent = 0; 1598 for (Vector<multi_mix_control>::Iterator I = controls.Begin(); 1599 I != controls.End() && index < Info->control_count; I++) { 1600 memcpy(Controls + index, &*I, sizeof(multi_mix_control)); 1601 switch (I->flags) { 1602 case B_MULTI_MIX_GROUP: 1603 Controls[index].id = index; 1604 Controls[index].parent = groupParent; 1605 if (groupParent == 0) { 1606 Controls[index].id |= 0x10000; 1607 groupParent = Controls[index].id; 1608 } 1609 gainParent = Controls[index].id; 1610 break; 1611 case B_MULTI_MIX_GAIN: 1612 Controls[index].parent = gainParent; 1613 break; 1614 default: 1615 TRACE(ERR, "Control type %d ignored\n", I->flags); 1616 continue; 1617 } 1618 1619 index++; 1620 } 1621 1622 if (index == Info->control_count) 1623 TRACE(ERR, "Control count limit %d has been reached.\n", index); 1624 } 1625 1626 1627 void 1628 AudioControlInterface::_ListMixControlsForMixerUnit(int32& index, 1629 multi_mix_control_info* Info, _AudioControl* control) 1630 { 1631 MixerUnit* mixer = static_cast<MixerUnit*>(control); 1632 if (mixer == 0 || mixer->SubType() != USB_AUDIO_AC_MIXER_UNIT) 1633 return; 1634 1635 struct _ChannelPair { 1636 size_t inLeft; 1637 size_t inRight; 1638 const char* name; 1639 } channelPairs[] = { 1640 { 0, 1, "" }, 1641 { 2, 2, "Center" }, 1642 { 3, 3, "L.F.E" }, 1643 { 4, 5, "Back" }, 1644 { 6, 7, "Front of Center" }, 1645 { 8, 8, "Back Center" }, 1646 { 9, 10, "Side" }, 1647 { 11, 11, "Top Center" }, 1648 { 12, 14, "Top Front" }, 1649 { 13, 13, "Top Front Center" }, 1650 { 15, 17, "Top Back" }, 1651 { 16, 16, "Top Back Center" } 1652 }; 1653 1654 Vector<_MixPageCollector*> mixControls; 1655 1656 _MixPageCollector* genericPage = new(std::nothrow) _MixPageCollector("Mixer"); 1657 mixControls.PushBack(genericPage); 1658 1659 // page for extended in (>2) and out (>2) mixer controls 1660 size_t controlsOnExMixerPage = 0; 1661 _MixPageCollector* exMixerPage = new(std::nothrow) _MixPageCollector("Mixer"); 1662 1663 AudioChannelCluster* outCluster = mixer->OutCluster(); 1664 1665 int inOffset = 0; 1666 for (int iPin = 0; iPin < mixer->fInputPins.Count(); iPin++) { 1667 _AudioControl* control = Find(mixer->fInputPins[iPin]); 1668 AudioChannelCluster* inCluster = NULL; 1669 if (control != NULL) 1670 inCluster = control->OutCluster(); 1671 if (inCluster == NULL) { 1672 TRACE(ERR, "control %p cluster %p failed!\n", control, inCluster); 1673 break; 1674 } 1675 1676 // at first - collect programmable control ids 1677 uint32 controlIds[kChannels][kChannels] = { { 0 } }; 1678 1679 int inChannel = 0; 1680 for (size_t in = 0; in < kChannels 1681 && inChannel < inCluster->ChannelsCount(); in++) { 1682 if ((inCluster->ChannelsConfig() & (1 << in)) == 0) 1683 continue; 1684 1685 for (size_t out = 0, outChannel = 0; out < kChannels 1686 && outChannel < outCluster->ChannelsCount(); out++) { 1687 if ((outCluster->ChannelsConfig() & (1 << out)) == 0) 1688 continue; 1689 1690 if (mixer->IsControlProgrammable( 1691 inOffset + inChannel, outChannel)) { 1692 if (SpecReleaseNumber() < 0x200) 1693 // USB Audio 1.0 uses ICN/OCN for request 1694 controlIds[in][out] = CTL_ID(inOffset + inChannel + 1, 1695 outChannel + 1, mixer->ID(), fInterface); 1696 else 1697 // USB Audio 2.0 uses CS/MCN for request 1698 controlIds[in][out] = CTL_ID(USB_AUDIO_MIXER_CONTROL, 1699 (inOffset + inChannel) * outCluster->ChannelsCount() 1700 + outChannel, mixer->ID(), fInterface); 1701 } 1702 1703 outChannel++; 1704 } 1705 1706 inChannel++; 1707 } 1708 1709 inOffset += inChannel; 1710 1711 for (size_t in = 0; in < kChannels; in++) 1712 for (size_t out = 0; out < kChannels; out++) 1713 if (controlIds[in][out] != 0) 1714 TRACE(UAC, "ctrl:%08x for in %d; out %d;\n", 1715 controlIds[in][out], in, out); 1716 1717 // second step - distribute controls on 1718 // mixer pages in logical groups 1719 uint32 exChannelsMask = ~(B_CHANNEL_LEFT | B_CHANNEL_RIGHT); 1720 bool inIsEx = (inCluster->ChannelsConfig() & exChannelsMask) != 0; 1721 bool outIsEx = (outCluster->ChannelsConfig() & exChannelsMask) != 0; 1722 1723 if (!inIsEx && !outIsEx) { 1724 // heap up all mono and stereo controls into single "Mixer" page 1725 for (size_t i = 0; i < 2; i++) 1726 _CollectMixerUnitControls(controlIds, 1727 kLeftChannel, channelPairs[i].inLeft, 1728 kRightChannel, channelPairs[i].inRight, 1729 control->Name(), channelPairs[i].name, 1730 *mixControls[0]); 1731 continue; // go next input cluster 1732 } 1733 1734 if (!outIsEx) { 1735 // special case - extended (>2 channels) input cluster 1736 // connected to 2-channels output - add into generic "Mixer" page 1737 for (size_t i = 0; i < B_COUNT_OF(channelPairs); i++) 1738 _CollectMixerUnitControls(controlIds, 1739 channelPairs[i].inLeft, kLeftChannel, 1740 channelPairs[i].inRight, kRightChannel, 1741 control->Name(), channelPairs[i].name, 1742 *mixControls[0]); 1743 continue; // go next input cluster 1744 } 1745 1746 // make separate mixer pages for set of extended (>2) input 1747 // channels connected to extended (>2 channels) output 1748 for (size_t in = 0; in < B_COUNT_OF(channelPairs); in++) { 1749 for (size_t out = 0; out < B_COUNT_OF(channelPairs); out++) { 1750 char outName[sizeof(Info->controls->name)] = { 0 }; 1751 if (in == out) 1752 strlcpy(outName, channelPairs[out].name, sizeof(outName)); 1753 else 1754 snprintf(outName, sizeof(outName), "%s to %s", 1755 channelPairs[in].name, channelPairs[out].name); 1756 1757 controlsOnExMixerPage += _CollectMixerUnitControls(controlIds, 1758 channelPairs[in].inLeft, channelPairs[out].inLeft, 1759 channelPairs[in].inRight, channelPairs[out].inRight, 1760 control->Name(), outName, *exMixerPage); 1761 } 1762 1763 if (controlsOnExMixerPage >= 6) { 1764 mixControls.PushBack(exMixerPage); 1765 exMixerPage = new(std::nothrow) _MixPageCollector("Mixer"); 1766 controlsOnExMixerPage = 0; 1767 } 1768 } 1769 } 1770 1771 if (exMixerPage->Count() > 1) 1772 mixControls.PushBack(exMixerPage); 1773 else 1774 delete exMixerPage; 1775 1776 // final step - fill multiaudio controls info with 1777 // already structured pages/controls info arrays 1778 for (Vector<_MixPageCollector*>::Iterator I = mixControls.Begin(); 1779 I != mixControls.End(); I++) { 1780 Vector<multi_mix_control>* controls = *I; 1781 TRACE(UAC, "controls count: %d\n", controls->Count()); 1782 if (controls->Count() > 1) 1783 _ListMixerUnitControls(index, Info, *controls); 1784 delete controls; 1785 } 1786 } 1787 1788 1789 void 1790 AudioControlInterface::_ListMixControlsPage(int32& index, 1791 multi_mix_control_info* Info, AudioControlsMap& Map, const char* Name) 1792 { 1793 multi_mix_control* Controls = Info->controls; 1794 int32 groupIndex = index | 0x10000; 1795 Controls[index].id = groupIndex; 1796 Controls[index].flags = B_MULTI_MIX_GROUP; 1797 Controls[index].parent = 0; 1798 strlcpy(Controls[index].name, Name, sizeof(Controls[index].name)); 1799 index++; 1800 1801 int32 group = groupIndex; 1802 for (AudioControlsIterator I = Map.Begin(); I != Map.End(); I++) { 1803 TRACE(UAC, "%s control %d listed.\n", Name, I->Value()->ID()); 1804 switch(I->Value()->SubType()) { 1805 case USB_AUDIO_AC_FEATURE_UNIT: 1806 group = _ListFeatureUnitControl(index, groupIndex, 1807 Info, I->Value()); 1808 break; 1809 case USB_AUDIO_AC_SELECTOR_UNIT: 1810 _ListSelectorUnitControl(index, group, Info, I->Value()); 1811 break; 1812 default: 1813 break; 1814 } 1815 } 1816 } 1817 1818 1819 status_t 1820 AudioControlInterface::ListMixControls(multi_mix_control_info* Info) 1821 { 1822 // first harvest feature units that assigned to output terminal(s) 1823 AudioControlsMap RecordControlsMap; 1824 AudioControlsMap OutputControlsMap; 1825 1826 for (AudioControlsIterator I = fOutputTerminals.Begin(); 1827 I != fOutputTerminals.End(); I++) { 1828 _Terminal* terminal = static_cast<_Terminal*>(I->Value()); 1829 if (terminal->IsUSBIO()) 1830 _HarvestRecordFeatureUnits(terminal, RecordControlsMap); 1831 else 1832 _HarvestOutputFeatureUnits(terminal, OutputControlsMap); 1833 } 1834 1835 // separate input and output Feature units 1836 // and collect mixer units that can be controlled 1837 AudioControlsMap InputControlsMap; 1838 AudioControlsMap MixerControlsMap; 1839 1840 for (AudioControlsIterator I = fAudioControls.Begin(); 1841 I != fAudioControls.End(); I++) { 1842 _AudioControl* control = I->Value(); 1843 1844 if (control->SubType() == USB_AUDIO_AC_MIXER_UNIT) { 1845 MixerUnit* mixerControl = static_cast<MixerUnit*>(control); 1846 if (mixerControl->HasProgrammableControls()) 1847 MixerControlsMap.Put(control->ID(), control); 1848 continue; 1849 } 1850 1851 // filter out feature units 1852 if (control->SubType() != USB_AUDIO_AC_FEATURE_UNIT) 1853 continue; 1854 1855 // ignore controls that are already in the output controls maps 1856 if (RecordControlsMap.Find(control->ID()) != RecordControlsMap.End() 1857 || OutputControlsMap.Find(control->ID()) != OutputControlsMap.End()) 1858 continue; 1859 1860 _AudioControl* sourceControl = Find(control->SourceID()); 1861 if (sourceControl != 0 1862 && sourceControl->SubType() == USB_AUDIO_AC_INPUT_TERMINAL) 1863 InputControlsMap.Put(control->ID(), control); 1864 else 1865 OutputControlsMap.Put(control->ID(), control); 1866 } 1867 1868 int32 index = 0; 1869 if (InputControlsMap.Count() > 0) 1870 _ListMixControlsPage(index, Info, InputControlsMap, "Input"); 1871 1872 if (OutputControlsMap.Count() > 0) 1873 _ListMixControlsPage(index, Info, OutputControlsMap, "Output"); 1874 1875 if (RecordControlsMap.Count() > 0) 1876 _ListMixControlsPage(index, Info, RecordControlsMap, "Record"); 1877 1878 1879 for (AudioControlsIterator I = MixerControlsMap.Begin(); 1880 I != MixerControlsMap.End(); I++) 1881 _ListMixControlsForMixerUnit(index, Info, I->Value()); 1882 1883 Info->control_count = index; 1884 1885 return B_OK; 1886 } 1887 1888 1889 status_t 1890 AudioControlInterface::GetMix(multi_mix_value_info* Info) 1891 { 1892 for (int32 i = 0; i < Info->item_count; i++) { 1893 uint16 length = 0; 1894 int16 data = 0; 1895 1896 _AudioControl* control = Find(ID_FROM_CTLID(Info->values[i].id)); 1897 if (control == NULL) { 1898 TRACE(ERR, "No control found for unit id %#02x. Ignore it.\n", 1899 ID_FROM_CTLID(Info->values[i].id)); 1900 continue; 1901 } 1902 1903 switch (control->SubType()) { 1904 case USB_AUDIO_AC_FEATURE_UNIT: 1905 switch(CS_FROM_CTLID(Info->values[i].id)) { 1906 case USB_AUDIO_VOLUME_CONTROL: 1907 length = 2; 1908 break; 1909 case USB_AUDIO_MUTE_CONTROL: 1910 case USB_AUDIO_AUTOMATIC_GAIN_CONTROL: 1911 length = 1; 1912 break; 1913 default: 1914 TRACE(ERR, "Unsupported control id:%08x of type %#02x " 1915 "ignored.\n", ID_FROM_CTLID(Info->values[i].id), 1916 CS_FROM_CTLID(Info->values[i].id)); 1917 continue; 1918 } 1919 break; 1920 case USB_AUDIO_AC_SELECTOR_UNIT: 1921 length = 1; 1922 break; 1923 case USB_AUDIO_AC_MIXER_UNIT: 1924 length = 2; 1925 break; 1926 default: 1927 TRACE(ERR, "Control id:%08x of type %d is not supported\n", 1928 ID_FROM_CTLID(Info->values[i].id), control->SubType()); 1929 continue; 1930 } 1931 1932 size_t actualLength = 0; 1933 status_t status = gUSBModule->send_request(fDevice->USBDevice(), 1934 USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_CLASS, USB_AUDIO_GET_CUR, 1935 REQ_VALUE(Info->values[i].id), REQ_INDEX(Info->values[i].id), 1936 length, &data, &actualLength); 1937 1938 if (status != B_OK || actualLength != length) { 1939 TRACE(ERR, "Request (%04x:%04x) failed:%#08x; received %d of %d\n", 1940 REQ_VALUE(Info->values[i].id), REQ_INDEX(Info->values[i].id), 1941 status, actualLength, length); 1942 continue; 1943 } 1944 1945 switch (control->SubType()) { 1946 case USB_AUDIO_AC_FEATURE_UNIT: 1947 switch(CS_FROM_CTLID(Info->values[i].id)) { 1948 case USB_AUDIO_VOLUME_CONTROL: 1949 Info->values[i].gain = static_cast<float>(data) / 256.; 1950 TRACE(MIX, "Gain control %d; channel: %d; is %f dB.\n", 1951 ID_FROM_CTLID(Info->values[i].id), 1952 CN_FROM_CTLID(Info->values[i].id), 1953 Info->values[i].gain); 1954 break; 1955 case USB_AUDIO_MUTE_CONTROL: 1956 Info->values[i].enable = data > 0; 1957 TRACE(MIX, "Mute control %d; channel: %d; is %d.\n", 1958 ID_FROM_CTLID(Info->values[i].id), 1959 CN_FROM_CTLID(Info->values[i].id), 1960 Info->values[i].enable); 1961 break; 1962 case USB_AUDIO_AUTOMATIC_GAIN_CONTROL: 1963 Info->values[i].enable = data > 0; 1964 TRACE(MIX, "AGain control %d; channel: %d; is %d.\n", 1965 ID_FROM_CTLID(Info->values[i].id), 1966 CN_FROM_CTLID(Info->values[i].id), 1967 Info->values[i].enable); 1968 break; 1969 default: 1970 break; 1971 } 1972 break; 1973 case USB_AUDIO_AC_SELECTOR_UNIT: 1974 Info->values[i].mux = data - 1; 1975 TRACE(MIX, "Selector control %d; is %d.\n", 1976 ID_FROM_CTLID(Info->values[i].id), 1977 Info->values[i].mux); 1978 break; 1979 case USB_AUDIO_AC_MIXER_UNIT: 1980 Info->values[i].gain = static_cast<float>(data) / 256.; 1981 TRACE(MIX, "Mixer #%d channels in: %d; out: %d; is %f dB.\n", 1982 ID_FROM_CTLID(Info->values[i].id), 1983 CS_FROM_CTLID(Info->values[i].id), 1984 CN_FROM_CTLID(Info->values[i].id), 1985 Info->values[i].gain); 1986 break; 1987 } 1988 } 1989 1990 return B_OK; 1991 } 1992 1993 1994 status_t 1995 AudioControlInterface::SetMix(multi_mix_value_info* Info) 1996 { 1997 for (int32 i = 0; i < Info->item_count; i++) { 1998 uint16 length = 0; 1999 int16 data = 0; 2000 2001 _AudioControl* control = Find(ID_FROM_CTLID(Info->values[i].id)); 2002 if (control == NULL) { 2003 TRACE(ERR, "No control found for unit id %#02x. Ignore it.\n", 2004 ID_FROM_CTLID(Info->values[i].id)); 2005 continue; 2006 } 2007 2008 switch (control->SubType()) { 2009 case USB_AUDIO_AC_FEATURE_UNIT: 2010 switch(CS_FROM_CTLID(Info->values[i].id)) { 2011 case USB_AUDIO_VOLUME_CONTROL: 2012 data = static_cast<int16>(Info->values[i].gain * 256.); 2013 length = 2; 2014 TRACE(MIX, "Gain control %d; channel: %d; " 2015 "about to set to %f dB.\n", 2016 ID_FROM_CTLID(Info->values[i].id), 2017 CN_FROM_CTLID(Info->values[i].id), 2018 Info->values[i].gain); 2019 break; 2020 case USB_AUDIO_MUTE_CONTROL: 2021 data = (Info->values[i].enable ? 1 : 0); 2022 length = 1; 2023 TRACE(MIX, "Mute control %d; channel: %d; " 2024 "about to set to %d.\n", 2025 ID_FROM_CTLID(Info->values[i].id), 2026 CN_FROM_CTLID(Info->values[i].id), 2027 Info->values[i].enable); 2028 break; 2029 case USB_AUDIO_AUTOMATIC_GAIN_CONTROL: 2030 data = (Info->values[i].enable ? 1 : 0); 2031 length = 1; 2032 TRACE(MIX, "AGain control %d; channel: %d; " 2033 "about to set to %d.\n", 2034 ID_FROM_CTLID(Info->values[i].id), 2035 CN_FROM_CTLID(Info->values[i].id), 2036 Info->values[i].enable); 2037 break; 2038 default: 2039 TRACE(ERR, "Unsupported control id:%08x of type %#02x " 2040 "ignored.\n", ID_FROM_CTLID(Info->values[i].id), 2041 CS_FROM_CTLID(Info->values[i].id)); 2042 continue; 2043 } 2044 break; 2045 case USB_AUDIO_AC_SELECTOR_UNIT: 2046 data = Info->values[i].mux + 1; 2047 length = 1; 2048 TRACE(MIX, "Selector Control %d about to set to %d.\n", 2049 ID_FROM_CTLID(Info->values[i].id), 2050 Info->values[i].mux); 2051 break; 2052 case USB_AUDIO_AC_MIXER_UNIT: 2053 data = static_cast<int16>(Info->values[i].gain * 256.); 2054 length = 2; 2055 TRACE(MIX, "Mixer %d channels in: %d; out: %d; " 2056 "about to set to %f dB.\n", 2057 ID_FROM_CTLID(Info->values[i].id), 2058 CS_FROM_CTLID(Info->values[i].id), 2059 CN_FROM_CTLID(Info->values[i].id), 2060 Info->values[i].gain); 2061 break; 2062 default: 2063 TRACE(ERR, "Control id:%08x of type %d is not supported\n", 2064 Info->values[i].id, control->SubType()); 2065 continue; 2066 } 2067 2068 size_t actualLength = 0; 2069 status_t status = gUSBModule->send_request(fDevice->USBDevice(), 2070 USB_REQTYPE_INTERFACE_OUT | USB_REQTYPE_CLASS, USB_AUDIO_SET_CUR, 2071 REQ_VALUE(Info->values[i].id), REQ_INDEX(Info->values[i].id), 2072 length, &data, &actualLength); 2073 2074 if (status != B_OK || actualLength != length) { 2075 TRACE(ERR, "Request (%04x:%04x) failed:%#08x; send %d of %d\n", 2076 REQ_VALUE(Info->values[i].id), REQ_INDEX(Info->values[i].id), 2077 status, actualLength, length); 2078 continue; 2079 } 2080 2081 TRACE(MIX, "Value set OK\n"); 2082 } 2083 2084 return B_OK; 2085 } 2086 2087