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

Revision 664, 14.3 kB (checked in by ppalmers, 15 years ago)

- Simplify EFC mixer control
- Implement FireWorks? generic mixer

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