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

Revision 957, 39.0 kB (checked in by ppalmers, 15 years ago)

add adat/spdif channel disable for saffire pro

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