root/branches/libffado-2.0/src/bebob/focusrite/focusrite_saffirepro.cpp

Revision 1235, 44.0 kB (checked in by ppalmers, 16 years ago)

svn merge -r 1231:1234 svn+ssh://ffadosvn@ffado.org/ffado/trunk/libffado

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