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

Revision 622, 15.8 kB (checked in by ppalmers, 17 years ago)

improve samplerate setting for the focusrite

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_device.h"
25 #include "focusrite_cmd.h"
26
27 namespace BeBoB {
28 namespace Focusrite {
29
30 SaffireProDevice::SaffireProDevice( Ieee1394Service& ieee1394Service,
31                             std::auto_ptr<ConfigRom>( configRom ))
32     : BeBoB::AvDevice( ieee1394Service, configRom)
33 {
34     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Focusrite::SaffireProDevice (NodeID %d)\n",
35                  getConfigRom().getNodeId() );
36
37     // create control objects for the saffire pro
38     m_Phantom1 = new BinaryControl(*this, FOCUSRITE_CMD_ID_PHANTOM14,
39                  "Phantom_1to4", "Phantom 1-4", "Switch Phantom Power on channels 1-4");
40     if (m_Phantom1) addElement(m_Phantom1);
41    
42     m_Phantom2 = new BinaryControl(*this, FOCUSRITE_CMD_ID_PHANTOM58,
43                  "Phantom_5to8", "Phantom 5-8", "Switch Phantom Power on channels 5-8");
44     if (m_Phantom2) addElement(m_Phantom2);
45    
46     m_Insert1 = new BinaryControl(*this, FOCUSRITE_CMD_ID_INSERT1,
47                 "Insert1", "Insert 1", "Switch Insert on Channel 1");
48     if (m_Insert1) addElement(m_Insert1);
49    
50     m_Insert2 = new BinaryControl(*this, FOCUSRITE_CMD_ID_INSERT2,
51                 "Insert2", "Insert 2", "Switch Insert on Channel 2");
52     if (m_Insert2) addElement(m_Insert2);
53    
54     m_AC3pass = new BinaryControl(*this, FOCUSRITE_CMD_ID_AC3_PASSTHROUGH,
55                 "AC3pass", "AC3 Passtrough", "Enable AC3 Passthrough");
56     if (m_AC3pass) addElement(m_AC3pass);
57    
58     m_MidiTru = new BinaryControl(*this, FOCUSRITE_CMD_ID_MIDI_TRU,
59                 "MidiTru", "Midi Tru", "Enable Midi Tru");
60     if (m_MidiTru) addElement(m_MidiTru);
61
62     // output mix controls
63     //  OUT12
64     m_Output12[0] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC1_TO_OUT1,
65                 "PC1_OUT1", "PC1_OUT1", "Volume from PC Channel 1 to Output Channel 1");
66     if (m_Output12[0]) addElement(m_Output12[0]);
67     m_Output12[1] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC2_TO_OUT2,
68                 "PC2_OUT2", "PC2_OUT2", "Volume from PC Channel 2 to Output Channel 2");
69     if (m_Output12[1]) addElement(m_Output12[1]);
70     m_Output12[2] = new VolumeControl(*this, FOCUSRITE_CMD_ID_MIX1_TO_OUT1,
71                 "MIX_OUT1", "MIX_OUT1", "Volume from Input Mix Left to Output Channel 1");
72     if (m_Output12[2]) addElement(m_Output12[2]);
73     m_Output12[3] = new VolumeControl(*this, FOCUSRITE_CMD_ID_MIX2_TO_OUT2,
74                 "MIX_OUT2", "MIX_OUT2", "Volume from Input Mix Right to Output Channel 2");
75     if (m_Output12[3]) addElement(m_Output12[3]);
76
77     //  OUT34
78     m_Output34[0] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC1_TO_OUT3,
79                 "PC1_OUT3", "PC1_OUT3", "Volume from PC Channel 1 to Output Channel 3");
80     if (m_Output34[0]) addElement(m_Output34[0]);
81     m_Output34[1] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC2_TO_OUT4,
82                 "PC2_OUT4", "PC2_OUT4", "Volume from PC Channel 2 to Output Channel 4");
83     if (m_Output34[1]) addElement(m_Output34[1]);
84     m_Output34[2] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC3_TO_OUT3,
85                 "PC3_OUT3", "PC3_OUT3", "Volume from PC Channel 3 to Output Channel 3");
86     if (m_Output34[2]) addElement(m_Output34[2]);
87     m_Output34[3] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC4_TO_OUT4,
88                 "PC4_OUT4", "PC4_OUT4", "Volume from PC Channel 4 to Output Channel 4");
89     if (m_Output34[3]) addElement(m_Output34[3]);
90     m_Output34[4] = new VolumeControl(*this, FOCUSRITE_CMD_ID_MIX1_TO_OUT3,
91                 "MIX_OUT3", "MIX_OUT3", "Volume from Input Mix Left to Output Channel 3");
92     if (m_Output34[4]) addElement(m_Output34[4]);
93     m_Output34[5] = new VolumeControl(*this, FOCUSRITE_CMD_ID_MIX2_TO_OUT4,
94                 "MIX_OUT4", "MIX_OUT4", "Volume from Input Mix Right to Output Channel 4");
95     if (m_Output34[5]) addElement(m_Output34[5]);
96    
97     //  OUT56
98     m_Output56[0] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC1_TO_OUT5,
99                 "PC1_OUT5", "PC1_OUT5", "Volume from PC Channel 1 to Output Channel 5");
100     if (m_Output56[0]) addElement(m_Output56[0]);
101     m_Output56[1] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC2_TO_OUT6,
102                 "PC2_OUT6", "PC2_OUT6", "Volume from PC Channel 2 to Output Channel 6");
103     if (m_Output56[1]) addElement(m_Output56[1]);
104     m_Output56[2] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC5_TO_OUT5,
105                 "PC5_OUT5", "PC5_OUT5", "Volume from PC Channel 5 to Output Channel 5");
106     if (m_Output56[2]) addElement(m_Output56[2]);
107     m_Output56[3] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC6_TO_OUT6,
108                 "PC6_OUT6", "PC6_OUT6", "Volume from PC Channel 6 to Output Channel 6");
109     if (m_Output56[3]) addElement(m_Output56[3]);
110     m_Output56[4] = new VolumeControl(*this, FOCUSRITE_CMD_ID_MIX1_TO_OUT5,
111                 "MIX_OUT5", "MIX_OUT5", "Volume from Input Mix Left to Output Channel 5");
112     if (m_Output56[4]) addElement(m_Output56[4]);
113     m_Output56[5] = new VolumeControl(*this, FOCUSRITE_CMD_ID_MIX2_TO_OUT6,
114                 "MIX_OUT6", "MIX_OUT6", "Volume from Input Mix Right to Output Channel 6");
115     if (m_Output56[5]) addElement(m_Output56[5]);
116
117     //  OUT78
118     m_Output78[0] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC1_TO_OUT7,
119                 "PC1_OUT7", "PC1_OUT7", "Volume from PC Channel 1 to Output Channel 7");
120     if (m_Output78[0]) addElement(m_Output78[0]);
121     m_Output78[1] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC2_TO_OUT8,
122                 "PC2_OUT8", "PC2_OUT8", "Volume from PC Channel 2 to Output Channel 8");
123     if (m_Output78[1]) addElement(m_Output78[1]);
124     m_Output78[2] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC7_TO_OUT7,
125                 "PC7_OUT7", "PC7_OUT7", "Volume from PC Channel 7 to Output Channel 7");
126     if (m_Output78[2]) addElement(m_Output78[2]);
127     m_Output78[3] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC8_TO_OUT8,
128                 "PC8_OUT8", "PC8_OUT8", "Volume from PC Channel 8 to Output Channel 8");
129     if (m_Output78[3]) addElement(m_Output78[3]);
130     m_Output78[4] = new VolumeControl(*this, FOCUSRITE_CMD_ID_MIX1_TO_OUT7,
131                 "MIX_OUT7", "MIX_OUT7", "Volume from Input Mix Left to Output Channel 7");
132     if (m_Output78[4]) addElement(m_Output78[4]);
133     m_Output78[5] = new VolumeControl(*this, FOCUSRITE_CMD_ID_MIX2_TO_OUT8,
134                 "MIX_OUT8", "MIX_OUT8", "Volume from Input Mix Right to Output Channel 8");
135     if (m_Output78[5]) addElement(m_Output78[5]);
136
137     //  OUT910
138     m_Output910[0] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC1_TO_OUT9,
139                 "PC1_OUT9", "PC1_OUT9", "Volume from PC Channel 1 to Output Channel 9");
140     if (m_Output910[0]) addElement(m_Output910[0]);
141     m_Output910[1] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC2_TO_OUT10,
142                 "PC2_OUT10", "PC2_OUT10", "Volume from PC Channel 2 to Output Channel 10");
143     if (m_Output910[1]) addElement(m_Output910[1]);
144     m_Output910[2] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC9_TO_OUT9,
145                 "PC9_OUT9", "PC9_OUT9", "Volume from PC Channel 9 to Output Channel 9");
146     if (m_Output910[2]) addElement(m_Output910[2]);
147     m_Output910[3] = new VolumeControl(*this, FOCUSRITE_CMD_ID_PC10_TO_OUT10,
148                 "PC10_OUT10", "PC10_OUT10", "Volume from PC Channel 10 to Output Channel 10");
149     if (m_Output910[3]) addElement(m_Output910[3]);
150     m_Output910[4] = new VolumeControl(*this, FOCUSRITE_CMD_ID_MIX1_TO_OUT9,
151                 "MIX_OUT9", "MIX_OUT9", "Volume from Input Mix Left to Output Channel 9");
152     if (m_Output910[4]) addElement(m_Output910[4]);
153     m_Output910[5] = new VolumeControl(*this, FOCUSRITE_CMD_ID_MIX2_TO_OUT10,
154                 "MIX_OUT10", "MIX_OUT10", "Volume from Input Mix Right to Output Channel 10");
155     if (m_Output910[5]) addElement(m_Output910[5]);
156
157 }
158
159 SaffireProDevice::~SaffireProDevice()
160 {
161     // remove and delete control elements
162     deleteElement(m_Phantom1);
163     if (m_Phantom1) delete m_Phantom1;
164    
165     deleteElement(m_Phantom2);
166     if (m_Phantom2) delete m_Phantom2;
167    
168     deleteElement(m_Insert1);
169     if (m_Insert1) delete m_Insert1;
170    
171     deleteElement(m_Insert2);
172     if (m_Insert2) delete m_Insert2;
173    
174     deleteElement(m_AC3pass);
175     if (m_AC3pass) delete m_AC3pass;
176    
177     deleteElement(m_MidiTru);
178     if (m_MidiTru) delete m_MidiTru;
179    
180     int i=0;
181     for (i=0;i<4;i++) {
182         deleteElement(m_Output12[i]);
183         if (m_Output12[i]) delete m_Output12[i];
184     }
185     for (i=0;i<6;i++) {
186         deleteElement(m_Output34[i]);
187         if (m_Output34[i]) delete m_Output34[i];
188     }
189     for (i=0;i<6;i++) {
190         deleteElement(m_Output56[i]);
191         if (m_Output56[i]) delete m_Output56[i];
192     }
193     for (i=0;i<6;i++) {
194         deleteElement(m_Output78[i]);
195         if (m_Output78[i]) delete m_Output78[i];
196     }
197     for (i=0;i<6;i++) {
198         deleteElement(m_Output910[i]);
199         if (m_Output910[i]) delete m_Output910[i];
200     }
201 }
202
203 void
204 SaffireProDevice::showDevice()
205 {
206     debugOutput(DEBUG_LEVEL_NORMAL, "This is a BeBoB::Focusrite::SaffireProDevice\n");
207     BeBoB::AvDevice::showDevice();
208 }
209
210 void
211 SaffireProDevice::setVerboseLevel(int l)
212 {
213     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
214
215     if (m_Phantom1) m_Phantom2->setVerboseLevel(l);
216     if (m_Phantom2) m_Phantom2->setVerboseLevel(l);
217
218     BeBoB::AvDevice::setVerboseLevel(l);
219 }
220
221 bool
222 SaffireProDevice::setSpecificValue(uint32_t id, uint32_t v)
223 {
224    
225     FocusriteVendorDependentCmd cmd( get1394Service() );
226     cmd.setCommandType( AVC::AVCCommand::eCT_Control );
227     cmd.setNodeId( getConfigRom().getNodeId() );
228     cmd.setSubunitType( AVC::eST_Unit  );
229     cmd.setSubunitId( 0xff );
230    
231     cmd.setVerbose( getDebugLevel() );
232         cmd.setVerbose( DEBUG_LEVEL_VERY_VERBOSE );
233    
234     cmd.m_id=id;
235     cmd.m_value=v;
236    
237     if ( !cmd.fire() ) {
238         debugError( "FocusriteVendorDependentCmd info command failed\n" );
239         return false;
240     }
241    
242     return true;
243 }
244
245 bool
246 SaffireProDevice::getSpecificValue(uint32_t id, uint32_t *v)
247 {
248    
249     FocusriteVendorDependentCmd cmd( get1394Service() );
250     cmd.setCommandType( AVC::AVCCommand::eCT_Status );
251     cmd.setNodeId( getConfigRom().getNodeId() );
252     cmd.setSubunitType( AVC::eST_Unit  );
253     cmd.setSubunitId( 0xff );
254    
255     cmd.setVerbose( getDebugLevel() );
256         cmd.setVerbose( DEBUG_LEVEL_VERY_VERBOSE );
257    
258     cmd.m_id=id;
259    
260     if ( !cmd.fire() ) {
261         debugError( "FocusriteVendorDependentCmd info command failed\n" );
262         return false;
263     }
264    
265     *v=cmd.m_value;
266
267     return true;
268 }
269
270 int
271 SaffireProDevice::getSamplingFrequency( ) {
272     uint32_t sr;
273    
274     if ( !getSpecificValue(FOCUSRITE_CMD_ID_SAMPLERATE, &sr ) ) {
275         debugError( "getSpecificValue failed\n" );
276         return 0;
277     }
278    
279     debugOutput( DEBUG_LEVEL_NORMAL,
280                      "getSampleRate: %d\n", sr );
281
282     switch(sr) {
283         case FOCUSRITE_CMD_SAMPLERATE_44K1:  return 44100;
284         case FOCUSRITE_CMD_SAMPLERATE_48K:   return 48000;
285         case FOCUSRITE_CMD_SAMPLERATE_88K2:  return 88200;
286         case FOCUSRITE_CMD_SAMPLERATE_96K:   return 96000;
287         case FOCUSRITE_CMD_SAMPLERATE_176K4: return 176400;
288         case FOCUSRITE_CMD_SAMPLERATE_192K:  return 192000;
289         default: return 0;
290     }
291 }
292
293 bool
294 SaffireProDevice::setSamplingFrequencyDo( int s )
295 {
296     uint32_t value;
297     switch(s) {
298         case 44100:  value=FOCUSRITE_CMD_SAMPLERATE_44K1;break;
299         case 48000:  value=FOCUSRITE_CMD_SAMPLERATE_48K;break;
300         case 88200:  value=FOCUSRITE_CMD_SAMPLERATE_88K2;break;
301         case 96000:  value=FOCUSRITE_CMD_SAMPLERATE_96K;break;
302         case 176400: value=FOCUSRITE_CMD_SAMPLERATE_176K4;break;
303         case 192000: value=FOCUSRITE_CMD_SAMPLERATE_192K;break;
304         default:
305             debugWarning("Unsupported samplerate: %d\n", s);
306             return false;
307     }
308
309
310     if ( !setSpecificValue(FOCUSRITE_CMD_ID_SAMPLERATE, value) ) {
311         debugError( "setSpecificValue failed\n" );
312         return false;
313     }
314     return true;
315 }
316
317 bool
318 SaffireProDevice::setSamplingFrequency( int s )
319 {
320     bool snoopMode=false;
321     if(!getOption("snoopMode", snoopMode)) {
322         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
323     }
324
325     if(snoopMode) {
326         int current_sr=getSamplingFrequency();
327         if (current_sr != s ) {
328             debugError("In snoop mode it is impossible to set the sample rate.\n");
329             debugError("Please start the client with the correct setting.\n");
330             return false;
331         }
332         return true;
333     } else {
334
335         if(!setSamplingFrequencyDo( s )) {
336             debugWarning("setSamplingFrequencyDo failed\n");
337         }
338        
339         // wait for a while
340         usleep(100 * 1000);
341         int verify=getSamplingFrequency();
342        
343         debugOutput( DEBUG_LEVEL_NORMAL,
344                      "setSampleRate: requested samplerate %d, device now has %d\n", s, verify );
345                      
346         if (s != verify) {
347             debugWarning("setting samplerate failed. trying again...\n");
348             if(!setSamplingFrequencyDo( s )) {
349                 debugWarning("setSamplingFrequencyDo failed\n");
350             }
351            
352             // wait for a while
353             usleep(100 * 1000);
354             verify=getSamplingFrequency();
355             debugOutput( DEBUG_LEVEL_NORMAL,
356                         "setSampleRate (2): requested samplerate %d, device now has %d\n", s, verify );
357             return (s==verify);
358         }
359         return true;
360     }
361     // not executable
362     return false;
363
364 }
365
366 // --- element implementation classes
367
368 BinaryControl::BinaryControl(SaffireProDevice& parent, int id)
369 : Control::Discrete()
370 , m_Parent(parent)
371 , m_cmd_id ( id )
372 {}
373 BinaryControl::BinaryControl(SaffireProDevice& parent, int id,
374                 std::string name, std::string label, std::string descr)
375 : Control::Discrete()
376 , m_Parent(parent)
377 , m_cmd_id ( id )
378 {
379     setName(name);
380     setLabel(label);
381     setDescription(descr);
382 }
383
384 bool
385 BinaryControl::setValue(int v)
386 {
387     uint32_t val=0;
388     if (v) val=1;
389
390     if ( !m_Parent.setSpecificValue(m_cmd_id, val) ) {
391         debugError( "setSpecificValue failed\n" );
392         return false;
393     } else return true;
394 }
395
396 int
397 BinaryControl::getValue()
398 {
399     uint32_t val=0;
400
401     if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) {
402         debugError( "getSpecificValue failed\n" );
403         return 0;
404     } else return val;
405 }
406
407 // --- element implementation classes
408
409 VolumeControl::VolumeControl(SaffireProDevice& parent, int id)
410 : Control::Discrete()
411 , m_Parent(parent)
412 , m_cmd_id ( id )
413 {}
414 VolumeControl::VolumeControl(SaffireProDevice& parent, int id,
415                 std::string name, std::string label, std::string descr)
416 : Control::Discrete()
417 , m_Parent(parent)
418 , m_cmd_id ( id )
419 {
420     setName(name);
421     setLabel(label);
422     setDescription(descr);
423 }
424
425
426 bool
427 VolumeControl::setValue(int v)
428 {
429     if (v>0x07FFF) v=0x07FFF;
430     else if (v<0) v=0;
431
432     if ( !m_Parent.setSpecificValue(m_cmd_id, v) ) {
433         debugError( "setSpecificValue failed\n" );
434         return false;
435     } else return true;
436 }
437
438 int
439 VolumeControl::getValue()
440 {
441     uint32_t val=0;
442
443     if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) {
444         debugError( "getSpecificValue failed\n" );
445         return 0;
446     } else return val;
447 }
448
449 } // Focusrite
450 } // BeBoB
Note: See TracBrowser for help on using the browser.