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

Revision 1294, 49.7 kB (checked in by ppalmers, 16 years ago)

(re: #145) try to fix focusrite saffire pro clock source selection. Not 100% sure it works properly though.

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