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

Revision 960, 39.2 kB (checked in by ppalmers, 16 years ago)

make dbus server handle bus resets and dynamic add/remove of devices

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