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

Revision 1107, 41.9 kB (checked in by ppalmers, 16 years ago)

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