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

Revision 1467, 52.0 kB (checked in by ppalmers, 12 years ago)

fixes #174

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