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

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

- Adapt the ffado external API (upgrade to v3)

NEEDS NEW JACK BACKEND

- simplify FFADODevice constructor even more
- implement first framework support for supporting multiple adapters.

currently all firewire adapters are scanned for supported devices unless specified otherwise
however attaching devices to separate adapters is not supported. using multiple adapters at
that are connected together might work.

Line 
1 /*
2  * Copyright (C) 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 library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #include "focusrite_saffirepro.h"
25 #include "focusrite_cmd.h"
26
27 namespace BeBoB {
28 namespace Focusrite {
29
30 SaffireProDevice::SaffireProDevice(std::auto_ptr<ConfigRom>( configRom ))
31     : FocusriteDevice( 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.