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

Revision 739, 14.1 kB (checked in by ppalmers, 15 years ago)

- Adapt the ffado external API (upgrade to v3)

NEEDS NEW JACK BACKEND

- simplify FFADODevice constructor even more
- implement first framework support for supporting multiple adapters.

currently all firewire adapters are scanned for supported devices unless specified otherwise
however attaching devices to separate adapters is not supported. using multiple adapters at
that are connected together might work.

Line 
1 /*
2  * Copyright (C) 2007 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 library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #include "focusrite_saffire.h"
25 #include "focusrite_cmd.h"
26
27 namespace BeBoB {
28 namespace Focusrite {
29
30 SaffireDevice::SaffireDevice( std::auto_ptr<ConfigRom>( configRom ))
31     : FocusriteDevice( configRom)
32 {
33     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Focusrite::SaffireDevice (NodeID %d)\n",
34                  getConfigRom().getNodeId() );
35
36     // the saffire pro doesn't seem to like it if the commands are too fast
37     if (AVC::AVCCommand::getSleepAfterAVCCommand() < 1000) {
38         AVC::AVCCommand::setSleepAfterAVCCommand( 1000 );
39     }
40
41 }
42
43 bool
44 SaffireDevice::buildMixer()
45 {
46     bool result=true;
47     debugOutput(DEBUG_LEVEL_VERBOSE, "Building a Focusrite Saffire mixer...\n");
48    
49     destroyMixer();
50    
51     // create the mixer object container
52     m_MixerContainer = new Control::Container("Mixer");
53
54     if (!m_MixerContainer) {
55         debugError("Could not create mixer container...\n");
56         return false;
57     }
58
59     // create control objects for the saffire
60     result &= m_MixerContainer->addElement(
61         new BinaryControl(*this,
62                 FR_SAFFIRE_CMD_ID_SPDIF_SWITCH, 0,
63                 "SpdifSwitch", "S/PDIF Switch", "S/PDIF Switch"));
64
65     // output mute controls
66     result &= m_MixerContainer->addElement(
67         new BinaryControl(*this,
68                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
69                 "Out12Mute", "Out1/2 Mute", "Output 1/2 Mute"));
70     result &= m_MixerContainer->addElement(
71         new BinaryControl(*this,
72                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
73                 "Out34Mute", "Out3/4 Mute", "Output 3/4 Mute"));
74     result &= m_MixerContainer->addElement(
75         new BinaryControl(*this,
76                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
77                 "Out56Mute", "Out5/6 Mute", "Output 5/6 Mute"));
78     result &= m_MixerContainer->addElement(
79         new BinaryControl(*this,
80                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
81                 "Out78Mute", "Out7/8 Mute", "Output 7/8 Mute"));
82     result &= m_MixerContainer->addElement(
83         new BinaryControl(*this,
84                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT910, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
85                 "Out910Mute", "Out9/10 Mute", "Output 9/10 Mute"));
86
87     // output front panel hw volume control
88     result &= m_MixerContainer->addElement(
89         new BinaryControl(*this,
90                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
91                 "Out12HwCtrl", "Out1/2 HwCtrl", "Output 1/2 Front Panel Hardware volume control"));
92     result &= m_MixerContainer->addElement(
93         new BinaryControl(*this,
94                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
95                 "Out34HwCtrl", "Out3/4 HwCtrl", "Output 3/4 Front Panel Hardware volume control"));
96     result &= m_MixerContainer->addElement(
97         new BinaryControl(*this,
98                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
99                 "Out56HwCtrl", "Out5/6 HwCtrl", "Output 5/6 Front Panel Hardware volume control"));
100     result &= m_MixerContainer->addElement(
101         new BinaryControl(*this,
102                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
103                 "Out78HwCtrl", "Out7/8 HwCtrl", "Output 7/8 Front Panel Hardware volume control"));
104    
105     // output level dim
106     result &= m_MixerContainer->addElement(
107         new BinaryControl(*this,
108                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DIM,
109                 "Out12Dim", "Out1/2 Dim", "Output 1/2 Level Dim"));
110
111     // output level controls
112     result &= m_MixerContainer->addElement(
113         new VolumeControlLowRes(*this,
114                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, 0,
115                 "Out12Level", "Out1/2 Level", "Output 1/2 Level"));
116     result &= m_MixerContainer->addElement(
117         new VolumeControlLowRes(*this,
118                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, 0,
119                 "Out34Level", "Out3/4 Level", "Output 3/4 Level"));
120     result &= m_MixerContainer->addElement(
121         new VolumeControlLowRes(*this,
122                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, 0,
123                 "Out56Level", "Out5/6 Level", "Output 5/6 Level"));
124     result &= m_MixerContainer->addElement(
125         new VolumeControlLowRes(*this,
126                 FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, 0,
127                 "Out78Level", "Out7/8 Level", "Output 7/8 Level"));
128    
129     // matrix mix controls
130     result &= m_MixerContainer->addElement(
131         new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_InputMix, "InputMix"));
132
133     result &= m_MixerContainer->addElement(
134         new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_PCMix, "PCMix"));
135
136
137     if (!result) {
138         debugWarning("One or more control elements could not be created.");
139         // clean up those that couldn't be created
140         destroyMixer();
141         return false;
142     }
143
144     if (!addElement(m_MixerContainer)) {
145         debugWarning("Could not register mixer to device\n");
146         // clean up
147         destroyMixer();
148         return false;
149     }
150
151     return true;
152 }
153
154 bool
155 SaffireDevice::destroyMixer()
156 {
157     debugOutput(DEBUG_LEVEL_VERBOSE, "destroy mixer...\n");
158    
159     if (m_MixerContainer == NULL) {
160         debugOutput(DEBUG_LEVEL_VERBOSE, "no mixer to destroy...\n");
161         return true;
162     }
163    
164     if (!deleteElement(m_MixerContainer)) {
165         debugError("Mixer present but not registered to the avdevice\n");
166         return false;
167     }
168    
169     // remove and delete (as in free) child control elements
170     m_MixerContainer->clearElements(true);
171     delete m_MixerContainer;
172     return true;
173 }
174
175 void
176 SaffireDevice::showDevice()
177 {
178     debugOutput(DEBUG_LEVEL_NORMAL, "This is a BeBoB::Focusrite::SaffireDevice\n");
179     FocusriteDevice::showDevice();
180 }
181
182 void
183 SaffireDevice::setVerboseLevel(int l)
184 {
185     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
186
187     FocusriteDevice::setVerboseLevel(l);
188 }
189
190 // Saffire pro matrix mixer element
191
192 SaffireMatrixMixer::SaffireMatrixMixer(SaffireDevice& p,
193                                        enum eMatrixMixerType type)
194 : FocusriteMatrixMixer(p, "MatrixMixer")
195 , m_type(type)
196 {
197     init();
198 }
199
200 SaffireMatrixMixer::SaffireMatrixMixer(SaffireDevice& p,
201                                        enum eMatrixMixerType type, std::string n)
202 : FocusriteMatrixMixer(p, n)
203 , m_type(type)
204 {
205     init();
206 }
207
208 void SaffireMatrixMixer::init()
209 {
210     if (m_type==eMMT_PCMix) {
211         addSignalInfo(m_RowInfo, "PC12", "PC 1/2", "PC Channel 1/2");
212         addSignalInfo(m_RowInfo, "PC34", "PC 3/4", "PC Channel 3/4");
213         addSignalInfo(m_RowInfo, "PC56", "PC 5/6", "PC Channel 5/6");
214         addSignalInfo(m_RowInfo, "PC78", "PC 7/8", "PC Channel 7/8");
215         addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10");
216        
217         addSignalInfo(m_ColInfo, "OUT12", "OUT 1/2", "Output 1/2");
218         addSignalInfo(m_ColInfo, "OUT34", "OUT 3/4", "Output 3/4");
219         addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6");
220         addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8");
221         addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10");
222        
223         // init the cell matrix
224         #define FOCUSRITE_SAFFIRE_PCMIX_NB_COLS 5
225         #define FOCUSRITE_SAFFIRE_PCMIX_NB_ROWS 5
226        
227         std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_PCMIX_NB_COLS );
228         std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_PCMIX_NB_ROWS, tmp_cols);
229         m_CellInfo = tmp_all;
230    
231         struct sCellInfo c;
232         c.row=-1;
233         c.col=-1;
234         c.valid=false;
235         c.address=0;
236        
237         for (int i=0;i<FOCUSRITE_SAFFIRE_PCMIX_NB_ROWS;i++) {
238             for (int j=0;j<FOCUSRITE_SAFFIRE_PCMIX_NB_COLS;j++) {
239                 m_CellInfo[i][j]=c;
240             }
241         }
242    
243         // now set the cells that are valid
244         setCellInfo(0,0,FR_SAFFIRE_CMD_ID_PC12_TO_OUT12, true);
245         setCellInfo(0,1,FR_SAFFIRE_CMD_ID_PC12_TO_OUT34, true);
246         setCellInfo(0,2,FR_SAFFIRE_CMD_ID_PC12_TO_OUT56, true);
247         setCellInfo(0,3,FR_SAFFIRE_CMD_ID_PC12_TO_OUT79, true);
248         setCellInfo(0,4,FR_SAFFIRE_CMD_ID_PC12_TO_OUT910, true);
249         setCellInfo(1,0,FR_SAFFIRE_CMD_ID_PC34_TO_OUT12, true);
250         setCellInfo(1,1,FR_SAFFIRE_CMD_ID_PC34_TO_OUT34, true);
251         setCellInfo(1,2,FR_SAFFIRE_CMD_ID_PC34_TO_OUT56, true);
252         setCellInfo(1,3,FR_SAFFIRE_CMD_ID_PC34_TO_OUT79, true);
253         setCellInfo(1,4,FR_SAFFIRE_CMD_ID_PC34_TO_OUT910, true);
254         setCellInfo(2,0,FR_SAFFIRE_CMD_ID_PC56_TO_OUT12, true);
255         setCellInfo(2,1,FR_SAFFIRE_CMD_ID_PC56_TO_OUT34, true);
256         setCellInfo(2,2,FR_SAFFIRE_CMD_ID_PC56_TO_OUT56, true);
257         setCellInfo(2,3,FR_SAFFIRE_CMD_ID_PC56_TO_OUT79, true);
258         setCellInfo(2,4,FR_SAFFIRE_CMD_ID_PC56_TO_OUT910, true);
259         setCellInfo(3,0,FR_SAFFIRE_CMD_ID_PC78_TO_OUT12, true);
260         setCellInfo(3,1,FR_SAFFIRE_CMD_ID_PC78_TO_OUT34, true);
261         setCellInfo(3,2,FR_SAFFIRE_CMD_ID_PC78_TO_OUT56, true);
262         setCellInfo(3,3,FR_SAFFIRE_CMD_ID_PC78_TO_OUT79, true);
263         setCellInfo(3,4,FR_SAFFIRE_CMD_ID_PC78_TO_OUT910, true);
264         setCellInfo(4,0,FR_SAFFIRE_CMD_ID_PC910_TO_OUT12, true);
265         setCellInfo(4,1,FR_SAFFIRE_CMD_ID_PC910_TO_OUT34, true);
266         setCellInfo(4,2,FR_SAFFIRE_CMD_ID_PC910_TO_OUT56, true);
267         setCellInfo(4,3,FR_SAFFIRE_CMD_ID_PC910_TO_OUT79, true);
268         setCellInfo(4,4,FR_SAFFIRE_CMD_ID_PC910_TO_OUT910, true);
269
270     } else if (m_type==eMMT_InputMix) {
271         addSignalInfo(m_RowInfo, "IN1", "Input 1", "Analog Input 1");
272         addSignalInfo(m_RowInfo, "IN2", "Input 2", "Analog Input 2");
273         addSignalInfo(m_RowInfo, "SPDIFL", "SPDIF L", "S/PDIF Left Input");
274         addSignalInfo(m_RowInfo, "SPDIFR", "SPDIF R", "S/PDIF Right Input");
275         addSignalInfo(m_RowInfo, "REV1", "REVERB 1", "Reverb CH1 return");
276         addSignalInfo(m_RowInfo, "REV1", "REVERB 2", "Reverb CH2 return");
277        
278         addSignalInfo(m_ColInfo, "OUT1", "OUT 1", "Output 1");
279         addSignalInfo(m_ColInfo, "OUT2", "OUT 2", "Output 2");
280         addSignalInfo(m_ColInfo, "OUT3", "OUT 3", "Output 3");
281         addSignalInfo(m_ColInfo, "OUT4", "OUT 4", "Output 4");
282         addSignalInfo(m_ColInfo, "OUT5", "OUT 5", "Output 5");
283         addSignalInfo(m_ColInfo, "OUT6", "OUT 6", "Output 6");
284         addSignalInfo(m_ColInfo, "OUT7", "OUT 7", "Output 7");
285         addSignalInfo(m_ColInfo, "OUT8", "OUT 8", "Output 8");
286         addSignalInfo(m_ColInfo, "OUT9", "OUT 9", "Output 9");
287         addSignalInfo(m_ColInfo, "OUT10", "OUT 10", "Output 10");
288        
289         // init the cell matrix
290         #define FOCUSRITE_SAFFIRE_INPUTMIX_NB_COLS 10
291         #define FOCUSRITE_SAFFIRE_INPUTMIX_NB_ROWS 6
292        
293         std::vector<struct sCellInfo> tmp_cols( FOCUSRITE_SAFFIRE_INPUTMIX_NB_COLS );
294         std::vector< std::vector<struct sCellInfo> > tmp_all(FOCUSRITE_SAFFIRE_INPUTMIX_NB_ROWS,tmp_cols);
295         m_CellInfo = tmp_all;
296    
297         struct sCellInfo c;
298         c.row=-1;
299         c.col=-1;
300         c.valid=false;
301         c.address=0;
302        
303         for (int i=0;i<FOCUSRITE_SAFFIRE_INPUTMIX_NB_ROWS;i++) {
304             for (int j=0;j<FOCUSRITE_SAFFIRE_INPUTMIX_NB_COLS;j++) {
305                 m_CellInfo[i][j]=c;
306             }
307         }
308
309         // now set the cells that are valid
310         setCellInfo(0,0,FR_SAFFIRE_CMD_ID_IN1_TO_OUT1, true);
311         setCellInfo(0,2,FR_SAFFIRE_CMD_ID_IN1_TO_OUT3, true);
312         setCellInfo(0,4,FR_SAFFIRE_CMD_ID_IN1_TO_OUT5, true);
313         setCellInfo(0,6,FR_SAFFIRE_CMD_ID_IN1_TO_OUT7, true);
314         setCellInfo(0,8,FR_SAFFIRE_CMD_ID_IN1_TO_OUT9, true);
315         setCellInfo(1,1,FR_SAFFIRE_CMD_ID_IN2_TO_OUT2, true);
316         setCellInfo(1,3,FR_SAFFIRE_CMD_ID_IN2_TO_OUT4, true);
317         setCellInfo(1,5,FR_SAFFIRE_CMD_ID_IN2_TO_OUT6, true);
318         setCellInfo(1,7,FR_SAFFIRE_CMD_ID_IN2_TO_OUT8, true);
319         setCellInfo(1,9,FR_SAFFIRE_CMD_ID_IN2_TO_OUT10, true);
320         setCellInfo(2,0,FR_SAFFIRE_CMD_ID_IN3_TO_OUT1, true);
321         setCellInfo(2,2,FR_SAFFIRE_CMD_ID_IN3_TO_OUT3, true);
322         setCellInfo(2,4,FR_SAFFIRE_CMD_ID_IN3_TO_OUT5, true);
323         setCellInfo(2,6,FR_SAFFIRE_CMD_ID_IN3_TO_OUT7, true);
324         setCellInfo(2,8,FR_SAFFIRE_CMD_ID_IN3_TO_OUT9, true);
325         setCellInfo(3,1,FR_SAFFIRE_CMD_ID_IN4_TO_OUT2, true);
326         setCellInfo(3,3,FR_SAFFIRE_CMD_ID_IN4_TO_OUT4, true);
327         setCellInfo(3,5,FR_SAFFIRE_CMD_ID_IN4_TO_OUT6, true);
328         setCellInfo(3,7,FR_SAFFIRE_CMD_ID_IN4_TO_OUT8, true);
329         setCellInfo(3,9,FR_SAFFIRE_CMD_ID_IN4_TO_OUT10, true);
330
331         setCellInfo(4,0,FR_SAFFIRE_CMD_ID_REV1_TO_OUT1, true);
332         setCellInfo(5,1,FR_SAFFIRE_CMD_ID_REV2_TO_OUT2, true);
333         setCellInfo(4,2,FR_SAFFIRE_CMD_ID_REV1_TO_OUT3, true);
334         setCellInfo(5,3,FR_SAFFIRE_CMD_ID_REV2_TO_OUT4, true);
335         setCellInfo(4,4,FR_SAFFIRE_CMD_ID_REV1_TO_OUT5, true);
336         setCellInfo(5,5,FR_SAFFIRE_CMD_ID_REV2_TO_OUT6, true);
337         setCellInfo(4,6,FR_SAFFIRE_CMD_ID_REV1_TO_OUT7, true);
338         setCellInfo(5,7,FR_SAFFIRE_CMD_ID_REV2_TO_OUT8, true);
339         setCellInfo(4,8,FR_SAFFIRE_CMD_ID_REV1_TO_OUT9, true);
340         setCellInfo(5,9,FR_SAFFIRE_CMD_ID_REV2_TO_OUT10, true);
341
342     } else {
343         debugError("Invalid mixer type\n");
344     }
345 }
346
347 void SaffireMatrixMixer::show()
348 {
349     debugOutput(DEBUG_LEVEL_NORMAL, "Saffire Pro Matrix mixer type %d\n");
350 }
351
352 } // Focusrite
353 } // BeBoB
Note: See TracBrowser for help on using the browser.