root/trunk/libffado/src/bebob/focusrite/focusrite_saffirepro.cpp

Revision 750, 32.1 kB (checked in by ppalmers, 15 years ago)

Code refactoring. Tries to simplify things and tries to put all code where it belongs.

Line 
1 /*
2  * Copyright (C) 2005-2007 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "focusrite_saffirepro.h"
25 #include "focusrite_cmd.h"
26
27 namespace BeBoB {
28 namespace Focusrite {
29
30 SaffireProDevice::SaffireProDevice( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
31     : FocusriteDevice( d, configRom )
32     , m_MixerContainer( NULL )
33     , m_ControlContainer( NULL )
34 {
35     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Focusrite::SaffireProDevice (NodeID %d)\n",
36                  getConfigRom().getNodeId() );
37
38     addOption(Util::OptionContainer::Option("rebootOnSamplerateChange", true));
39     // the saffire pro doesn't seem to like it if the commands are too fast
40     if (AVC::AVCCommand::getSleepAfterAVCCommand() < 500) {
41         AVC::AVCCommand::setSleepAfterAVCCommand( 500 );
42     }
43 }
44
45 SaffireProDevice::~SaffireProDevice()
46 {
47     destroyMixer();
48 }
49
50 bool
51 SaffireProDevice::buildMixer()
52 {
53     bool result=true;
54     debugOutput(DEBUG_LEVEL_VERBOSE, "Building a Focusrite SaffirePro mixer...\n");
55    
56     destroyMixer();
57    
58     // create the mixer object container
59     m_MixerContainer = new Control::Container("Mixer");
60
61     if (!m_MixerContainer) {
62         debugError("Could not create mixer container...\n");
63         return false;
64     }
65
66     // output mute controls
67     result &= m_MixerContainer->addElement(
68         new BinaryControl(*this,
69                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT12, FR_SAFFIREPRO_CMD_BITFIELD_BIT_MUTE,
70                 "Out12Mute", "Out1/2 Mute", "Output 1/2 Mute"));
71     result &= m_MixerContainer->addElement(
72         new BinaryControl(*this,
73                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT34, FR_SAFFIREPRO_CMD_BITFIELD_BIT_MUTE,
74                 "Out34Mute", "Out3/4 Mute", "Output 3/4 Mute"));
75     result &= m_MixerContainer->addElement(
76         new BinaryControl(*this,
77                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT56, FR_SAFFIREPRO_CMD_BITFIELD_BIT_MUTE,
78                 "Out56Mute", "Out5/6 Mute", "Output 5/6 Mute"));
79     result &= m_MixerContainer->addElement(
80         new BinaryControl(*this,
81                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT78, FR_SAFFIREPRO_CMD_BITFIELD_BIT_MUTE,
82                 "Out78Mute", "Out7/8 Mute", "Output 7/8 Mute"));
83
84     // output front panel hw volume control
85     result &= m_MixerContainer->addElement(
86         new BinaryControl(*this,
87                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT12, FR_SAFFIREPRO_CMD_BITFIELD_BIT_HWCTRL,
88                 "Out12HwCtrl", "Out1/2 HwCtrl", "Output 1/2 Front Panel Hardware volume control"));
89     result &= m_MixerContainer->addElement(
90         new BinaryControl(*this,
91                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT34, FR_SAFFIREPRO_CMD_BITFIELD_BIT_HWCTRL,
92                 "Out34HwCtrl", "Out3/4 HwCtrl", "Output 3/4 Front Panel Hardware volume control"));
93     result &= m_MixerContainer->addElement(
94         new BinaryControl(*this,
95                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT56, FR_SAFFIREPRO_CMD_BITFIELD_BIT_HWCTRL,
96                 "Out56HwCtrl", "Out5/6 HwCtrl", "Output 5/6 Front Panel Hardware volume control"));
97     result &= m_MixerContainer->addElement(
98         new BinaryControl(*this,
99                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT78, FR_SAFFIREPRO_CMD_BITFIELD_BIT_HWCTRL,
100                 "Out78HwCtrl", "Out7/8 HwCtrl", "Output 7/8 Front Panel Hardware volume control"));
101
102     // output active monitor padding
103     result &= m_MixerContainer->addElement(
104         new BinaryControl(*this,
105                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT12, FR_SAFFIREPRO_CMD_BITFIELD_BIT_PAD,
106                 "Out12Pad", "Out1/2 Pad", "Output 1/2 Active Monitor Pad"));
107     result &= m_MixerContainer->addElement(
108         new BinaryControl(*this,
109                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT34, FR_SAFFIREPRO_CMD_BITFIELD_BIT_PAD,
110                 "Out34Pad", "Out3/4 Pad", "Output 3/4 Active Monitor Pad"));
111     result &= m_MixerContainer->addElement(
112         new BinaryControl(*this,
113                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT56, FR_SAFFIREPRO_CMD_BITFIELD_BIT_PAD,
114                 "Out56Pad", "Out5/6 Pad", "Output 5/6 Active Monitor Pad"));
115     result &= m_MixerContainer->addElement(
116         new BinaryControl(*this,
117                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT78, FR_SAFFIREPRO_CMD_BITFIELD_BIT_PAD,
118                 "Out78Pad", "Out7/8 Pad", "Output 7/8 Active Monitor Pad"));
119
120     // output level dim
121     result &= m_MixerContainer->addElement(
122         new BinaryControl(*this,
123                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT12, FR_SAFFIREPRO_CMD_BITFIELD_BIT_DIM,
124                 "Out12Dim", "Out1/2 Dim", "Output 1/2 Level Dim"));
125     result &= m_MixerContainer->addElement(
126         new BinaryControl(*this,
127                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT34, FR_SAFFIREPRO_CMD_BITFIELD_BIT_DIM,
128                 "Out34Dim", "Out3/4 Dim", "Output 3/4 Level Dim"));
129     result &= m_MixerContainer->addElement(
130         new BinaryControl(*this,
131                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT56, FR_SAFFIREPRO_CMD_BITFIELD_BIT_DIM,
132                 "Out56Dim", "Out5/6 Dim", "Output 5/6 Level Dim"));
133     result &= m_MixerContainer->addElement(
134         new BinaryControl(*this,
135                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT78, FR_SAFFIREPRO_CMD_BITFIELD_BIT_DIM,
136                 "Out78Dim", "Out7/8 Dim", "Output 7/8 Level Dim"));
137
138     // output level controls
139     result &= m_MixerContainer->addElement(
140         new VolumeControlLowRes(*this,
141                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT12, 0,
142                 "Out12Level", "Out1/2 Level", "Output 1/2 Level"));
143     result &= m_MixerContainer->addElement(
144         new VolumeControlLowRes(*this,
145                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT34, 0,
146                 "Out34Level", "Out3/4 Level", "Output 3/4 Level"));
147     result &= m_MixerContainer->addElement(
148         new VolumeControlLowRes(*this,
149                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT56, 0,
150                 "Out56Level", "Out5/6 Level", "Output 5/6 Level"));
151     result &= m_MixerContainer->addElement(
152         new VolumeControlLowRes(*this,
153                 FR_SAFFIREPRO_CMD_ID_BITFIELD_OUT78, 0,
154                 "Out78Level", "Out7/8 Level", "Output 7/8 Level"));
155
156     // indicators
157     result &= m_MixerContainer->addElement(
158         new BinaryControl(*this,
159                 FR_SAFFIREPRO_CMD_ID_MUTE_INDICATOR, 0,
160                 "Out12MuteInd", "Out1/2 Mute Ind", "Output 1/2 Mute Indicator"));
161
162     result &= m_MixerContainer->addElement(
163         new BinaryControl(*this,
164                 FR_SAFFIREPRO_CMD_ID_DIM_INDICATOR, 0,
165                 "Out12DimInd", "Out1/2 Dim Ind", "Output 1/2 Level Dim Indicator"));
166
167     // matrix mix controls
168     result &= m_MixerContainer->addElement(
169         new SaffireProMatrixMixer(*this, SaffireProMatrixMixer::eMMT_InputMix, "InputMix"));
170
171     result &= m_MixerContainer->addElement(
172         new SaffireProMatrixMixer(*this, SaffireProMatrixMixer::eMMT_OutputMix, "OutputMix"));
173
174     if (!result) {
175         debugWarning("One or more mixer control elements could not be created.");
176         // clean up those that couldn't be created
177         destroyMixer();
178         return false;
179     }
180     if (!addElement(m_MixerContainer)) {
181         debugWarning("Could not register mixer to device\n");
182         // clean up
183         destroyMixer();
184         return false;
185     }
186
187     // special controls
188     m_ControlContainer = new Control::Container("Control");
189     if (!m_ControlContainer) {
190         debugError("Could not create mixer container...\n");
191         return false;
192     }
193
194     // create control objects for the saffire pro
195     result &= m_ControlContainer->addElement(
196         new BinaryControl(*this, FR_SAFFIREPRO_CMD_ID_PHANTOM14, 0,
197                  "Phantom_1to4", "Phantom 1-4", "Switch Phantom Power on channels 1-4"));
198    
199     result &= m_ControlContainer->addElement(
200         new BinaryControl(*this, FR_SAFFIREPRO_CMD_ID_PHANTOM58, 0,
201                  "Phantom_5to8", "Phantom 5-8", "Switch Phantom Power on channels 5-8"));
202    
203     result &= m_ControlContainer->addElement(
204         new BinaryControl(*this, FR_SAFFIREPRO_CMD_ID_INSERT1, 0,
205                 "Insert1", "Insert 1", "Switch Insert on Channel 1"));
206    
207     result &= m_ControlContainer->addElement(
208         new BinaryControl(*this, FR_SAFFIREPRO_CMD_ID_INSERT2, 0,
209                 "Insert2", "Insert 2", "Switch Insert on Channel 2"));
210    
211     result &= m_ControlContainer->addElement(
212         new BinaryControl(*this, FR_SAFFIREPRO_CMD_ID_AC3_PASSTHROUGH, 0,
213                 "AC3pass", "AC3 Passtrough", "Enable AC3 Passthrough"));
214    
215     result &= m_ControlContainer->addElement(
216         new BinaryControl(*this, FR_SAFFIREPRO_CMD_ID_MIDI_TRU, 0,
217                 "MidiTru", "Midi Tru", "Enable Midi Tru"));
218    
219     result &= m_ControlContainer->addElement(
220         new SaffireProMultiControl(*this, SaffireProMultiControl::eTCT_Reboot,
221             "Reboot", "Reboot", "Reboot Device"));
222
223     result &= m_ControlContainer->addElement(
224         new SaffireProMultiControl(*this, SaffireProMultiControl::eTCT_FlashLed,
225             "FlashLed", "Flash Led", "Flash power led"));
226
227     result &= m_ControlContainer->addElement(
228         new SaffireProMultiControl(*this, SaffireProMultiControl::eTCT_UseHighVoltageRail,
229             "UseHighVoltageRail", "Use High Supply", "Prefer the high voltage power supply rail"));
230
231     if (!result) {
232         debugWarning("One or more device control elements could not be created.");
233         // clean up those that couldn't be created
234         destroyMixer();
235         return false;
236     }
237     if (!addElement(m_ControlContainer)) {
238         debugWarning("Could not register controls to device\n");
239         // clean up
240         destroyMixer();
241         return false;
242     }
243
244
245     return true;
246 }
247
248 bool
249 SaffireProDevice::destroyMixer()
250 {
251     debugOutput(DEBUG_LEVEL_VERBOSE, "destroy mixer...\n");
252    
253     if (m_MixerContainer == NULL) {
254         debugOutput(DEBUG_LEVEL_VERBOSE, "no mixer to destroy...\n");
255         return true;
256     }
257    
258     if (!deleteElement(m_MixerContainer)) {
259         debugError("Mixer present but not registered to the avdevice\n");
260         return false;
261     }
262    
263     // remove and delete (as in free) child control elements
264     m_MixerContainer->clearElements(true);
265     delete m_MixerContainer;
266     m_MixerContainer = NULL;
267
268     // remove control container
269     if (m_ControlContainer == NULL) {
270         debugOutput(DEBUG_LEVEL_VERBOSE, "no controls to destroy...\n");
271         return true;
272     }
273    
274     if (!deleteElement(m_ControlContainer)) {
275         debugError("Controls present but not registered to the avdevice\n");
276         return false;
277     }
278    
279     // remove and delete (as in free) child control elements
280     m_ControlContainer->clearElements(true);
281     delete m_ControlContainer;
282     m_ControlContainer = NULL;
283
284     return true;
285 }
286
287 void
288 SaffireProDevice::showDevice()
289 {
290     debugOutput(DEBUG_LEVEL_VERBOSE, "This is a BeBoB::Focusrite::SaffireProDevice\n");
291     FocusriteDevice::showDevice();
292 }
293
294 void
295 SaffireProDevice::setVerboseLevel(int l)
296 {
297     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
298
299     if (m_MixerContainer) m_MixerContainer->setVerboseLevel(l);
300
301     // FIXME: add the other elements here too
302
303     FocusriteDevice::setVerboseLevel(l);
304 }
305
306 int
307 SaffireProDevice::getSamplingFrequency( ) {
308     uint32_t sr;
309     if ( !getSpecificValue(FR_SAFFIREPRO_CMD_ID_SAMPLERATE, &sr ) ) {
310         debugError( "getSpecificValue failed\n" );
311         return 0;
312     }
313    
314     debugOutput( DEBUG_LEVEL_VERBOSE,
315                      "getSampleRate: %d\n", sr );
316
317     return convertDefToSr(sr);
318 }
319
320 bool
321 SaffireProDevice::setSamplingFrequencyDo( uint32_t value )
322 {
323     if ( !setSpecificValue(FR_SAFFIREPRO_CMD_ID_SAMPLERATE, value) ) {
324         debugError( "setSpecificValue failed\n" );
325         return false;
326     }
327     return true;
328 }
329
330 bool
331 SaffireProDevice::setSamplingFrequencyDoNoReboot( uint32_t value )
332 {
333     if ( !setSpecificValue(FR_SAFFIREPRO_CMD_ID_SAMPLERATE_NOREBOOT, value) ) {
334         debugError( "setSpecificValue failed\n" );
335         return false;
336     }
337     return true;
338 }
339
340 bool
341 SaffireProDevice::setSamplingFrequency( int s )
342 {
343     bool snoopMode=false;
344     if(!getOption("snoopMode", snoopMode)) {
345         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
346     }
347
348     bool rebootOnSamplerateChange=false;
349     if(!getOption("rebootOnSamplerateChange", rebootOnSamplerateChange)) {
350         debugWarning("Could not retrieve rebootOnSamplerateChange parameter, defauling to false\n");
351     }
352
353     if(snoopMode) {
354         if (s != getSamplingFrequency()) {
355             debugError("In snoop mode it is impossible to set the sample rate.\n");
356             debugError("Please start the client with the correct setting.\n");
357             return false;
358         }
359         return true;
360     } else {
361         uint32_t value = convertSrToDef(s);
362         if ( value == 0 ) {
363             debugError("Unsupported samplerate: %u\n", s);
364             return false;
365         }
366    
367         if (s == getSamplingFrequency()) {
368             debugOutput( DEBUG_LEVEL_VERBOSE, "No need to change samplerate\n");
369             return true;
370         }
371
372         const int max_tries = 2;
373         int ntries = max_tries+1;
374        
375         unsigned int gen_before = get1394Service().getGeneration();
376        
377         while(--ntries) {
378             if (rebootOnSamplerateChange) {
379                 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting samplerate with reboot\n");
380                 if(!setSamplingFrequencyDo( value )) {
381                     debugWarning("setSamplingFrequencyDo failed\n");
382                 }
383
384                 debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for device to finish rebooting...\n");
385
386                 // the device needs quite some time to reboot
387                 usleep(2 * 1000 * 1000);
388
389                 int timeout = 5; // multiples of 1s
390                 // wait for a busreset to occur
391                 while ((gen_before == get1394Service().getGeneration())
392                        && --timeout)
393                 {
394                     // wait for a while
395                     usleep(1000 * 1000);
396                 }
397                 if (!timeout) {
398                     debugOutput(DEBUG_LEVEL_VERBOSE, "Device did not reset itself, forcing reboot...\n");
399                     rebootDevice();
400
401                     // the device needs quite some time to reboot
402                     usleep(2 * 1000 * 1000);
403
404                     // wait for the device to finish the reboot
405                     timeout = 10; // multiples of 1s
406                     while ((gen_before == get1394Service().getGeneration())
407                            && --timeout)
408                     {
409                         // wait for a while
410                         usleep(1000 * 1000);
411                     }
412                     if (!timeout) {
413                         debugError( "Device did not reset itself after forced reboot...\n");
414                         return false;
415                     }
416                 }
417
418                 // so we know the device is rebooting
419                 // now wait until it stops generating busresets
420                 timeout = 10;
421                 unsigned int gen_current;
422                 do {
423                     gen_current=get1394Service().getGeneration();
424                     debugOutput(DEBUG_LEVEL_VERBOSE, "Waiting... (gen: %u)\n", gen_current);
425
426                     // wait for a while
427                     usleep(4 * 1000 * 1000);
428                 } while (gen_current != get1394Service().getGeneration()
429                          && --timeout);
430
431                 if (!timeout) {
432                     debugError( "Device did not recover from reboot...\n");
433                     return false;
434                 }
435
436                 debugOutput(DEBUG_LEVEL_VERBOSE, "Device available (gen: %u => %u)...\n",
437                     gen_before, get1394Service().getGeneration());
438
439                 // wait some more
440                 usleep(1 * 1000 * 1000);
441
442                 // we have to rediscover the device
443                 if (discover()) break;
444             } else {
445                 debugOutput( DEBUG_LEVEL_VERBOSE, "Setting samplerate without reboot\n");
446                 if(!setSamplingFrequencyDoNoReboot( value )) {
447                     debugWarning("setSamplingFrequencyDoNoReboot failed\n");
448                 }
449             }
450
451             int verify=getSamplingFrequency();
452             debugOutput( DEBUG_LEVEL_VERBOSE,
453                         "setSampleRate (try %d): requested samplerate %d, device now has %d\n",
454                         max_tries-ntries, s, verify );
455
456             if (s == verify) {
457                 break;
458             }
459             debugOutput( DEBUG_LEVEL_VERBOSE, "setSampleRate (try %d) failed. Try again...\n" );
460         }
461
462         if (ntries==0) {
463             debugError("Setting samplerate failed...\n");
464             return false;
465         }
466
467         return true;
468     }
469     // not executable
470     return false;
471
472 }
473
474 void
475 SaffireProDevice::rebootDevice() {
476     debugOutput( DEBUG_LEVEL_VERBOSE, "rebooting device...\n" );
477     if ( !setSpecificValue(FR_SAFFIREPRO_CMD_ID_REBOOT,
478                            FR_SAFFIREPRO_CMD_REBOOT_CODE ) ) {
479         debugError( "setSpecificValue failed\n" );
480     }
481 }
482
483 void
484 SaffireProDevice::flashLed() {
485     int ledFlashDuration=2;
486     if(!getOption("ledFlashDuration", ledFlashDuration)) {
487         debugWarning("Could not retrieve ledFlashDuration parameter, defaulting to 2sec\n");
488     }
489     int ledFlashFrequency=10;
490     if(!getOption("ledFlashFrequency", ledFlashFrequency)) {
491         debugWarning("Could not retrieve ledFlashFrequency parameter, defaulting to 10Hz\n");
492     }
493
494     uint32_t reg=0;
495     debugOutput( DEBUG_LEVEL_VERBOSE, "flashing led ...\n" );
496    
497     reg = FR_SAFFIREPRO_CMD_SET_FLASH_SECS(reg, ledFlashDuration);
498     reg = FR_SAFFIREPRO_CMD_SET_FLASH_FREQ(reg, ledFlashFrequency);
499    
500     if ( !setSpecificValue(FR_SAFFIREPRO_CMD_ID_FLASH_LED,
501                            reg ) ) {
502         debugError( "setSpecificValue failed\n" );
503     }
504 }
505
506 bool
507 SaffireProDevice::isAudioOn() {
508     uint32_t ready;
509     if ( !getSpecificValue(FR_SAFFIREPRO_CMD_ID_AUDIO_ON, &ready ) ) {
510         debugError( "getSpecificValue failed\n" );
511         return false;
512     }
513
514     debugOutput( DEBUG_LEVEL_VERBOSE,
515                      "isAudioOn: %d\n", ready!=0 );
516     return ready != 0;
517 }
518
519 bool
520 SaffireProDevice::isExtClockLocked() {
521     uint32_t ready;
522     if ( !getSpecificValue(FR_SAFFIREPRO_CMD_ID_EXT_CLOCK_LOCK, &ready ) ) {
523         debugError( "getSpecificValue failed\n" );
524         return false;
525     }
526
527     debugOutput( DEBUG_LEVEL_VERBOSE,
528                      "isExtClockLocked: %d\n", ready!=0 );
529     return ready != 0;
530 }
531
532 uint32_t
533 SaffireProDevice::getCount32() {
534     uint32_t v;
535     if ( !getSpecificValue(FR_SAFFIREPRO_CMD_ID_PLAYBACK_COUNT, &v ) ) {
536         debugError( "getSpecificValue failed\n" );
537         return false;
538     }
539
540     debugOutput( DEBUG_LEVEL_VERBOSE,
541                      "getCount32: %08lX\n", v );
542     return v;
543 }
544
545 void
546 SaffireProDevice::useHighVoltageRail(bool useIt) {
547     uint32_t reg=useIt;
548     debugOutput( DEBUG_LEVEL_VERBOSE, "%s high voltage rail ...\n",
549         (useIt?"Using":"Not using") );
550
551     if ( !setSpecificValue(FR_SAFFIREPRO_CMD_ID_USE_HIGHVOLTAGE_RAIL,
552                            reg ) ) {
553         debugError( "setSpecificValue failed\n" );
554     }
555 }
556
557 bool
558 SaffireProDevice::usingHighVoltageRail() {
559     uint32_t retval;
560     if ( !getSpecificValue(FR_SAFFIREPRO_CMD_ID_USING_HIGHVOLTAGE_RAIL, &retval ) ) {
561         debugError( "getSpecificValue failed\n" );
562         return false;
563     }
564
565     debugOutput( DEBUG_LEVEL_VERBOSE,
566                      "usingHighVoltageRail: %d\n", retval!=0 );
567     return retval != 0;
568 }
569
570 // swiss army knife control element
571 SaffireProMultiControl::SaffireProMultiControl(SaffireProDevice& parent, enum eTriggerControlType t)
572 : Control::Discrete()
573 , m_Parent(parent)
574 , m_type ( t )
575 {}
576 SaffireProMultiControl::SaffireProMultiControl(SaffireProDevice& parent, enum eTriggerControlType t,
577                 std::string name, std::string label, std::string descr)
578 : Control::Discrete()
579 , m_Parent(parent)
580 , m_type ( t )
581 {
582     setName(name);
583     setLabel(label);
584     setDescription(descr);
585 }
586
587 bool
588 SaffireProMultiControl::setValue(int v)
589 {
590     switch (m_type) {
591         case eTCT_Reboot: m_Parent.rebootDevice(); return true;
592         case eTCT_FlashLed: m_Parent.flashLed(); return true;
593         case eTCT_UseHighVoltageRail: m_Parent.useHighVoltageRail(v); return true;
594     }
595     return false;
596 }
597
598 int
599 SaffireProMultiControl::getValue()
600 {
601     switch (m_type) {
602         case eTCT_Reboot: return 0;
603         case eTCT_FlashLed: return 0;
604         case eTCT_UseHighVoltageRail: return m_Parent.usingHighVoltageRail();
605     }
606     return -1;
607 }
608
609
610 // Saffire pro matrix mixer element
611
612 SaffireProMatrixMixer::SaffireProMatrixMixer(SaffireProDevice& p,
613                                              enum eMatrixMixerType type)
614 : FocusriteMatrixMixer(p, "MatrixMixer")
615 , m_type(type)
616 {
617     init();
618 }
619
620 SaffireProMatrixMixer::SaffireProMatrixMixer(SaffireProDevice& p,
621                                              enum eMatrixMixerType type, std::string n)
622 : FocusriteMatrixMixer(p, n)
623 , m_type(type)
624 {
625     init();
626 }
627
628 void SaffireProMatrixMixer::init()
629 {
630     if (m_type==eMMT_OutputMix) {
631         addSignalInfo(m_RowInfo, "PC1", "PC 1", "PC Channel 1");
632         addSignalInfo(m_RowInfo, "PC2", "PC 2", "PC Channel 2");
633         addSignalInfo(m_RowInfo, "PC3", "PC 3", "PC Channel 3");
634         addSignalInfo(m_RowInfo, "PC4", "PC 4", "PC Channel 4");
635         addSignalInfo(m_RowInfo, "PC5", "PC 5", "PC Channel 5");
636         addSignalInfo(m_RowInfo, "PC6", "PC 6", "PC Channel 6");
637         addSignalInfo(m_RowInfo, "PC7", "PC 7", "PC Channel 7");
638         addSignalInfo(m_RowInfo, "PC8", "PC 8", "PC Channel 8");
639         addSignalInfo(m_RowInfo, "PC9", "PC 9", "PC Channel 9");
640         addSignalInfo(m_RowInfo, "PC10", "PC 10", "PC Channel 10");
641         addSignalInfo(m_RowInfo, "IMIXL", "IMix L", "Input Mix Left");
642         addSignalInfo(m_RowInfo, "IMIXR", "IMix R", "Input Mix Right");
643        
644         addSignalInfo(m_ColInfo, "OUT1", "OUT 1", "Output Channel 1");
645         addSignalInfo(m_ColInfo, "OUT2", "OUT 2", "Output Channel 2");
646         addSignalInfo(m_ColInfo, "OUT3", "OUT 3", "Output Channel 3");
647         addSignalInfo(m_ColInfo, "OUT4", "OUT 4", "Output Channel 4");
648         addSignalInfo(m_ColInfo, "OUT5", "OUT 5", "Output Channel 5");
649         addSignalInfo(m_ColInfo, "OUT6", "OUT 6", "Output Channel 6");
650         addSignalInfo(m_ColInfo, "OUT7", "OUT 7", "Output Channel 7");
651         addSignalInfo(m_ColInfo, "OUT8", "OUT 8", "Output Channel 8");
652         addSignalInfo(m_ColInfo, "OUT9", "OUT 9", "Output Channel 9");
653         addSignalInfo(m_ColInfo, "OUT10", "OUT 10", "Output Channel 10");
654        
655         // init the cell matrix
656         #define FOCUSRITE_SAFFIRE_PRO_OUTMIX_NB_COLS 10
657         #define FOCUSRITE_SAFFIRE_PRO_OUTMIX_NB_ROWS 12
658        
659         std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_PRO_OUTMIX_NB_COLS );
660         std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_PRO_OUTMIX_NB_ROWS, tmp_cols);
661         m_CellInfo = tmp_all;
662    
663         struct sCellInfo c;
664         c.row=-1;
665         c.col=-1;
666         c.valid=false;
667         c.address=0;
668        
669         for (int i=0;i<FOCUSRITE_SAFFIRE_PRO_OUTMIX_NB_ROWS;i++) {
670             for (int j=0;j<FOCUSRITE_SAFFIRE_PRO_OUTMIX_NB_COLS;j++) {
671                 m_CellInfo[i][j]=c;
672             }
673         }
674    
675         // now set the cells that are valid
676         setCellInfo(0,0,FR_SAFFIREPRO_CMD_ID_PC1_TO_OUT1, true);
677         setCellInfo(1,1,FR_SAFFIREPRO_CMD_ID_PC2_TO_OUT2, true);
678         setCellInfo(10,0,FR_SAFFIREPRO_CMD_ID_MIX1_TO_OUT1, true);
679         setCellInfo(11,1,FR_SAFFIREPRO_CMD_ID_MIX2_TO_OUT2, true);
680         setCellInfo(0,2,FR_SAFFIREPRO_CMD_ID_PC1_TO_OUT3, true);
681         setCellInfo(1,3,FR_SAFFIREPRO_CMD_ID_PC2_TO_OUT4, true);
682         setCellInfo(2,2,FR_SAFFIREPRO_CMD_ID_PC3_TO_OUT3, true);
683         setCellInfo(3,3,FR_SAFFIREPRO_CMD_ID_PC4_TO_OUT4, true);
684         setCellInfo(10,2,FR_SAFFIREPRO_CMD_ID_MIX1_TO_OUT3, true);
685         setCellInfo(11,3,FR_SAFFIREPRO_CMD_ID_MIX2_TO_OUT4, true);
686         setCellInfo(0,4,FR_SAFFIREPRO_CMD_ID_PC1_TO_OUT5, true);
687         setCellInfo(1,5,FR_SAFFIREPRO_CMD_ID_PC2_TO_OUT6, true);
688         setCellInfo(4,4,FR_SAFFIREPRO_CMD_ID_PC5_TO_OUT5, true);
689         setCellInfo(5,5,FR_SAFFIREPRO_CMD_ID_PC6_TO_OUT6, true);
690         setCellInfo(10,4,FR_SAFFIREPRO_CMD_ID_MIX1_TO_OUT5, true);
691         setCellInfo(11,5,FR_SAFFIREPRO_CMD_ID_MIX2_TO_OUT6, true);
692         setCellInfo(0,6,FR_SAFFIREPRO_CMD_ID_PC1_TO_OUT7, true);
693         setCellInfo(1,7,FR_SAFFIREPRO_CMD_ID_PC2_TO_OUT8, true);
694         setCellInfo(6,6,FR_SAFFIREPRO_CMD_ID_PC7_TO_OUT7, true);
695         setCellInfo(7,7,FR_SAFFIREPRO_CMD_ID_PC8_TO_OUT8, true);
696         setCellInfo(10,6,FR_SAFFIREPRO_CMD_ID_MIX1_TO_OUT7, true);
697         setCellInfo(11,7,FR_SAFFIREPRO_CMD_ID_MIX2_TO_OUT8, true);
698         setCellInfo(0,8,FR_SAFFIREPRO_CMD_ID_PC1_TO_OUT9, true);
699         setCellInfo(1,9,FR_SAFFIREPRO_CMD_ID_PC2_TO_OUT10, true);
700         setCellInfo(8,8,FR_SAFFIREPRO_CMD_ID_PC9_TO_OUT9, true);
701         setCellInfo(9,9,FR_SAFFIREPRO_CMD_ID_PC10_TO_OUT10, true);
702         setCellInfo(10,8,FR_SAFFIREPRO_CMD_ID_MIX1_TO_OUT9, true);
703         setCellInfo(11,9,FR_SAFFIREPRO_CMD_ID_MIX2_TO_OUT10, true);
704
705     } else if (m_type==eMMT_InputMix) {
706         addSignalInfo(m_RowInfo, "AN1", "Analog 1", "Analog Input 1");
707         addSignalInfo(m_RowInfo, "AN2", "Analog 2", "Analog Input 2");
708         addSignalInfo(m_RowInfo, "AN3", "Analog 3", "Analog Input 3");
709         addSignalInfo(m_RowInfo, "AN4", "Analog 4", "Analog Input 4");
710         addSignalInfo(m_RowInfo, "AN5", "Analog 5", "Analog Input 5");
711         addSignalInfo(m_RowInfo, "AN6", "Analog 6", "Analog Input 6");
712         addSignalInfo(m_RowInfo, "AN7", "Analog 7", "Analog Input 7");
713         addSignalInfo(m_RowInfo, "AN8", "Analog 8", "Analog Input 8");
714         addSignalInfo(m_RowInfo, "SPDIFL", "SPDIF L", "SPDIF Left Input");
715         addSignalInfo(m_RowInfo, "SPDIFR", "SPDIF R", "SPDIF Right Input");
716        
717         addSignalInfo(m_RowInfo, "ADAT11", "ADAT1 1", "ADAT1 Channel 1");
718         addSignalInfo(m_RowInfo, "ADAT12", "ADAT1 2", "ADAT1 Channel 2");
719         addSignalInfo(m_RowInfo, "ADAT13", "ADAT1 3", "ADAT1 Channel 3");
720         addSignalInfo(m_RowInfo, "ADAT14", "ADAT1 4", "ADAT1 Channel 4");
721         addSignalInfo(m_RowInfo, "ADAT15", "ADAT1 5", "ADAT1 Channel 5");
722         addSignalInfo(m_RowInfo, "ADAT16", "ADAT1 6", "ADAT1 Channel 6");
723         addSignalInfo(m_RowInfo, "ADAT17", "ADAT1 7", "ADAT1 Channel 7");
724         addSignalInfo(m_RowInfo, "ADAT18", "ADAT1 8", "ADAT1 Channel 8");
725        
726         addSignalInfo(m_RowInfo, "ADAT21", "ADAT2 1", "ADAT2 Channel 1");
727         addSignalInfo(m_RowInfo, "ADAT22", "ADAT2 2", "ADAT2 Channel 2");
728         addSignalInfo(m_RowInfo, "ADAT23", "ADAT2 3", "ADAT2 Channel 3");
729         addSignalInfo(m_RowInfo, "ADAT24", "ADAT2 4", "ADAT2 Channel 4");
730         addSignalInfo(m_RowInfo, "ADAT25", "ADAT2 5", "ADAT2 Channel 5");
731         addSignalInfo(m_RowInfo, "ADAT26", "ADAT2 6", "ADAT2 Channel 6");
732         addSignalInfo(m_RowInfo, "ADAT27", "ADAT2 7", "ADAT2 Channel 7");
733         addSignalInfo(m_RowInfo, "ADAT28", "ADAT2 8", "ADAT2 Channel 8");
734        
735         addSignalInfo(m_ColInfo, "IMIXL", "IMix L", "Input Mix Left");
736         addSignalInfo(m_ColInfo, "IMIXR", "IMix R", "Input Mix Right");
737        
738         // init the cell matrix
739         #define FOCUSRITE_SAFFIRE_PRO_INMIX_NB_COLS 2
740         #define FOCUSRITE_SAFFIRE_PRO_INMIX_NB_ROWS 26
741        
742         std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_PRO_INMIX_NB_COLS );
743         std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_PRO_INMIX_NB_ROWS,tmp_cols);
744         m_CellInfo = tmp_all;
745    
746         struct sCellInfo c;
747         c.row=-1;
748         c.col=-1;
749         c.valid=false;
750         c.address=0;
751        
752         for (int i=0;i<FOCUSRITE_SAFFIRE_PRO_INMIX_NB_ROWS;i++) {
753             for (int j=0;j<FOCUSRITE_SAFFIRE_PRO_INMIX_NB_COLS;j++) {
754                 m_CellInfo[i][j]=c;
755             }
756         }
757    
758         // now set the cells that are valid
759         setCellInfo(0,0,FR_SAFFIREPRO_CMD_ID_AN1_TO_IMIXL, true);
760         setCellInfo(0,1,FR_SAFFIREPRO_CMD_ID_AN1_TO_IMIXR, true);
761         setCellInfo(1,0,FR_SAFFIREPRO_CMD_ID_AN2_TO_IMIXL, true);
762         setCellInfo(1,1,FR_SAFFIREPRO_CMD_ID_AN2_TO_IMIXR, true);
763         setCellInfo(2,0,FR_SAFFIREPRO_CMD_ID_AN3_TO_IMIXL, true);
764         setCellInfo(2,1,FR_SAFFIREPRO_CMD_ID_AN3_TO_IMIXR, true);
765         setCellInfo(3,0,FR_SAFFIREPRO_CMD_ID_AN4_TO_IMIXL, true);
766         setCellInfo(3,1,FR_SAFFIREPRO_CMD_ID_AN4_TO_IMIXR, true);
767         setCellInfo(4,0,FR_SAFFIREPRO_CMD_ID_AN5_TO_IMIXL, true);
768         setCellInfo(4,1,FR_SAFFIREPRO_CMD_ID_AN5_TO_IMIXR, true);
769         setCellInfo(5,0,FR_SAFFIREPRO_CMD_ID_AN6_TO_IMIXL, true);
770         setCellInfo(5,1,FR_SAFFIREPRO_CMD_ID_AN6_TO_IMIXR, true);
771         setCellInfo(6,0,FR_SAFFIREPRO_CMD_ID_AN7_TO_IMIXL, true);
772         setCellInfo(6,1,FR_SAFFIREPRO_CMD_ID_AN7_TO_IMIXR, true);
773         setCellInfo(7,0,FR_SAFFIREPRO_CMD_ID_AN8_TO_IMIXL, true);
774         setCellInfo(7,1,FR_SAFFIREPRO_CMD_ID_AN8_TO_IMIXR, true);
775         setCellInfo(8,0,FR_SAFFIREPRO_CMD_ID_SPDIFL_TO_IMIXL, true);
776         setCellInfo(8,1,FR_SAFFIREPRO_CMD_ID_SPDIFL_TO_IMIXR, true);
777         setCellInfo(9,0,FR_SAFFIREPRO_CMD_ID_SPDIFR_TO_IMIXL, true);
778         setCellInfo(9,1,FR_SAFFIREPRO_CMD_ID_SPDIFR_TO_IMIXR, true);
779
780         setCellInfo(10,0,FR_SAFFIREPRO_CMD_ID_ADAT11_TO_IMIXL, true);
781         setCellInfo(10,1,FR_SAFFIREPRO_CMD_ID_ADAT11_TO_IMIXR, true);
782         setCellInfo(11,0,FR_SAFFIREPRO_CMD_ID_ADAT12_TO_IMIXL, true);
783         setCellInfo(11,1,FR_SAFFIREPRO_CMD_ID_ADAT12_TO_IMIXR, true);
784         setCellInfo(12,0,FR_SAFFIREPRO_CMD_ID_ADAT13_TO_IMIXL, true);
785         setCellInfo(12,1,FR_SAFFIREPRO_CMD_ID_ADAT13_TO_IMIXR, true);
786         setCellInfo(13,0,FR_SAFFIREPRO_CMD_ID_ADAT14_TO_IMIXL, true);
787         setCellInfo(13,1,FR_SAFFIREPRO_CMD_ID_ADAT14_TO_IMIXR, true);
788         setCellInfo(14,0,FR_SAFFIREPRO_CMD_ID_ADAT15_TO_IMIXL, true);
789         setCellInfo(14,1,FR_SAFFIREPRO_CMD_ID_ADAT15_TO_IMIXR, true);
790         setCellInfo(15,0,FR_SAFFIREPRO_CMD_ID_ADAT16_TO_IMIXL, true);
791         setCellInfo(15,1,FR_SAFFIREPRO_CMD_ID_ADAT16_TO_IMIXR, true);
792         setCellInfo(16,0,FR_SAFFIREPRO_CMD_ID_ADAT17_TO_IMIXL, true);
793         setCellInfo(16,1,FR_SAFFIREPRO_CMD_ID_ADAT17_TO_IMIXR, true);
794         setCellInfo(17,0,FR_SAFFIREPRO_CMD_ID_ADAT18_TO_IMIXL, true);
795         setCellInfo(17,1,FR_SAFFIREPRO_CMD_ID_ADAT18_TO_IMIXR, true);
796
797         setCellInfo(18,0,FR_SAFFIREPRO_CMD_ID_ADAT21_TO_IMIXL, true);
798         setCellInfo(18,1,FR_SAFFIREPRO_CMD_ID_ADAT21_TO_IMIXR, true);
799         setCellInfo(19,0,FR_SAFFIREPRO_CMD_ID_ADAT22_TO_IMIXL, true);
800         setCellInfo(19,1,FR_SAFFIREPRO_CMD_ID_ADAT22_TO_IMIXR, true);
801         setCellInfo(20,0,FR_SAFFIREPRO_CMD_ID_ADAT23_TO_IMIXL, true);
802         setCellInfo(20,1,FR_SAFFIREPRO_CMD_ID_ADAT23_TO_IMIXR, true);
803         setCellInfo(21,0,FR_SAFFIREPRO_CMD_ID_ADAT24_TO_IMIXL, true);
804         setCellInfo(21,1,FR_SAFFIREPRO_CMD_ID_ADAT24_TO_IMIXR, true);
805         setCellInfo(22,0,FR_SAFFIREPRO_CMD_ID_ADAT25_TO_IMIXL, true);
806         setCellInfo(22,1,FR_SAFFIREPRO_CMD_ID_ADAT25_TO_IMIXR, true);
807         setCellInfo(23,0,FR_SAFFIREPRO_CMD_ID_ADAT26_TO_IMIXL, true);
808         setCellInfo(23,1,FR_SAFFIREPRO_CMD_ID_ADAT26_TO_IMIXR, true);
809         setCellInfo(24,0,FR_SAFFIREPRO_CMD_ID_ADAT27_TO_IMIXL, true);
810         setCellInfo(24,1,FR_SAFFIREPRO_CMD_ID_ADAT27_TO_IMIXR, true);
811         setCellInfo(25,0,FR_SAFFIREPRO_CMD_ID_ADAT28_TO_IMIXL, true);
812         setCellInfo(25,1,FR_SAFFIREPRO_CMD_ID_ADAT28_TO_IMIXR, true);
813
814     } else {
815         debugError("Invalid mixer type\n");
816     }
817 }
818
819 void SaffireProMatrixMixer::show()
820 {
821     debugOutput(DEBUG_LEVEL_NORMAL, "Saffire Pro Matrix mixer type %d\n");
822 }
823
824 } // Focusrite
825 } // BeBoB
Note: See TracBrowser for help on using the browser.