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; i < 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, bool isForInput) 1071 { 1072 uint32 addedChannels = 0; 1073 1074 for (int32 i = 0; i < Terminals.Count(); i++) { 1075 AudioChannelCluster* cluster = Terminals[i]->OutCluster(); 1076 if (cluster == NULL || cluster->ChannelsCount() <= 0) { 1077 TRACE(ERR, "Terminal #%d ignored due null " 1078 "channels cluster (%08x)\n", Terminals[i]->ID(), cluster); 1079 continue; 1080 } 1081 1082 uint32 channels = GetTerminalChannels(Channels, cluster, 1083 isForInput ? B_MULTI_INPUT_CHANNEL : B_MULTI_OUTPUT_CHANNEL); 1084 1085 if (isForInput) 1086 Description->input_channel_count += channels; 1087 else 1088 Description->output_channel_count += channels; 1089 1090 addedChannels += channels; 1091 } 1092 1093 return addedChannels; 1094 } 1095 1096 1097 uint32 1098 AudioControlInterface::GetTerminalChannels(Vector<multi_channel_info>& Channels, 1099 AudioChannelCluster* cluster, channel_kind kind, uint32 connectors) 1100 { 1101 if (cluster->ChannelsCount() < 2) { // mono channel 1102 multi_channel_info info; 1103 info.channel_id = Channels.Count(); 1104 info.kind = kind; 1105 info.designations= B_CHANNEL_MONO_BUS; 1106 info.connectors = connectors; 1107 Channels.PushBack(info); 1108 1109 return 1; 1110 } 1111 1112 uint32 startCount = Channels.Count(); 1113 1114 // Haiku multi-aduio designations have the same bits 1115 // as USB Audio 2.0 cluster spatial locations :-) 1116 for (size_t i = 0; i < kChannels; i++) { 1117 uint32 designation = 1 << i; 1118 if ((cluster->ChannelsConfig() & designation) == designation) { 1119 multi_channel_info info; 1120 info.channel_id = Channels.Count(); 1121 info.kind = kind; 1122 info.designations= gDesignations[i].ch | gDesignations[i].bus; 1123 info.connectors = connectors; 1124 Channels.PushBack(info); 1125 } 1126 } 1127 1128 return Channels.Count() - startCount; 1129 } 1130 1131 1132 uint32 1133 AudioControlInterface::GetBusChannelsDescription( 1134 Vector<multi_channel_info>& Channels, multi_description* Description) 1135 { 1136 uint32 addedChannels = 0; 1137 1138 // first iterate output channels 1139 for (AudioControlsIterator I = fOutputTerminals.Begin(); 1140 I != fOutputTerminals.End(); I++) { 1141 _AudioControl* control = I->Value(); 1142 if (static_cast<_Terminal*>(control)->IsUSBIO()) 1143 continue; 1144 1145 AudioChannelCluster* cluster = control->OutCluster(); 1146 if (cluster == 0 || cluster->ChannelsCount() <= 0) { 1147 TRACE(ERR, "Terminal #%d ignored due null " 1148 "channels cluster (%08x)\n", control->ID(), cluster); 1149 continue; 1150 } 1151 1152 uint32 channels = GetTerminalChannels(Channels, 1153 cluster, B_MULTI_OUTPUT_BUS); 1154 1155 Description->output_bus_channel_count += channels; 1156 addedChannels += channels; 1157 } 1158 1159 // input channels should follow too 1160 for (AudioControlsIterator I = fInputTerminals.Begin(); 1161 I != fInputTerminals.End(); I++) { 1162 _AudioControl* control = I->Value(); 1163 if (static_cast<_Terminal*>(control)->IsUSBIO()) 1164 continue; 1165 1166 AudioChannelCluster* cluster = control->OutCluster(); 1167 if (cluster == NULL || cluster->ChannelsCount() <= 0) { 1168 TRACE(ERR, "Terminal #%d ignored due null " 1169 "channels cluster (%08x)\n", control->ID(), cluster); 1170 continue; 1171 } 1172 1173 uint32 channels = GetTerminalChannels(Channels, 1174 cluster, B_MULTI_INPUT_BUS); 1175 1176 Description->input_bus_channel_count += channels; 1177 addedChannels += channels; 1178 } 1179 1180 return addedChannels; 1181 } 1182 1183 1184 void 1185 AudioControlInterface::_HarvestRecordFeatureUnits(_AudioControl* rootControl, 1186 AudioControlsMap& Map) 1187 { 1188 if (rootControl == 0) { 1189 TRACE(ERR, "Not processing due NULL root control.\n"); 1190 return; 1191 } 1192 1193 switch(rootControl->SubType()) { 1194 case USB_AUDIO_AC_SELECTOR_UNIT: 1195 { 1196 SelectorUnit* unit = static_cast<SelectorUnit*>(rootControl); 1197 for (int i = 0; i < unit->fInputPins.Count(); i++) 1198 _HarvestRecordFeatureUnits(Find(unit->fInputPins[i]), Map); 1199 Map.Put(rootControl->ID(), rootControl); 1200 } 1201 break; 1202 1203 case USB_AUDIO_AC_FEATURE_UNIT: 1204 Map.Put(rootControl->ID(), rootControl); 1205 break; 1206 } 1207 } 1208 1209 1210 void 1211 AudioControlInterface::_HarvestOutputFeatureUnits(_AudioControl* rootControl, 1212 AudioControlsMap& Map) 1213 { 1214 if (rootControl == 0) { 1215 TRACE(ERR, "Not processing due NULL root control.\n"); 1216 return; 1217 } 1218 1219 switch(rootControl->SubType()) { 1220 case USB_AUDIO_AC_MIXER_UNIT: 1221 { 1222 MixerUnit* unit = static_cast<MixerUnit*>(rootControl); 1223 for (int i = 0; i < unit->fInputPins.Count(); i++) 1224 _HarvestOutputFeatureUnits(Find(unit->fInputPins[i]), Map); 1225 Map.Put(rootControl->ID(), rootControl); 1226 } 1227 break; 1228 1229 case USB_AUDIO_AC_FEATURE_UNIT: 1230 Map.Put(rootControl->ID(), rootControl); 1231 break; 1232 } 1233 } 1234 1235 1236 bool 1237 AudioControlInterface::_InitGainLimits(multi_mix_control& Control) 1238 { 1239 bool canControl = false; 1240 float current = 0.; 1241 struct _GainInfo { 1242 uint8 request; 1243 int16 data; 1244 float& value; 1245 } gainInfos[] = { 1246 { USB_AUDIO_GET_CUR, 0, current }, 1247 { USB_AUDIO_GET_MIN, 0, Control.gain.min_gain }, 1248 { USB_AUDIO_GET_MAX, 0, Control.gain.max_gain }, 1249 { USB_AUDIO_GET_RES, 0, Control.gain.granularity } 1250 }; 1251 1252 Control.gain.min_gain = 0.; 1253 Control.gain.max_gain = 100.; 1254 Control.gain.granularity = 1.; 1255 1256 size_t actualLength = 0; 1257 for (size_t i = 0; i < B_COUNT_OF(gainInfos); i++) { 1258 status_t status = gUSBModule->send_request(fDevice->USBDevice(), 1259 USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_CLASS, 1260 gainInfos[i].request, REQ_VALUE(Control.id), 1261 REQ_INDEX(Control.id), sizeof(gainInfos[i].data), 1262 &gainInfos[i].data, &actualLength); 1263 1264 if (status != B_OK || actualLength != sizeof(gainInfos[i].data)) { 1265 TRACE(ERR, "Request %d (%04x:%04x) fail:%#08x; received %d of %d\n", 1266 i, REQ_VALUE(Control.id), REQ_INDEX(Control.id), status, 1267 actualLength, sizeof(gainInfos[i].data)); 1268 continue; 1269 } 1270 1271 if (i == 0) 1272 canControl = true; 1273 1274 gainInfos[i].value = static_cast<float>(gainInfos[i].data) / 256.; 1275 } 1276 1277 TRACE(ERR, "Control %s: %f dB, from %f to %f dB, step %f dB.\n", 1278 Control.name, current, Control.gain.min_gain, Control.gain.max_gain, 1279 Control.gain.granularity); 1280 return canControl; 1281 } 1282 1283 1284 uint32 1285 AudioControlInterface::_ListFeatureUnitOption(uint32 controlType, 1286 int32& index, int32 parentIndex, multi_mix_control_info* Info, 1287 FeatureUnit* unit, uint32 channel, uint32 channels) 1288 { 1289 int32 startIndex = index; 1290 uint32 id = 0; 1291 uint32 flags = 0; 1292 strind_id string = S_null; 1293 const char* name = NULL; 1294 bool initGainLimits = false; 1295 1296 switch(controlType) { 1297 case BMA_CTL_MUTE: 1298 id = USB_AUDIO_MUTE_CONTROL; 1299 flags = B_MULTI_MIX_ENABLE; 1300 string = S_MUTE; 1301 break; 1302 case BMA_CTL_VOLUME: 1303 id = USB_AUDIO_VOLUME_CONTROL; 1304 flags = B_MULTI_MIX_GAIN; 1305 string = S_GAIN; 1306 initGainLimits = true; 1307 break; 1308 case BMA_CTL_AUTOGAIN: 1309 id = USB_AUDIO_AUTOMATIC_GAIN_CONTROL; 1310 flags = B_MULTI_MIX_ENABLE; 1311 name = "Auto Gain"; 1312 break; 1313 default: 1314 TRACE(ERR, "Unsupported type %#08x ignored.\n", controlType); 1315 return 0; 1316 } 1317 1318 multi_mix_control* Controls = Info->controls; 1319 1320 if (unit->HasControl(channel, controlType)) { 1321 uint32 masterIndex = CTL_ID(id, channel, unit->ID(), fInterface); 1322 Controls[index].id = masterIndex; 1323 Controls[index].flags = flags; 1324 Controls[index].parent = parentIndex; 1325 Controls[index].string = string; 1326 if (name != NULL) 1327 strlcpy(Controls[index].name, name, sizeof(Controls[index].name)); 1328 if (initGainLimits) 1329 _InitGainLimits(Controls[index]); 1330 1331 index++; 1332 1333 if (channels == 2) { 1334 Controls[index].id = CTL_ID(id, channel + 1, unit->ID(), fInterface); 1335 Controls[index].flags = flags; 1336 Controls[index].parent = parentIndex; 1337 Controls[index].master = masterIndex; 1338 Controls[index].string = string; 1339 if (name != NULL) 1340 strlcpy(Controls[index].name, name, sizeof(Controls[index].name)); 1341 if (initGainLimits) 1342 _InitGainLimits(Controls[index]); 1343 index++; 1344 } 1345 } 1346 1347 return index - startIndex; 1348 } 1349 1350 1351 int32 1352 AudioControlInterface::_ListFeatureUnitControl(int32& index, int32 parentIndex, 1353 multi_mix_control_info* Info, _AudioControl* control) 1354 { 1355 FeatureUnit* unit = static_cast<FeatureUnit*>(control); 1356 if (unit == 0) { 1357 TRACE(ERR, "Feature Unit for null control ignored.\n"); 1358 return 0; 1359 } 1360 1361 if (index + 4 > Info->control_count) { 1362 TRACE(ERR, "Could not list feature control group." 1363 " Limit %d of %d has been reached.\n", 1364 index, Info->control_count); 1365 return 0; 1366 } 1367 1368 AudioChannelCluster* cluster = unit->OutCluster(); 1369 if (cluster == 0) { 1370 TRACE(ERR, "Control %s with null cluster ignored.\n", unit->Name()); 1371 return 0; 1372 } 1373 1374 struct _ChannelInfo { 1375 const char* Name; 1376 uint8 channels; 1377 uint32 Mask; 1378 } channelInfos[] = { 1379 { "", 1, 0 }, // Master channel entry - no bitmask 1380 { "", 2, B_CHANNEL_LEFT | B_CHANNEL_RIGHT }, 1381 { "Left", 1, B_CHANNEL_LEFT }, 1382 { "Right", 1, B_CHANNEL_RIGHT }, 1383 { "Center", 1, B_CHANNEL_CENTER }, 1384 { "L.F.E.", 1, B_CHANNEL_SUB }, 1385 { "Back", 2, B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT }, 1386 { "Back Left", 1, B_CHANNEL_REARLEFT }, 1387 { "Back Right", 1, B_CHANNEL_REARRIGHT }, 1388 { "Front of Center", 2, B_CHANNEL_FRONT_LEFT_CENTER 1389 | B_CHANNEL_FRONT_RIGHT_CENTER }, 1390 { "Front Left of Center", 1, B_CHANNEL_FRONT_LEFT_CENTER }, 1391 { "Front Right of Center", 1, B_CHANNEL_FRONT_RIGHT_CENTER }, 1392 { "Back Center", 1, B_CHANNEL_BACK_CENTER }, 1393 { "Side", 2, B_CHANNEL_SIDE_LEFT | B_CHANNEL_SIDE_RIGHT }, 1394 { "Side Left", 1, B_CHANNEL_SIDE_LEFT }, 1395 { "Side Right", 1, B_CHANNEL_SIDE_RIGHT }, 1396 { "Top Center", 1, B_CHANNEL_TOP_CENTER }, 1397 { "Top Front Left", 1, B_CHANNEL_TOP_FRONT_LEFT }, 1398 { "Top Front Center", 1, B_CHANNEL_TOP_FRONT_CENTER }, 1399 { "Top Front Right", 1, B_CHANNEL_TOP_FRONT_RIGHT }, 1400 { "Top Back Left", 1, B_CHANNEL_TOP_BACK_LEFT }, 1401 { "Top Back Center", 1, B_CHANNEL_TOP_BACK_CENTER }, 1402 { "Top Back Right", 1, B_CHANNEL_TOP_BACK_RIGHT } 1403 }; 1404 1405 multi_mix_control* Controls = Info->controls; 1406 1407 uint32 channelsConfig = cluster->ChannelsConfig(); 1408 int32 groupIndex = 0; 1409 int32 channel = 0; 1410 int32 masterIndex = 0; // in case master channel has no volume 1411 // control - add following "L+R" channels into it 1412 1413 for (size_t i = 0; i < B_COUNT_OF(channelInfos); i++) { 1414 if ((channelsConfig & channelInfos[i].Mask) != channelInfos[i].Mask) { 1415 // ignore non-listed and possibly non-paired stereo channels. 1416 // note that master channel with zero mask pass this check! ;-) 1417 continue; 1418 } 1419 1420 if (masterIndex == 0) { 1421 groupIndex = index; 1422 Controls[index].id = groupIndex; 1423 Controls[index].flags = B_MULTI_MIX_GROUP; 1424 Controls[index].parent = parentIndex; 1425 snprintf(Controls[index].name, sizeof(Controls[index].name), 1426 "%s %s", unit->Name(), channelInfos[i].Name); 1427 index++; 1428 } else { 1429 groupIndex = masterIndex; 1430 masterIndex = 0; 1431 } 1432 1433 // First list possible Mute controls 1434 _ListFeatureUnitOption(BMA_CTL_MUTE, index, groupIndex, Info, 1435 unit, channel, channelInfos[i].channels); 1436 1437 // Gain controls may be usefull too 1438 if (_ListFeatureUnitOption(BMA_CTL_VOLUME, index, groupIndex, Info, 1439 unit, channel, channelInfos[i].channels) == 0) { 1440 masterIndex = (i == 0) ? groupIndex : 0 ; 1441 TRACE(UAC, "channel:%d set master index to %d\n", 1442 channel, masterIndex); 1443 } 1444 1445 // Auto Gain checkbox will be listed too 1446 _ListFeatureUnitOption(BMA_CTL_AUTOGAIN, index, groupIndex, Info, 1447 unit, channel, channelInfos[i].channels); 1448 1449 // Now check if the group filled with something usefull. 1450 // In case no controls were added into it - "remove" it 1451 if (Controls[index - 1].flags == B_MULTI_MIX_GROUP) { 1452 Controls[index - 1].id = 0; 1453 index--; 1454 1455 masterIndex = 0; 1456 } 1457 1458 channel += channelInfos[i].channels; 1459 1460 // remove bits for already processed channels - this prevent from 1461 // duplication of the stereo channels as "orphaned" ones and optimize 1462 // exit from this iterations after all channels are processed. 1463 channelsConfig &= ~channelInfos[i].Mask; 1464 1465 if (0 == channelsConfig) 1466 break; 1467 } 1468 1469 if (channelsConfig > 0) 1470 TRACE(ERR, "Following channels were not processed: %#08x.\n", 1471 channelsConfig); 1472 1473 // return last group index to stick possible selector unit to it. ;-) 1474 return groupIndex; 1475 } 1476 1477 1478 void 1479 AudioControlInterface::_ListSelectorUnitControl(int32& index, int32 parentGroup, 1480 multi_mix_control_info* Info, _AudioControl* control) 1481 { 1482 SelectorUnit* selector = static_cast<SelectorUnit*>(control); 1483 if (selector == 0 || selector->SubType() != USB_AUDIO_AC_SELECTOR_UNIT) 1484 return; 1485 1486 if ((index + 1 + selector->fInputPins.Count()) > Info->control_count) { 1487 TRACE(ERR, "Could not list selector control." 1488 " Limit %d of %d has been reached.\n", 1489 index, Info->control_count); 1490 return; 1491 } 1492 1493 multi_mix_control* Controls = Info->controls; 1494 1495 int32 recordMUX = CTL_ID(0, 0, selector->ID(), fInterface); 1496 Controls[index].id = recordMUX; 1497 Controls[index].flags = B_MULTI_MIX_MUX; 1498 Controls[index].parent = parentGroup; 1499 Controls[index].string = S_null; 1500 strlcpy(Controls[index].name, "Source", sizeof(Controls[index].name)); 1501 index++; 1502 1503 for (int i = 0; i < selector->fInputPins.Count(); i++) { 1504 Controls[index].id = CTL_ID(0, 1, selector->ID(), fInterface); 1505 Controls[index].flags = B_MULTI_MIX_MUX_VALUE; 1506 Controls[index].master = 0; 1507 Controls[index].string = S_null; 1508 Controls[index].parent = recordMUX; 1509 _AudioControl* control = Find(selector->fInputPins[i]); 1510 if (control != NULL) 1511 strlcpy(Controls[index].name, 1512 control->Name(), sizeof(Controls[index].name)); 1513 else 1514 snprintf(Controls[index].name, 1515 sizeof(Controls[index].name), "Input #%d", i + 1); 1516 index++; 1517 } 1518 } 1519 1520 1521 size_t 1522 AudioControlInterface::_CollectMixerUnitControls( 1523 const uint32 controlIds[kChannels][kChannels], 1524 size_t inLeft, size_t outLeft, size_t inRight, size_t outRight, 1525 const char* inputName, const char* name, 1526 Vector<multi_mix_control>& Controls) 1527 { 1528 size_t count = 0; 1529 uint32 leftId = controlIds[inLeft][outLeft]; 1530 uint32 rightId = controlIds[inRight][outRight]; 1531 1532 // TRACE(UAC, "left:%d %d: %08x; right:%d %d: %08x\n", 1533 // inLeft, outLeft, leftId, inRight, outRight, rightId); 1534 1535 multi_mix_control control; 1536 memset(&control, 0, sizeof(multi_mix_control)); 1537 snprintf(control.name, sizeof(control.name), "%s %s", inputName, name); 1538 1539 for (size_t i = 0; i < 2; i++) { 1540 if (leftId != 0 || rightId != 0) { 1541 control.flags = B_MULTI_MIX_GROUP; 1542 control.string = S_null; 1543 Controls.PushBack(control); 1544 1545 int gainControls = 0; 1546 if (leftId != 0) { 1547 control.id = leftId; 1548 control.flags = B_MULTI_MIX_GAIN; 1549 control.string = S_GAIN; 1550 if (_InitGainLimits(control)) { 1551 gainControls++; 1552 Controls.PushBack(control); 1553 } 1554 } 1555 1556 if (rightId != 0) { 1557 control.id = rightId; 1558 control.flags = B_MULTI_MIX_GAIN; 1559 control.string = S_GAIN; 1560 control.master = leftId; 1561 if (_InitGainLimits(control)) { 1562 gainControls++; 1563 Controls.PushBack(control); 1564 } 1565 } 1566 1567 // remove empty mix group 1568 if (gainControls == 0) 1569 Controls.PopBack(); 1570 else 1571 count++; 1572 } 1573 1574 // take care about surround bus 1575 if (inLeft == inRight) 1576 break; 1577 // handle possible reverse controls 1578 leftId = controlIds[inLeft][outRight]; 1579 rightId = controlIds[inRight][outLeft]; 1580 snprintf(control.name, sizeof(control.name), 1581 "%s %s (Reverse)", inputName, name); 1582 } 1583 1584 return count; 1585 } 1586 1587 1588 void 1589 AudioControlInterface::_ListMixerUnitControls(int32& index, 1590 multi_mix_control_info* Info, Vector<multi_mix_control>& controls) 1591 { 1592 multi_mix_control* Controls = Info->controls; 1593 uint32 groupParent = 0; 1594 uint32 gainParent = 0; 1595 for (Vector<multi_mix_control>::Iterator I = controls.Begin(); 1596 I != controls.End() && index < Info->control_count; I++) { 1597 memcpy(Controls + index, &*I, sizeof(multi_mix_control)); 1598 switch (I->flags) { 1599 case B_MULTI_MIX_GROUP: 1600 Controls[index].id = index; 1601 Controls[index].parent = groupParent; 1602 if (groupParent == 0) { 1603 Controls[index].id |= 0x10000; 1604 groupParent = Controls[index].id; 1605 } 1606 gainParent = Controls[index].id; 1607 break; 1608 case B_MULTI_MIX_GAIN: 1609 Controls[index].parent = gainParent; 1610 break; 1611 default: 1612 TRACE(ERR, "Control type %d ignored\n", I->flags); 1613 continue; 1614 } 1615 1616 index++; 1617 } 1618 1619 if (index == Info->control_count) 1620 TRACE(ERR, "Control count limit %d has been reached.\n", index); 1621 } 1622 1623 1624 void 1625 AudioControlInterface::_ListMixControlsForMixerUnit(int32& index, 1626 multi_mix_control_info* Info, _AudioControl* control) 1627 { 1628 MixerUnit* mixer = static_cast<MixerUnit*>(control); 1629 if (mixer == 0 || mixer->SubType() != USB_AUDIO_AC_MIXER_UNIT) 1630 return; 1631 1632 struct _ChannelPair { 1633 size_t inLeft; 1634 size_t inRight; 1635 const char* name; 1636 } channelPairs[] = { 1637 { 0, 1, "" }, 1638 { 2, 2, "Center" }, 1639 { 3, 3, "L.F.E" }, 1640 { 4, 5, "Back" }, 1641 { 6, 7, "Front of Center" }, 1642 { 8, 8, "Back Center" }, 1643 { 9, 10, "Side" }, 1644 { 11, 11, "Top Center" }, 1645 { 12, 14, "Top Front" }, 1646 { 13, 13, "Top Front Center" }, 1647 { 15, 17, "Top Back" }, 1648 { 16, 16, "Top Back Center" } 1649 }; 1650 1651 Vector<_MixPageCollector*> mixControls; 1652 1653 _MixPageCollector* genericPage = new(std::nothrow) _MixPageCollector("Mixer"); 1654 mixControls.PushBack(genericPage); 1655 1656 // page for extended in (>2) and out (>2) mixer controls 1657 size_t controlsOnExMixerPage = 0; 1658 _MixPageCollector* exMixerPage = new(std::nothrow) _MixPageCollector("Mixer"); 1659 1660 AudioChannelCluster* outCluster = mixer->OutCluster(); 1661 1662 int inOffset = 0; 1663 for (int iPin = 0; iPin < mixer->fInputPins.Count(); iPin++) { 1664 _AudioControl* control = Find(mixer->fInputPins[iPin]); 1665 AudioChannelCluster* inCluster = NULL; 1666 if (control != NULL) 1667 inCluster = control->OutCluster(); 1668 if (inCluster == NULL) { 1669 TRACE(ERR, "control %p cluster %p failed!\n", control, inCluster); 1670 break; 1671 } 1672 1673 // at first - collect programmable control ids 1674 uint32 controlIds[kChannels][kChannels] = { { 0 } }; 1675 1676 int inChannel = 0; 1677 for (size_t in = 0; in < kChannels 1678 && inChannel < inCluster->ChannelsCount(); in++) { 1679 if ((inCluster->ChannelsConfig() & (1 << in)) == 0) 1680 continue; 1681 1682 for (size_t out = 0, outChannel = 0; out < kChannels 1683 && outChannel < outCluster->ChannelsCount(); out++) { 1684 if ((outCluster->ChannelsConfig() & (1 << out)) == 0) 1685 continue; 1686 1687 if (mixer->IsControlProgrammable( 1688 inOffset + inChannel, outChannel)) { 1689 if (SpecReleaseNumber() < 0x200) 1690 // USB Audio 1.0 uses ICN/OCN for request 1691 controlIds[in][out] = CTL_ID(inOffset + inChannel + 1, 1692 outChannel + 1, mixer->ID(), fInterface); 1693 else 1694 // USB Audio 2.0 uses CS/MCN for request 1695 controlIds[in][out] = CTL_ID(USB_AUDIO_MIXER_CONTROL, 1696 (inOffset + inChannel) * outCluster->ChannelsCount() 1697 + outChannel, mixer->ID(), fInterface); 1698 } 1699 1700 outChannel++; 1701 } 1702 1703 inChannel++; 1704 } 1705 1706 inOffset += inChannel; 1707 1708 for (size_t in = 0; in < kChannels; in++) 1709 for (size_t out = 0; out < kChannels; out++) 1710 if (controlIds[in][out] != 0) 1711 TRACE(UAC, "ctrl:%08x for in %d; out %d;\n", 1712 controlIds[in][out], in, out); 1713 1714 // second step - distribute controls on 1715 // mixer pages in logical groups 1716 uint32 exChannelsMask = ~(B_CHANNEL_LEFT | B_CHANNEL_RIGHT); 1717 bool inIsEx = (inCluster->ChannelsConfig() & exChannelsMask) != 0; 1718 bool outIsEx = (outCluster->ChannelsConfig() & exChannelsMask) != 0; 1719 1720 if (!inIsEx && !outIsEx) { 1721 // heap up all mono and stereo controls into single "Mixer" page 1722 for (size_t i = 0; i < 2; i++) 1723 _CollectMixerUnitControls(controlIds, 1724 kLeftChannel, channelPairs[i].inLeft, 1725 kRightChannel, channelPairs[i].inRight, 1726 control->Name(), channelPairs[i].name, 1727 *mixControls[0]); 1728 continue; // go next input cluster 1729 } 1730 1731 if (!outIsEx) { 1732 // special case - extended (>2 channels) input cluster 1733 // connected to 2-channels output - add into generic "Mixer" page 1734 for (size_t i = 0; i < B_COUNT_OF(channelPairs); i++) 1735 _CollectMixerUnitControls(controlIds, 1736 channelPairs[i].inLeft, kLeftChannel, 1737 channelPairs[i].inRight, kRightChannel, 1738 control->Name(), channelPairs[i].name, 1739 *mixControls[0]); 1740 continue; // go next input cluster 1741 } 1742 1743 // make separate mixer pages for set of extended (>2) input 1744 // channels connected to extended (>2 channels) output 1745 for (size_t in = 0; in < B_COUNT_OF(channelPairs); in++) { 1746 for (size_t out = 0; out < B_COUNT_OF(channelPairs); out++) { 1747 char outName[sizeof(Info->controls->name)] = { 0 }; 1748 if (in == out) 1749 strlcpy(outName, channelPairs[out].name, sizeof(outName)); 1750 else 1751 snprintf(outName, sizeof(outName), "%s to %s", 1752 channelPairs[in].name, channelPairs[out].name); 1753 1754 controlsOnExMixerPage += _CollectMixerUnitControls(controlIds, 1755 channelPairs[in].inLeft, channelPairs[out].inLeft, 1756 channelPairs[in].inRight, channelPairs[out].inRight, 1757 control->Name(), outName, *exMixerPage); 1758 } 1759 1760 if (controlsOnExMixerPage >= 6) { 1761 mixControls.PushBack(exMixerPage); 1762 exMixerPage = new(std::nothrow) _MixPageCollector("Mixer"); 1763 controlsOnExMixerPage = 0; 1764 } 1765 } 1766 } 1767 1768 if (exMixerPage->Count() > 1) 1769 mixControls.PushBack(exMixerPage); 1770 else 1771 delete exMixerPage; 1772 1773 // final step - fill multiaudio controls info with 1774 // already structured pages/controls info arrays 1775 for (Vector<_MixPageCollector*>::Iterator I = mixControls.Begin(); 1776 I != mixControls.End(); I++) { 1777 Vector<multi_mix_control>* controls = *I; 1778 TRACE(UAC, "controls count: %d\n", controls->Count()); 1779 if (controls->Count() > 1) 1780 _ListMixerUnitControls(index, Info, *controls); 1781 delete controls; 1782 } 1783 } 1784 1785 1786 void 1787 AudioControlInterface::_ListMixControlsPage(int32& index, 1788 multi_mix_control_info* Info, AudioControlsMap& Map, const char* Name) 1789 { 1790 multi_mix_control* Controls = Info->controls; 1791 int32 groupIndex = index | 0x10000; 1792 Controls[index].id = groupIndex; 1793 Controls[index].flags = B_MULTI_MIX_GROUP; 1794 Controls[index].parent = 0; 1795 strlcpy(Controls[index].name, Name, sizeof(Controls[index].name)); 1796 index++; 1797 1798 int32 group = groupIndex; 1799 for (AudioControlsIterator I = Map.Begin(); I != Map.End(); I++) { 1800 TRACE(UAC, "%s control %d listed.\n", Name, I->Value()->ID()); 1801 switch(I->Value()->SubType()) { 1802 case USB_AUDIO_AC_FEATURE_UNIT: 1803 group = _ListFeatureUnitControl(index, groupIndex, 1804 Info, I->Value()); 1805 break; 1806 case USB_AUDIO_AC_SELECTOR_UNIT: 1807 _ListSelectorUnitControl(index, group, Info, I->Value()); 1808 break; 1809 default: 1810 break; 1811 } 1812 } 1813 } 1814 1815 1816 status_t 1817 AudioControlInterface::ListMixControls(multi_mix_control_info* Info) 1818 { 1819 // first harvest feature units that assigned to output terminal(s) 1820 AudioControlsMap RecordControlsMap; 1821 AudioControlsMap OutputControlsMap; 1822 1823 for (AudioControlsIterator I = fOutputTerminals.Begin(); 1824 I != fOutputTerminals.End(); I++) { 1825 _Terminal* terminal = static_cast<_Terminal*>(I->Value()); 1826 if (terminal->IsUSBIO()) 1827 _HarvestRecordFeatureUnits(terminal, RecordControlsMap); 1828 else 1829 _HarvestOutputFeatureUnits(terminal, OutputControlsMap); 1830 } 1831 1832 // separate input and output Feature units 1833 // and collect mixer units that can be controlled 1834 AudioControlsMap InputControlsMap; 1835 AudioControlsMap MixerControlsMap; 1836 1837 for (AudioControlsIterator I = fAudioControls.Begin(); 1838 I != fAudioControls.End(); I++) { 1839 _AudioControl* control = I->Value(); 1840 1841 if (control->SubType() == USB_AUDIO_AC_MIXER_UNIT) { 1842 MixerUnit* mixerControl = static_cast<MixerUnit*>(control); 1843 if (mixerControl->HasProgrammableControls()) 1844 MixerControlsMap.Put(control->ID(), control); 1845 continue; 1846 } 1847 1848 // filter out feature units 1849 if (control->SubType() != USB_AUDIO_AC_FEATURE_UNIT) 1850 continue; 1851 1852 // ignore controls that are already in the output controls maps 1853 if (RecordControlsMap.Find(control->ID()) != RecordControlsMap.End() 1854 || OutputControlsMap.Find(control->ID()) != OutputControlsMap.End()) 1855 continue; 1856 1857 _AudioControl* sourceControl = Find(control->SourceID()); 1858 if (sourceControl != 0 1859 && sourceControl->SubType() == USB_AUDIO_AC_INPUT_TERMINAL) 1860 InputControlsMap.Put(control->ID(), control); 1861 else 1862 OutputControlsMap.Put(control->ID(), control); 1863 } 1864 1865 int32 index = 0; 1866 if (InputControlsMap.Count() > 0) 1867 _ListMixControlsPage(index, Info, InputControlsMap, "Input"); 1868 1869 if (OutputControlsMap.Count() > 0) 1870 _ListMixControlsPage(index, Info, OutputControlsMap, "Output"); 1871 1872 if (RecordControlsMap.Count() > 0) 1873 _ListMixControlsPage(index, Info, RecordControlsMap, "Record"); 1874 1875 1876 for (AudioControlsIterator I = MixerControlsMap.Begin(); 1877 I != MixerControlsMap.End(); I++) 1878 _ListMixControlsForMixerUnit(index, Info, I->Value()); 1879 1880 Info->control_count = index; 1881 1882 return B_OK; 1883 } 1884 1885 1886 status_t 1887 AudioControlInterface::GetMix(multi_mix_value_info* Info) 1888 { 1889 for (int32 i = 0; i < Info->item_count; i++) { 1890 uint16 length = 0; 1891 int16 data = 0; 1892 1893 _AudioControl* control = Find(ID_FROM_CTLID(Info->values[i].id)); 1894 if (control == NULL) { 1895 TRACE(ERR, "No control found for unit id %#02x. Ignore it.\n", 1896 ID_FROM_CTLID(Info->values[i].id)); 1897 continue; 1898 } 1899 1900 switch (control->SubType()) { 1901 case USB_AUDIO_AC_FEATURE_UNIT: 1902 switch(CS_FROM_CTLID(Info->values[i].id)) { 1903 case USB_AUDIO_VOLUME_CONTROL: 1904 length = 2; 1905 break; 1906 case USB_AUDIO_MUTE_CONTROL: 1907 case USB_AUDIO_AUTOMATIC_GAIN_CONTROL: 1908 length = 1; 1909 break; 1910 default: 1911 TRACE(ERR, "Unsupported control id:%08x of type %#02x " 1912 "ignored.\n", ID_FROM_CTLID(Info->values[i].id), 1913 CS_FROM_CTLID(Info->values[i].id)); 1914 continue; 1915 } 1916 break; 1917 case USB_AUDIO_AC_SELECTOR_UNIT: 1918 length = 1; 1919 break; 1920 case USB_AUDIO_AC_MIXER_UNIT: 1921 length = 2; 1922 break; 1923 default: 1924 TRACE(ERR, "Control id:%08x of type %d is not supported\n", 1925 ID_FROM_CTLID(Info->values[i].id), control->SubType()); 1926 continue; 1927 } 1928 1929 size_t actualLength = 0; 1930 status_t status = gUSBModule->send_request(fDevice->USBDevice(), 1931 USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_CLASS, USB_AUDIO_GET_CUR, 1932 REQ_VALUE(Info->values[i].id), REQ_INDEX(Info->values[i].id), 1933 length, &data, &actualLength); 1934 1935 if (status != B_OK || actualLength != length) { 1936 TRACE(ERR, "Request (%04x:%04x) failed:%#08x; received %d of %d\n", 1937 REQ_VALUE(Info->values[i].id), REQ_INDEX(Info->values[i].id), 1938 status, actualLength, length); 1939 continue; 1940 } 1941 1942 switch (control->SubType()) { 1943 case USB_AUDIO_AC_FEATURE_UNIT: 1944 switch(CS_FROM_CTLID(Info->values[i].id)) { 1945 case USB_AUDIO_VOLUME_CONTROL: 1946 Info->values[i].gain = static_cast<float>(data) / 256.; 1947 TRACE(MIX, "Gain control %d; channel: %d; is %f dB.\n", 1948 ID_FROM_CTLID(Info->values[i].id), 1949 CN_FROM_CTLID(Info->values[i].id), 1950 Info->values[i].gain); 1951 break; 1952 case USB_AUDIO_MUTE_CONTROL: 1953 Info->values[i].enable = data > 0; 1954 TRACE(MIX, "Mute control %d; channel: %d; is %d.\n", 1955 ID_FROM_CTLID(Info->values[i].id), 1956 CN_FROM_CTLID(Info->values[i].id), 1957 Info->values[i].enable); 1958 break; 1959 case USB_AUDIO_AUTOMATIC_GAIN_CONTROL: 1960 Info->values[i].enable = data > 0; 1961 TRACE(MIX, "AGain control %d; channel: %d; is %d.\n", 1962 ID_FROM_CTLID(Info->values[i].id), 1963 CN_FROM_CTLID(Info->values[i].id), 1964 Info->values[i].enable); 1965 break; 1966 default: 1967 break; 1968 } 1969 break; 1970 case USB_AUDIO_AC_SELECTOR_UNIT: 1971 Info->values[i].mux = data - 1; 1972 TRACE(MIX, "Selector control %d; is %d.\n", 1973 ID_FROM_CTLID(Info->values[i].id), 1974 Info->values[i].mux); 1975 break; 1976 case USB_AUDIO_AC_MIXER_UNIT: 1977 Info->values[i].gain = static_cast<float>(data) / 256.; 1978 TRACE(MIX, "Mixer #%d channels in: %d; out: %d; is %f dB.\n", 1979 ID_FROM_CTLID(Info->values[i].id), 1980 CS_FROM_CTLID(Info->values[i].id), 1981 CN_FROM_CTLID(Info->values[i].id), 1982 Info->values[i].gain); 1983 break; 1984 } 1985 } 1986 1987 return B_OK; 1988 } 1989 1990 1991 status_t 1992 AudioControlInterface::SetMix(multi_mix_value_info* Info) 1993 { 1994 for (int32 i = 0; i < Info->item_count; i++) { 1995 uint16 length = 0; 1996 int16 data = 0; 1997 1998 _AudioControl* control = Find(ID_FROM_CTLID(Info->values[i].id)); 1999 if (control == NULL) { 2000 TRACE(ERR, "No control found for unit id %#02x. Ignore it.\n", 2001 ID_FROM_CTLID(Info->values[i].id)); 2002 continue; 2003 } 2004 2005 switch (control->SubType()) { 2006 case USB_AUDIO_AC_FEATURE_UNIT: 2007 switch(CS_FROM_CTLID(Info->values[i].id)) { 2008 case USB_AUDIO_VOLUME_CONTROL: 2009 data = static_cast<int16>(Info->values[i].gain * 256.); 2010 length = 2; 2011 TRACE(MIX, "Gain control %d; channel: %d; " 2012 "about to set to %f dB.\n", 2013 ID_FROM_CTLID(Info->values[i].id), 2014 CN_FROM_CTLID(Info->values[i].id), 2015 Info->values[i].gain); 2016 break; 2017 case USB_AUDIO_MUTE_CONTROL: 2018 data = (Info->values[i].enable ? 1 : 0); 2019 length = 1; 2020 TRACE(MIX, "Mute control %d; channel: %d; " 2021 "about to set to %d.\n", 2022 ID_FROM_CTLID(Info->values[i].id), 2023 CN_FROM_CTLID(Info->values[i].id), 2024 Info->values[i].enable); 2025 break; 2026 case USB_AUDIO_AUTOMATIC_GAIN_CONTROL: 2027 data = (Info->values[i].enable ? 1 : 0); 2028 length = 1; 2029 TRACE(MIX, "AGain control %d; channel: %d; " 2030 "about to set to %d.\n", 2031 ID_FROM_CTLID(Info->values[i].id), 2032 CN_FROM_CTLID(Info->values[i].id), 2033 Info->values[i].enable); 2034 break; 2035 default: 2036 TRACE(ERR, "Unsupported control id:%08x of type %#02x " 2037 "ignored.\n", ID_FROM_CTLID(Info->values[i].id), 2038 CS_FROM_CTLID(Info->values[i].id)); 2039 continue; 2040 } 2041 break; 2042 case USB_AUDIO_AC_SELECTOR_UNIT: 2043 data = Info->values[i].mux + 1; 2044 length = 1; 2045 TRACE(MIX, "Selector Control %d about to set to %d.\n", 2046 ID_FROM_CTLID(Info->values[i].id), 2047 Info->values[i].mux); 2048 break; 2049 case USB_AUDIO_AC_MIXER_UNIT: 2050 data = static_cast<int16>(Info->values[i].gain * 256.); 2051 length = 2; 2052 TRACE(MIX, "Mixer %d channels in: %d; out: %d; " 2053 "about to set to %f dB.\n", 2054 ID_FROM_CTLID(Info->values[i].id), 2055 CS_FROM_CTLID(Info->values[i].id), 2056 CN_FROM_CTLID(Info->values[i].id), 2057 Info->values[i].gain); 2058 break; 2059 default: 2060 TRACE(ERR, "Control id:%08x of type %d is not supported\n", 2061 Info->values[i].id, control->SubType()); 2062 continue; 2063 } 2064 2065 size_t actualLength = 0; 2066 status_t status = gUSBModule->send_request(fDevice->USBDevice(), 2067 USB_REQTYPE_INTERFACE_OUT | USB_REQTYPE_CLASS, USB_AUDIO_SET_CUR, 2068 REQ_VALUE(Info->values[i].id), REQ_INDEX(Info->values[i].id), 2069 length, &data, &actualLength); 2070 2071 if (status != B_OK || actualLength != length) { 2072 TRACE(ERR, "Request (%04x:%04x) failed:%#08x; send %d of %d\n", 2073 REQ_VALUE(Info->values[i].id), REQ_INDEX(Info->values[i].id), 2074 status, actualLength, length); 2075 continue; 2076 } 2077 2078 TRACE(MIX, "Value set OK\n"); 2079 } 2080 2081 return B_OK; 2082 } 2083 2084