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

Revision 2691, 33.0 kB (checked in by jwoithe, 7 years ago)

Initial attempt to address deprecation of auto_ptr.

C++11 deprecates auto_ptr, and gcc6 (and later versions) print compile time
warnings to this effect whenever it is encountered in the source. The
replacement type is either shared_ptr or unique_ptr depending on the usage.
For almost all usages within FFADO it seems unique_ptr could be the
appropriate choice, but the symantics are a little different to auto_ptr.
Shared_ptr on the other hand can be a drop-in replacement, although it comes
with considerable overheads which unique_ptr avoids. In the context of the
current usage, the extra overhead incurred is not critical.

The code-base cannot at this time change unconditionally to shared_ptr and
unique_ptr because these are not available in gcc4 unless "--std=c++11" is
given. When gcc4 is used certain older versions of dependent libraries must
be used and these in turn will cause compile failures in their header files
if "--std=c++11" is used (libxml++ being an example). At present there are
sufficient users of FFADO still on gcc4 to justify maintaining compatibility
with that gcc version.

The approach adopted at present is to define ffado_smartptr to be either
auto_ptr (if c++11 is not in use) or shared_ptr if it is. All auto_ptr
instances are then changed to ffado_smartptr. This should allow FFADO to be
compiled without errors or warnings on systems using gcc4 and above. Gcc6
defaults to the c++14 standard, so ffado_smartptr will be shared_ptr in that
case; thus the warnings will be avoided.

In time, once gcc4 drops out of common use, the ffado_smartptr instances can
be progressively migrated to unique_ptr or shared_ptr as is appropriate. It
has been pointed out in the ffado-devel mailing list by Jano Svitok (2 May
2017, subject "smart pointers Was: [FFADO-devel] Liquid Saffire 56") that
bebob_dl_mgr.cpp could use unique_ptr. shared_ptr should be ok in other
auto_ptr sites, but futher analysis may show that at least some of them can
use unique_ptr.

The addressing of the auto_ptr issue was prompted by Xavier Forestier's
patch set submitted to ffado-devel in November 2016.

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_saffire.h"
25 #include "focusrite_cmd.h"
26
27 #include "devicemanager.h"
28
29 namespace BeBoB {
30 namespace Focusrite {
31
32 SaffireDevice::SaffireDevice( DeviceManager& d, ffado_smartptr<ConfigRom>( configRom ))
33     : FocusriteDevice( d, configRom)
34     , m_MixerContainer( NULL )
35 {
36     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Focusrite::SaffireDevice (NodeID %d)\n",
37                  getConfigRom().getNodeId() );
38
39     if(getConfigRom().getGuid() < 0x130e0100040000LL) {
40         m_isSaffireLE = false;
41     } else {
42         m_isSaffireLE = true;
43     }
44
45     // find the configured delay time for this device
46     Util::Configuration &config = d.getConfiguration();
47     int delaytime = 0;
48     if(config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "cmd_interval_time", delaytime)) {
49         m_cmd_time_interval = delaytime;
50         debugOutput( DEBUG_LEVEL_VERBOSE, "Setting command interval time to %" PRIu64 "\n",
51                      m_cmd_time_interval );
52     } else {
53         m_cmd_time_interval = 10000;
54         debugOutput( DEBUG_LEVEL_VERBOSE, "No command interval time setting found, defaulting to %" PRIu64 "\n",
55                      m_cmd_time_interval );
56     }
57 }
58
59 bool
60 SaffireDevice::buildMixer()
61 {
62     bool result=true;
63     debugOutput(DEBUG_LEVEL_VERBOSE, "Building a Focusrite Saffire 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     if(m_isSaffireLE) {
76         // create control objects for the saffire LE
77         result &= m_MixerContainer->addElement(
78             new BinaryControl(*this,
79                     FR_SAFFIRELE_CMD_ID_SPDIF_TRANSPARENT, 0,
80                     "SpdifTransparent", "S/PDIF Transparent", "S/PDIF Transparent"));
81         result &= m_MixerContainer->addElement(
82             new BinaryControl(*this,
83                     FR_SAFFIRELE_CMD_ID_MIDITHRU, 0,
84                     "MidiThru", "MIDI Thru", "MIDI Thru"));
85         result &= m_MixerContainer->addElement(
86             new BinaryControl(*this,
87                     FR_SAFFIRELE_CMD_ID_SAVE_SETTINGS, 0,
88                     "SaveSettings", "Save Settings", "Save Settings"));
89         result &= m_MixerContainer->addElement(
90             new BinaryControl(*this,
91                     FR_SAFFIRELE_CMD_ID_HIGH_GAIN_LINE3, 0,
92                     "HighGainLine3", "High Gain Line-in 3", "High Gain Line-in 3"));
93         result &= m_MixerContainer->addElement(
94             new BinaryControl(*this,
95                     FR_SAFFIRELE_CMD_ID_HIGH_GAIN_LINE4, 0,
96                     "HighGainLine4", "High Gain Line-in 4", "High Gain Line-in 4"));
97
98         // output mute controls
99         result &= m_MixerContainer->addElement(
100             new BinaryControl(*this,
101                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_MUTE,
102                     "Out12Mute", "Out1/2 Mute", "Output 1/2 Mute"));
103         result &= m_MixerContainer->addElement(
104             new BinaryControl(*this,
105                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_MUTE,
106                     "Out34Mute", "Out3/4 Mute", "Output 3/4 Mute"));
107         result &= m_MixerContainer->addElement(
108             new BinaryControl(*this,
109                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_MUTE,
110                     "Out56Mute", "Out5/6 Mute", "Output 5/6 Mute"));
111
112         // output front panel hw volume control
113         result &= m_MixerContainer->addElement(
114             new BinaryControl(*this,
115                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_HWCTRL,
116                     "Out12HwCtrl", "Out1/2 HwCtrl", "Output 1/2 Front Panel Hardware volume control"));
117         result &= m_MixerContainer->addElement(
118             new BinaryControl(*this,
119                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_HWCTRL,
120                     "Out34HwCtrl", "Out3/4 HwCtrl", "Output 3/4 Front Panel Hardware volume control"));
121         result &= m_MixerContainer->addElement(
122             new BinaryControl(*this,
123                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_HWCTRL,
124                     "Out56HwCtrl", "Out5/6 HwCtrl", "Output 5/6 Front Panel Hardware volume control"));
125
126         // dac ignore
127         result &= m_MixerContainer->addElement(
128             new BinaryControl(*this,
129                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DACIGNORE,
130                     "Out12DacIgnore", "Out1/2 Dac Ignore", "Output 1/2 Dac Ignore"));
131         result &= m_MixerContainer->addElement(
132             new BinaryControl(*this,
133                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DACIGNORE,
134                     "Out34DacIgnore", "Out3/4 Dac Ignore", "Output 3/4 Dac Ignore"));
135         result &= m_MixerContainer->addElement(
136             new BinaryControl(*this,
137                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DACIGNORE,
138                     "Out56DacIgnore", "Out5/6 Dac Ignore", "Output 5/6 Dac Ignore"));
139
140         // output level controls
141         result &= m_MixerContainer->addElement(
142             new VolumeControlLowRes(*this,
143                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DAC,
144                     "Out12Level", "Out1/2 Level", "Output 1/2 Level"));
145         result &= m_MixerContainer->addElement(
146             new VolumeControlLowRes(*this,
147                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DAC,
148                     "Out34Level", "Out3/4 Level", "Output 3/4 Level"));
149         result &= m_MixerContainer->addElement(
150             new VolumeControlLowRes(*this,
151                     FR_SAFFIRELE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DAC,
152                     "Out56Level", "Out5/6 Level", "Output 5/6 Level"));
153
154     } else {
155         // create control objects for the saffire
156         result &= m_MixerContainer->addElement(
157             new BinaryControl(*this,
158                     FR_SAFFIRE_CMD_ID_INPUT_SOURCE, 0,
159                     "SpdifSwitch", "S/PDIF Switch", "S/PDIF Switch"));
160         result &= m_MixerContainer->addElement(
161             new BinaryControl(*this,
162                     FR_SAFFIRE_CMD_ID_MONO_MODE, 0,
163                     "MonoMode", "Mono Mode", "Toggle Mono Mode"));
164         result &= m_MixerContainer->addElement(
165             new BinaryControl(*this,
166                     FR_SAFFIRE_CMD_ID_DEVICE_MODE, 0,
167                     "DeviceMode", "Device Mode", "Toggle Device Mode"));
168         result &= m_MixerContainer->addElement(
169             new BinaryControl(*this,
170                     FR_SAFFIRE_CMD_ID_EXTERNAL_LOCK, 0,
171                     "ExternalLock", "External Lock", "Has external lock?"));
172         result &= m_MixerContainer->addElement(
173             new BinaryControl(*this,
174                     FR_SAFFIRE_CMD_ID_AUDIO_ON_STATUS, 0,
175                     "AudioOnStatus", "Audio On Status", "Audio On Status"));
176         result &= m_MixerContainer->addElement(
177             new BinaryControl(*this,
178                     FR_SAFFIRE_CMD_ID_SAVE_SETTINGS, 0,
179                     "SaveSettings", "Save Settings", "Save Settings"));
180
181         // output mute controls
182         result &= m_MixerContainer->addElement(
183             new BinaryControl(*this,
184                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
185                     "Out12Mute", "Out1/2 Mute", "Output 1/2 Mute"));
186         result &= m_MixerContainer->addElement(
187             new BinaryControl(*this,
188                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
189                     "Out34Mute", "Out3/4 Mute", "Output 3/4 Mute"));
190         result &= m_MixerContainer->addElement(
191             new BinaryControl(*this,
192                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
193                     "Out56Mute", "Out5/6 Mute", "Output 5/6 Mute"));
194         result &= m_MixerContainer->addElement(
195             new BinaryControl(*this,
196                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
197                     "Out78Mute", "Out7/8 Mute", "Output 7/8 Mute"));
198         result &= m_MixerContainer->addElement(
199             new BinaryControl(*this,
200                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT910, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
201                     "Out910Mute", "Out9/10 Mute", "Output 9/10 Mute"));
202
203         // output front panel hw volume control
204         result &= m_MixerContainer->addElement(
205             new BinaryControl(*this,
206                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
207                     "Out12HwCtrl", "Out1/2 HwCtrl", "Output 1/2 Front Panel Hardware volume control"));
208         result &= m_MixerContainer->addElement(
209             new BinaryControl(*this,
210                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
211                     "Out34HwCtrl", "Out3/4 HwCtrl", "Output 3/4 Front Panel Hardware volume control"));
212         result &= m_MixerContainer->addElement(
213             new BinaryControl(*this,
214                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
215                     "Out56HwCtrl", "Out5/6 HwCtrl", "Output 5/6 Front Panel Hardware volume control"));
216         result &= m_MixerContainer->addElement(
217             new BinaryControl(*this,
218                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
219                     "Out78HwCtrl", "Out7/8 HwCtrl", "Output 7/8 Front Panel Hardware volume control"));
220
221         // output level dim
222         result &= m_MixerContainer->addElement(
223             new BinaryControl(*this,
224                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DIM,
225                     "Out12Dim", "Out1/2 Dim", "Output 1/2 Level Dim"));
226
227         // dac ignore
228         result &= m_MixerContainer->addElement(
229             new BinaryControl(*this,
230                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DACIGNORE,
231                     "Out12DacIgnore", "Out1/2 Dac Ignore", "Output 1/2 Dac Ignore"));
232         result &= m_MixerContainer->addElement(
233             new BinaryControl(*this,
234                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DACIGNORE,
235                     "Out34DacIgnore", "Out3/4 Dac Ignore", "Output 3/4 Dac Ignore"));
236         result &= m_MixerContainer->addElement(
237             new BinaryControl(*this,
238                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DACIGNORE,
239                     "Out56DacIgnore", "Out5/6 Dac Ignore", "Output 5/6 Dac Ignore"));
240         result &= m_MixerContainer->addElement(
241             new BinaryControl(*this,
242                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DACIGNORE,
243                     "Out78DacIgnore", "Out7/8 Dac Ignore", "Output 7/8 Dac Ignore"));
244
245         // output level controls
246         result &= m_MixerContainer->addElement(
247             new VolumeControlLowRes(*this,
248                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DAC,
249                     "Out12Level", "Out1/2 Level", "Output 1/2 Level"));
250         result &= m_MixerContainer->addElement(
251             new VolumeControlLowRes(*this,
252                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DAC,
253                     "Out34Level", "Out3/4 Level", "Output 3/4 Level"));
254         result &= m_MixerContainer->addElement(
255             new VolumeControlLowRes(*this,
256                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DAC,
257                     "Out56Level", "Out5/6 Level", "Output 5/6 Level"));
258         result &= m_MixerContainer->addElement(
259             new VolumeControlLowRes(*this,
260                     FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DAC,
261                     "Out78Level", "Out7/8 Level", "Output 7/8 Level"));
262
263         result &= m_MixerContainer->addElement(
264             new DialPositionControl(*this,
265                     FR_SAFFIRE_CMD_ID_MONITOR_DIAL, 0,
266                     "MonitorDial", "Monitor Dial", "Monitor Dial Value"));
267
268         // metering
269         result &= m_MixerContainer->addElement(
270             new MeteringControl(*this,
271                     FR_SAFFIRE_CMD_ID_METERING_IN1,
272                     "MeteringIn1", "Metering Input 1", "Metering on Input 1"));
273         result &= m_MixerContainer->addElement(
274             new MeteringControl(*this,
275                     FR_SAFFIRE_CMD_ID_METERING_IN2,
276                     "MeteringIn2", "Metering Input 2", "Metering on Input 2"));
277         result &= m_MixerContainer->addElement(
278             new MeteringControl(*this,
279                     FR_SAFFIRE_CMD_ID_METERING_IN3,
280                     "MeteringIn3", "Metering Input 3", "Metering on Input 3"));
281         result &= m_MixerContainer->addElement(
282             new MeteringControl(*this,
283                     FR_SAFFIRE_CMD_ID_METERING_IN4,
284                     "MeteringIn4", "Metering Input 4", "Metering on Input 4"));
285
286         result &= m_MixerContainer->addElement(
287             new MeteringControl(*this,
288                     FR_SAFFIRE_CMD_ID_METERING_PC1,
289                     "MeteringPc1", "Metering PC 1", "Metering on PC Channel 1"));
290         result &= m_MixerContainer->addElement(
291             new MeteringControl(*this,
292                     FR_SAFFIRE_CMD_ID_METERING_PC2,
293                     "MeteringPc2", "Metering PC 2", "Metering on PC Channel 2"));
294         result &= m_MixerContainer->addElement(
295             new MeteringControl(*this,
296                     FR_SAFFIRE_CMD_ID_METERING_PC3,
297                     "MeteringPc3", "Metering PC 3", "Metering on PC Channel 3"));
298         result &= m_MixerContainer->addElement(
299             new MeteringControl(*this,
300                     FR_SAFFIRE_CMD_ID_METERING_PC4,
301                     "MeteringPc4", "Metering PC 4", "Metering on PC Channel 4"));
302         result &= m_MixerContainer->addElement(
303             new MeteringControl(*this,
304                     FR_SAFFIRE_CMD_ID_METERING_PC5,
305                     "MeteringPc5", "Metering PC 5", "Metering on PC Channel 5"));
306         result &= m_MixerContainer->addElement(
307             new MeteringControl(*this,
308                     FR_SAFFIRE_CMD_ID_METERING_PC6,
309                     "MeteringPc6", "Metering PC 6", "Metering on PC Channel 6"));
310         result &= m_MixerContainer->addElement(
311             new MeteringControl(*this,
312                     FR_SAFFIRE_CMD_ID_METERING_PC7,
313                     "MeteringPc7", "Metering PC 7", "Metering on PC Channel 7"));
314         result &= m_MixerContainer->addElement(
315             new MeteringControl(*this,
316                     FR_SAFFIRE_CMD_ID_METERING_PC8,
317                     "MeteringPc8", "Metering PC 8", "Metering on PC Channel 8"));
318         result &= m_MixerContainer->addElement(
319             new MeteringControl(*this,
320                     FR_SAFFIRE_CMD_ID_METERING_PC9,
321                     "MeteringPc9", "Metering PC 9", "Metering on PC Channel 9"));
322         result &= m_MixerContainer->addElement(
323             new MeteringControl(*this,
324                     FR_SAFFIRE_CMD_ID_METERING_PC10,
325                     "MeteringPc10", "Metering PC 10", "Metering on PC Channel 10"));
326
327     }
328    
329     // matrix mix controls
330     if(m_isSaffireLE) {
331         result &= m_MixerContainer->addElement(
332             new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_LEMix48, "LEMix48"));
333    
334         result &= m_MixerContainer->addElement(
335             new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_LEMix96, "LEMix96"));
336
337         result &= m_MixerContainer->addElement(
338             new BinaryControl(*this,
339                     FR_SAFFIRELE_CMD_ID_SWAP_OUT4_OUT1_48K, 0,
340                     "Swap41_48", "Swap41_48", "Swap41_48"));
341         result &= m_MixerContainer->addElement(
342             new BinaryControl(*this,
343                     FR_SAFFIRELE_CMD_ID_SWAP_OUT4_OUT1_96K, 0,
344                     "Swap41_96", "Swap41_96", "Swap41_96"));
345     } else {
346         result &= m_MixerContainer->addElement(
347             new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_SaffireStereoMatrixMix, "MatrixMixerStereo"));
348         result &= m_MixerContainer->addElement(
349             new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_SaffireMonoMatrixMix, "MatrixMixerMono"));
350     }
351
352     if (!result) {
353         debugWarning("One or more control elements could not be created.");
354         // clean up those that were created
355         destroyMixer();
356         return false;
357     }
358
359     if (!addElement(m_MixerContainer)) {
360         debugWarning("Could not register mixer to device\n");
361         // clean up
362         destroyMixer();
363         return false;
364     }
365
366     // add a direct register access element
367     if (!addElement(new RegisterControl(*this, "Register", "Register Access", "Direct register access"))) {
368         debugWarning("Could not create register control element.");
369         // clean up those that were created
370         destroyMixer();
371         return false;
372     }
373
374     return true;
375 }
376
377 bool
378 SaffireDevice::destroyMixer()
379 {
380     debugOutput(DEBUG_LEVEL_VERBOSE, "destroy mixer...\n");
381    
382     if (m_MixerContainer == NULL) {
383         debugOutput(DEBUG_LEVEL_VERBOSE, "no mixer to destroy...\n");
384         return true;
385     }
386    
387     if (!deleteElement(m_MixerContainer)) {
388         debugError("Mixer present but not registered to the avdevice\n");
389         return false;
390     }
391    
392     // remove and delete (as in free) child control elements
393     m_MixerContainer->clearElements(true);
394     delete m_MixerContainer;
395     return true;
396 }
397
398 std::vector<int>
399 SaffireDevice::getSupportedSamplingFrequencies()
400 {
401     std::vector<int> frequencies;
402     frequencies.push_back(44100);
403     frequencies.push_back(48000);
404     frequencies.push_back(88200);
405     frequencies.push_back(96000);
406     return frequencies;
407 }
408
409 void
410 SaffireDevice::showDevice()
411 {
412     if(m_isSaffireLE) {
413         debugOutput(DEBUG_LEVEL_NORMAL, "This is a BeBoB::Focusrite::SaffireDevice (Saffire LE)\n");
414     } else {
415         debugOutput(DEBUG_LEVEL_NORMAL, "This is a BeBoB::Focusrite::SaffireDevice (Saffire)\n");
416     }
417     FocusriteDevice::showDevice();
418 }
419
420 void
421 SaffireDevice::setVerboseLevel(int l)
422 {
423     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
424
425     FocusriteDevice::setVerboseLevel(l);
426 }
427
428 // Saffire pro matrix mixer element
429
430 SaffireMatrixMixer::SaffireMatrixMixer(SaffireDevice& p,
431                                        enum eMatrixMixerType type)
432 : FocusriteMatrixMixer(p, "MatrixMixer")
433 , m_type(type)
434 {
435     init();
436 }
437
438 SaffireMatrixMixer::SaffireMatrixMixer(SaffireDevice& p,
439                                        enum eMatrixMixerType type, std::string n)
440 : FocusriteMatrixMixer(p, n)
441 , m_type(type)
442 {
443     init();
444 }
445
446 void SaffireMatrixMixer::init()
447 {
448     if (m_type==eMMT_SaffireStereoMatrixMix) {
449         m_RowInfo.clear();
450         addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10");
451         addSignalInfo(m_RowInfo, "PC12", "PC 1/2", "PC Channel 1/2");
452         addSignalInfo(m_RowInfo, "PC34", "PC 3/4", "PC Channel 3/4");
453         addSignalInfo(m_RowInfo, "PC56", "PC 5/6", "PC Channel 5/6");
454         addSignalInfo(m_RowInfo, "PC78", "PC 7/8", "PC Channel 7/8");
455         addSignalInfo(m_RowInfo, "IN12", "Input 1/2", "Hardware Inputs 1/2");
456         addSignalInfo(m_RowInfo, "IN34", "Input 3/4", "Hardware Inputs 3/4 (dry / S/PDIF)");
457         addSignalInfo(m_RowInfo, "FX", "Effect return", "Effect return");
458
459         m_ColInfo.clear();
460         addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10");
461         addSignalInfo(m_ColInfo, "OUT12", "OUT 1/2", "Output 1/2");
462         addSignalInfo(m_ColInfo, "OUT34", "OUT 3/4", "Output 3/4");
463         addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6 (HP1)");
464         addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8 (HP2)");
465        
466         // init the cell matrix
467         #define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS 5
468         #define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS 8
469         #define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_OFFSET 0
470
471         std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS );
472         std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS, tmp_cols);
473         m_CellInfo = tmp_all;
474    
475         struct sCellInfo c;
476         c.row=-1;
477         c.col=-1;
478         c.valid=false;
479         c.address=0;
480        
481         // all cells are valid
482         for (int i=0; i < FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS; i++) {
483             for (int j=0; j < FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS; j++) {
484                 c.row = i;
485                 c.col = j;
486                 c.valid = true;
487                 c.address = FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_OFFSET + c.row * FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS + c.col;
488                 m_CellInfo.at(i).at(j) =  c;
489             }
490         }
491     } else if (m_type==eMMT_SaffireMonoMatrixMix) {
492         m_RowInfo.clear();
493         addSignalInfo(m_RowInfo, "IN1", "Input 1", "Hardware Inputs 1");
494         addSignalInfo(m_RowInfo, "IN3", "Input 3", "Hardware Inputs 3");
495         addSignalInfo(m_RowInfo, "FX1", "Effect return 1", "Effect return 1");
496         addSignalInfo(m_RowInfo, "IN2", "Input 2", "Hardware Inputs 2");
497         addSignalInfo(m_RowInfo, "IN4", "Input 4", "Hardware Inputs 4");
498         addSignalInfo(m_RowInfo, "FX2", "Effect return 2", "Effect return 2");
499         addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10");
500         addSignalInfo(m_RowInfo, "PC12", "PC 1/2", "PC Channel 1/2");
501         addSignalInfo(m_RowInfo, "PC34", "PC 3/4", "PC Channel 3/4");
502         addSignalInfo(m_RowInfo, "PC56", "PC 5/6", "PC Channel 5/6");
503         addSignalInfo(m_RowInfo, "PC78", "PC 7/8", "PC Channel 7/8");
504
505         m_ColInfo.clear();
506         addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10");
507         addSignalInfo(m_ColInfo, "OUT12", "OUT 1/2", "Output 1/2");
508         addSignalInfo(m_ColInfo, "OUT34", "OUT 3/4", "Output 3/4");
509         addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6 (HP1)");
510         addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8 (HP2)");
511        
512         // init the cell matrix
513         #define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS 5
514         #define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS 11
515         #define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_OFFSET 0
516
517         std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS );
518         std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS, tmp_cols);
519         m_CellInfo = tmp_all;
520    
521         struct sCellInfo c;
522         c.row=-1;
523         c.col=-1;
524         c.valid=false;
525         c.address=0;
526        
527         // all cells are valid
528         for (int i=0; i < FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS; i++) {
529             for (int j=0; j < FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS; j++) {
530                 c.row = i;
531                 c.col = j;
532                 c.valid = true;
533                 c.address = FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_OFFSET + c.row * FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS + c.col;
534                 m_CellInfo.at(i).at(j) =  c;
535             }
536         }
537     } else if (m_type == eMMT_LEMix48) {
538         addSignalInfo(m_RowInfo, "IN1", "Input 1", "Analog Input 1");
539         addSignalInfo(m_RowInfo, "IN2", "Input 2", "Analog Input 2");
540         addSignalInfo(m_RowInfo, "IN3", "Input 3", "Analog Input 3");
541         addSignalInfo(m_RowInfo, "IN4", "Input 4", "Analog Input 4");
542         addSignalInfo(m_RowInfo, "SPDIFL", "SPDIF L", "S/PDIF Left Input");
543         addSignalInfo(m_RowInfo, "SPDIFR", "SPDIF R", "S/PDIF Right Input");
544
545         addSignalInfo(m_RowInfo, "PC1", "PC 1", "PC Channel 1");
546         addSignalInfo(m_RowInfo, "PC2", "PC 2", "PC Channel 2");
547         addSignalInfo(m_RowInfo, "PC3", "PC 3", "PC Channel 3");
548         addSignalInfo(m_RowInfo, "PC4", "PC 4", "PC Channel 4");
549         addSignalInfo(m_RowInfo, "PC5", "PC 5", "PC Channel 5");
550         addSignalInfo(m_RowInfo, "PC6", "PC 6", "PC Channel 6");
551         addSignalInfo(m_RowInfo, "PC7", "PC 7", "PC Channel 7");
552         addSignalInfo(m_RowInfo, "PC8", "PC 8", "PC Channel 8");
553
554         addSignalInfo(m_ColInfo, "OUT1", "OUT 1", "Output 1");
555         addSignalInfo(m_ColInfo, "OUT2", "OUT 2", "Output 2");
556         addSignalInfo(m_ColInfo, "OUT3", "OUT 3", "Output 3");
557         addSignalInfo(m_ColInfo, "OUT4", "OUT 4", "Output 4");
558
559         // init the cell matrix
560         #define FOCUSRITE_SAFFIRELE_48KMIX_NB_COLS 4
561         #define FOCUSRITE_SAFFIRELE_48KMIX_NB_ROWS 14
562        
563         std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRELE_48KMIX_NB_COLS );
564         std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRELE_48KMIX_NB_ROWS,tmp_cols);
565         m_CellInfo = tmp_all;
566    
567         struct sCellInfo c;
568         c.row=-1;
569         c.col=-1;
570         c.valid=false;
571         c.address=0;
572        
573         for (int i=0;i<FOCUSRITE_SAFFIRELE_48KMIX_NB_ROWS;i++) {
574             for (int j=0;j<FOCUSRITE_SAFFIRELE_48KMIX_NB_COLS;j++) {
575                 m_CellInfo.at(i).at(j) = c;
576             }
577         }
578
579         // now set the cells that are valid
580         setCellInfo(0,0,FR_SAFFIRELE_CMD_ID_IN1_TO_OUT1, true);
581         setCellInfo(0,1,FR_SAFFIRELE_CMD_ID_IN1_TO_OUT2, true);
582         setCellInfo(0,2,FR_SAFFIRELE_CMD_ID_IN1_TO_OUT3, true);
583         setCellInfo(0,3,FR_SAFFIRELE_CMD_ID_IN1_TO_OUT4, true);
584         setCellInfo(1,0,FR_SAFFIRELE_CMD_ID_IN2_TO_OUT1, true);
585         setCellInfo(1,1,FR_SAFFIRELE_CMD_ID_IN2_TO_OUT2, true);
586         setCellInfo(1,2,FR_SAFFIRELE_CMD_ID_IN2_TO_OUT3, true);
587         setCellInfo(1,3,FR_SAFFIRELE_CMD_ID_IN2_TO_OUT4, true);
588         setCellInfo(2,0,FR_SAFFIRELE_CMD_ID_IN3_TO_OUT1, true);
589         setCellInfo(2,1,FR_SAFFIRELE_CMD_ID_IN3_TO_OUT2, true);
590         setCellInfo(2,2,FR_SAFFIRELE_CMD_ID_IN3_TO_OUT3, true);
591         setCellInfo(2,3,FR_SAFFIRELE_CMD_ID_IN3_TO_OUT4, true);
592         setCellInfo(3,0,FR_SAFFIRELE_CMD_ID_IN4_TO_OUT1, true);
593         setCellInfo(3,1,FR_SAFFIRELE_CMD_ID_IN4_TO_OUT2, true);
594         setCellInfo(3,2,FR_SAFFIRELE_CMD_ID_IN4_TO_OUT3, true);
595         setCellInfo(3,3,FR_SAFFIRELE_CMD_ID_IN4_TO_OUT4, true);
596        
597         setCellInfo(4,0,FR_SAFFIRELE_CMD_ID_SPDIF1_TO_OUT1, true);
598         setCellInfo(4,1,FR_SAFFIRELE_CMD_ID_SPDIF1_TO_OUT2, true);
599         setCellInfo(4,2,FR_SAFFIRELE_CMD_ID_SPDIF1_TO_OUT3, true);
600         setCellInfo(4,3,FR_SAFFIRELE_CMD_ID_SPDIF1_TO_OUT4, true);
601         setCellInfo(5,0,FR_SAFFIRELE_CMD_ID_SPDIF2_TO_OUT1, true);
602         setCellInfo(5,1,FR_SAFFIRELE_CMD_ID_SPDIF2_TO_OUT2, true);
603         setCellInfo(5,2,FR_SAFFIRELE_CMD_ID_SPDIF2_TO_OUT3, true);
604         setCellInfo(5,3,FR_SAFFIRELE_CMD_ID_SPDIF2_TO_OUT4, true);
605         setCellInfo(6,0,FR_SAFFIRELE_CMD_ID_PC1_TO_OUT1, true);
606         setCellInfo(6,1,FR_SAFFIRELE_CMD_ID_PC1_TO_OUT2, true);
607         setCellInfo(6,2,FR_SAFFIRELE_CMD_ID_PC1_TO_OUT3, true);
608         setCellInfo(6,3,FR_SAFFIRELE_CMD_ID_PC1_TO_OUT4, true);
609         setCellInfo(7,0,FR_SAFFIRELE_CMD_ID_PC2_TO_OUT1, true);
610         setCellInfo(7,1,FR_SAFFIRELE_CMD_ID_PC2_TO_OUT2, true);
611         setCellInfo(7,2,FR_SAFFIRELE_CMD_ID_PC2_TO_OUT3, true);
612         setCellInfo(7,3,FR_SAFFIRELE_CMD_ID_PC2_TO_OUT4, true);
613         setCellInfo(8,0,FR_SAFFIRELE_CMD_ID_PC3_TO_OUT1, true);
614         setCellInfo(8,1,FR_SAFFIRELE_CMD_ID_PC3_TO_OUT2, true);
615         setCellInfo(8,2,FR_SAFFIRELE_CMD_ID_PC3_TO_OUT3, true);
616         setCellInfo(8,3,FR_SAFFIRELE_CMD_ID_PC3_TO_OUT4, true);
617         setCellInfo(9,0,FR_SAFFIRELE_CMD_ID_PC4_TO_OUT1, true);
618         setCellInfo(9,1,FR_SAFFIRELE_CMD_ID_PC4_TO_OUT2, true);
619         setCellInfo(9,2,FR_SAFFIRELE_CMD_ID_PC4_TO_OUT3, true);
620         setCellInfo(9,3,FR_SAFFIRELE_CMD_ID_PC4_TO_OUT4, true);
621         setCellInfo(10,0,FR_SAFFIRELE_CMD_ID_PC5_TO_OUT1, true);
622         setCellInfo(10,1,FR_SAFFIRELE_CMD_ID_PC5_TO_OUT2, true);
623         setCellInfo(10,2,FR_SAFFIRELE_CMD_ID_PC5_TO_OUT3, true);
624         setCellInfo(10,3,FR_SAFFIRELE_CMD_ID_PC5_TO_OUT4, true);
625         setCellInfo(11,0,FR_SAFFIRELE_CMD_ID_PC6_TO_OUT1, true);
626         setCellInfo(11,1,FR_SAFFIRELE_CMD_ID_PC6_TO_OUT2, true);
627         setCellInfo(11,2,FR_SAFFIRELE_CMD_ID_PC6_TO_OUT3, true);
628         setCellInfo(11,3,FR_SAFFIRELE_CMD_ID_PC6_TO_OUT4, true);
629         setCellInfo(12,0,FR_SAFFIRELE_CMD_ID_PC7_TO_OUT1, true);
630         setCellInfo(12,1,FR_SAFFIRELE_CMD_ID_PC7_TO_OUT2, true);
631         setCellInfo(12,2,FR_SAFFIRELE_CMD_ID_PC7_TO_OUT3, true);
632         setCellInfo(12,3,FR_SAFFIRELE_CMD_ID_PC7_TO_OUT4, true);
633         setCellInfo(13,0,FR_SAFFIRELE_CMD_ID_PC8_TO_OUT1, true);
634         setCellInfo(13,1,FR_SAFFIRELE_CMD_ID_PC8_TO_OUT2, true);
635         setCellInfo(13,2,FR_SAFFIRELE_CMD_ID_PC8_TO_OUT3, true);
636         setCellInfo(13,3,FR_SAFFIRELE_CMD_ID_PC8_TO_OUT4, true);
637
638     } else if (m_type == eMMT_LEMix96) {
639         addSignalInfo(m_RowInfo, "IN1", "Input 1", "Analog Input 1");
640         addSignalInfo(m_RowInfo, "IN2", "Input 2", "Analog Input 2");
641         addSignalInfo(m_RowInfo, "IN3", "Input 3", "Analog Input 3");
642         addSignalInfo(m_RowInfo, "IN4", "Input 4", "Analog Input 4");
643         addSignalInfo(m_RowInfo, "SPDIFL", "SPDIF L", "S/PDIF Left Input");
644         addSignalInfo(m_RowInfo, "SPDIFR", "SPDIF R", "S/PDIF Right Input");
645
646         addSignalInfo(m_RowInfo, "PC1", "PC 1", "PC Channel 1");
647         addSignalInfo(m_RowInfo, "PC2", "PC 2", "PC Channel 2");
648         addSignalInfo(m_RowInfo, "PC3", "PC 3", "PC Channel 3");
649         addSignalInfo(m_RowInfo, "PC4", "PC 4", "PC Channel 4");
650         addSignalInfo(m_RowInfo, "PC5", "PC 5", "PC Channel 5");
651         addSignalInfo(m_RowInfo, "PC6", "PC 6", "PC Channel 6");
652         addSignalInfo(m_RowInfo, "PC7", "PC 7", "PC Channel 7");
653         addSignalInfo(m_RowInfo, "PC8", "PC 8", "PC Channel 8");
654         addSignalInfo(m_RowInfo, "RECMIXRETURN", "RECMIXRETURN", "Record mix (mono) return");
655
656         addSignalInfo(m_ColInfo, "OUT1", "OUT 1", "Output 1");
657         addSignalInfo(m_ColInfo, "OUT2", "OUT 2", "Output 2");
658         addSignalInfo(m_ColInfo, "OUT3", "OUT 3", "Output 3");
659         addSignalInfo(m_ColInfo, "OUT4", "OUT 4", "Output 4");
660         addSignalInfo(m_ColInfo, "RECMIX", "RECMIX", "Record mix (mono)");
661
662         // init the cell matrix
663         #define FOCUSRITE_SAFFIRELE_96KMIX_NB_COLS 5
664         #define FOCUSRITE_SAFFIRELE_96KMIX_NB_ROWS 15
665        
666         std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRELE_96KMIX_NB_COLS );
667         std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRELE_96KMIX_NB_ROWS,tmp_cols);
668         m_CellInfo = tmp_all;
669    
670         struct sCellInfo c;
671         c.row=-1;
672         c.col=-1;
673         c.valid=false;
674         c.address=0;
675        
676         for (int i=0;i<FOCUSRITE_SAFFIRELE_96KMIX_NB_ROWS;i++) {
677             for (int j=0;j<FOCUSRITE_SAFFIRELE_96KMIX_NB_COLS;j++) {
678                 m_CellInfo.at(i).at(j) = c;
679             }
680         }
681
682         // now set the cells that are valid
683         setCellInfo(0,4,FR_SAFFIRELE_CMD_ID_IN1_TO_RECMIX_96K, true);
684         setCellInfo(1,4,FR_SAFFIRELE_CMD_ID_IN2_TO_RECMIX_96K, true);
685         setCellInfo(2,4,FR_SAFFIRELE_CMD_ID_IN3_TO_RECMIX_96K, true);
686         setCellInfo(3,4,FR_SAFFIRELE_CMD_ID_IN4_TO_RECMIX_96K, true);
687         setCellInfo(4,4,FR_SAFFIRELE_CMD_ID_SPDIF1_TO_RECMIX_96K, true);
688         setCellInfo(5,4,FR_SAFFIRELE_CMD_ID_SPDIF2_TO_RECMIX_96K, true);
689
690         setCellInfo(14,0,FR_SAFFIRELE_CMD_ID_RECMIX_TO_OUT1_96K, true);
691         setCellInfo(14,1,FR_SAFFIRELE_CMD_ID_RECMIX_TO_OUT2_96K, true);
692         setCellInfo(14,2,FR_SAFFIRELE_CMD_ID_RECMIX_TO_OUT3_96K, true);
693         setCellInfo(14,3,FR_SAFFIRELE_CMD_ID_RECMIX_TO_OUT4_96K, true);
694
695         setCellInfo(7,0,FR_SAFFIRELE_CMD_ID_PC1_TO_OUT1_96K, true);
696         setCellInfo(7,1,FR_SAFFIRELE_CMD_ID_PC1_TO_OUT2_96K, true);
697         setCellInfo(7,2,FR_SAFFIRELE_CMD_ID_PC1_TO_OUT3_96K, true);
698         setCellInfo(7,3,FR_SAFFIRELE_CMD_ID_PC1_TO_OUT4_96K, true);
699         setCellInfo(8,0,FR_SAFFIRELE_CMD_ID_PC2_TO_OUT1_96K, true);
700         setCellInfo(8,1,FR_SAFFIRELE_CMD_ID_PC2_TO_OUT2_96K, true);
701         setCellInfo(8,2,FR_SAFFIRELE_CMD_ID_PC2_TO_OUT3_96K, true);
702         setCellInfo(8,3,FR_SAFFIRELE_CMD_ID_PC2_TO_OUT4_96K, true);
703     } else {
704         debugError("Invalid mixer type\n");
705     }
706 }
707
708 void SaffireMatrixMixer::show()
709 {
710     debugOutput(DEBUG_LEVEL_NORMAL, "Saffire Matrix mixer type %d\n", m_type);
711 }
712
713 } // Focusrite
714 } // BeBoB
Note: See TracBrowser for help on using the browser.