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> {
_MixPageCollector_MixPageCollector61 _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
_AudioControl(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~_AudioControl()84 _AudioControl::~_AudioControl()
85 {
86 }
87
88
89 AudioChannelCluster*
OutCluster()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
AudioChannelCluster()103 AudioChannelCluster::AudioChannelCluster()
104 :
105 fOutChannelsNumber(0),
106 fChannelsConfig(0),
107 fChannelNames(0)
108 {
109 }
110
111
~AudioChannelCluster()112 AudioChannelCluster::~AudioChannelCluster()
113 {
114 }
115
116
117 bool
HasChannel(uint32 location)118 AudioChannelCluster::HasChannel(uint32 location)
119 {
120 return (fChannelsConfig & location) == location;
121 }
122
123
_Terminal(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~_Terminal()136 _Terminal::~_Terminal()
137 {
138 }
139
140
141 const char*
Name()142 _Terminal::Name()
143 {
144 return _GetTerminalDescription(fTerminalType);
145 }
146
147
148 bool
IsUSBIO()149 _Terminal::IsUSBIO()
150 {
151 return (fTerminalType & 0xff00) == USB_AUDIO_UNDEFINED_USB_IO;
152 }
153
154
155 const char*
_GetTerminalDescription(uint16 TerminalType)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
InputTerminal(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~InputTerminal()285 InputTerminal::~InputTerminal()
286 {
287 }
288
289
290 const char*
Name()291 InputTerminal::Name()
292 {
293 if (fTerminalType == USB_AUDIO_STREAMING_USB_IO)
294 return "USB Input";
295 return _Terminal::Name();
296 }
297
298
OutputTerminal(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~OutputTerminal()335 OutputTerminal::~OutputTerminal()
336 {
337 }
338
339
340 const char*
Name()341 OutputTerminal::Name()
342 {
343 if (fTerminalType == USB_AUDIO_STREAMING_USB_IO)
344 return "USB Output";
345 return _Terminal::Name();
346 }
347
348
MixerUnit(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~MixerUnit()435 MixerUnit::~MixerUnit()
436 {
437 }
438
439
440 bool
HasProgrammableControls()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
IsControlProgrammable(int inChannel,int outChannel)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
SelectorUnit(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~SelectorUnit()504 SelectorUnit::~SelectorUnit()
505 {
506 }
507
508
509 AudioChannelCluster*
OutCluster()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
FeatureUnit(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~FeatureUnit()578 FeatureUnit::~FeatureUnit()
579 {
580 }
581
582
583 const char*
Name()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
HasControl(int32 Channel,uint32 Control)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
NormalizeAndTraceChannel(int32 Channel)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
EffectUnit(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~EffectUnit()704 EffectUnit::~EffectUnit()
705 {
706 }
707
708
ProcessingUnit(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~ProcessingUnit()771 ProcessingUnit::~ProcessingUnit()
772 {
773 }
774
775
ExtensionUnit(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~ExtensionUnit()838 ExtensionUnit::~ExtensionUnit()
839 {
840 }
841
842
ClockSource(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~ClockSource()854 ClockSource::~ClockSource()
855 {
856 }
857
858
ClockSelector(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~ClockSelector()870 ClockSelector::~ClockSelector()
871 {
872 }
873
874
ClockMultiplier(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~ClockMultiplier()886 ClockMultiplier::~ClockMultiplier()
887 {
888 }
889
890
SampleRateConverter(AudioControlInterface * interface,usb_audiocontrol_header_descriptor * Header)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
~SampleRateConverter()902 SampleRateConverter::~SampleRateConverter()
903 {
904 }
905
906
AudioControlInterface(Device * device)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
~AudioControlInterface()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
Init(size_t interface,usb_interface_info * Interface)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*
Find(uint8 id)1025 AudioControlInterface::Find(uint8 id)
1026 {
1027 return fAudioControls.Get(id);
1028 }
1029
1030
1031 _AudioControl*
FindOutputTerminal(uint8 id)1032 AudioControlInterface::FindOutputTerminal(uint8 id)
1033 {
1034 return fOutputTerminals.Get(id);
1035 }
1036
1037
1038 status_t
InitACHeader(size_t interface,usb_audiocontrol_header_descriptor * Header)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
GetChannelsDescription(Vector<multi_channel_info> & Channels,multi_description * Description,Vector<_AudioControl * > & Terminals,bool isForInput)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
GetTerminalChannels(Vector<multi_channel_info> & Channels,AudioChannelCluster * cluster,channel_kind kind,uint32 connectors)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
GetBusChannelsDescription(Vector<multi_channel_info> & Channels,multi_description * Description)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
_HarvestRecordFeatureUnits(_AudioControl * rootControl,AudioControlsMap & Map)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
_HarvestOutputFeatureUnits(_AudioControl * rootControl,AudioControlsMap & Map)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
_InitGainLimits(multi_mix_control & Control)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
_ListFeatureUnitOption(uint32 controlType,int32 & index,int32 parentIndex,multi_mix_control_info * Info,FeatureUnit * unit,uint32 channel,uint32 channels)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
_ListFeatureUnitControl(int32 & index,int32 parentIndex,multi_mix_control_info * Info,_AudioControl * control)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
_ListSelectorUnitControl(int32 & index,int32 parentGroup,multi_mix_control_info * Info,_AudioControl * control)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
_CollectMixerUnitControls(const uint32 controlIds[kChannels][kChannels],size_t inLeft,size_t outLeft,size_t inRight,size_t outRight,const char * inputName,const char * name,Vector<multi_mix_control> & Controls)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
_ListMixerUnitControls(int32 & index,multi_mix_control_info * Info,Vector<multi_mix_control> & controls)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
_ListMixControlsForMixerUnit(int32 & index,multi_mix_control_info * Info,_AudioControl * control)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
_ListMixControlsPage(int32 & index,multi_mix_control_info * Info,AudioControlsMap & Map,const char * Name)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
ListMixControls(multi_mix_control_info * Info)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
GetMix(multi_mix_value_info * Info)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
SetMix(multi_mix_value_info * Info)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