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

Revision 648, 16.8 kB (checked in by ppalmers, 15 years ago)

rename saffire pro device implementation file to ease normal saffire implementation

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