root/trunk/libffado/src/bebob/bebob_mixer.cpp

Revision 975, 12.1 kB (checked in by ppalmers, 16 years ago)

fix debug message verbose level

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 "bebob/bebob_mixer.h"
25
26 #include "bebob/bebob_avdevice.h"
27 #include "bebob/bebob_avdevice_subunit.h"
28
29 #include "libavc/audiosubunit/avc_function_block.h"
30 #include "libutil/cmd_serialize.h"
31
32 #include "libcontrol/BasicElements.h"
33
34 #include "libieee1394/ieee1394service.h"
35 #include "libieee1394/configrom.h"
36
37 #include <string>
38 #include <sstream>
39 #include <iostream>
40
41 #include <assert.h>
42
43 using namespace AVC;
44
45 namespace BeBoB {
46
47 template <class T>
48 bool from_string(T& t,
49                  const std::string& s,
50                  std::ios_base& (*f)(std::ios_base&))
51 {
52   std::istringstream iss(s);
53   return !(iss >> f >> t).fail();
54 }
55
56 IMPL_DEBUG_MODULE( Mixer, Mixer, DEBUG_LEVEL_NORMAL );
57
58 Mixer::Mixer(AvDevice &d)
59     : Control::Container()
60     , m_device(d)
61 {
62     addElementForAllFunctionBlocks();
63     if (!d.addElement(this)) {
64         debugWarning("Could not add myself to Control::Container\n");
65     }
66 }
67
68 Mixer::~Mixer() {
69    
70     debugOutput(DEBUG_LEVEL_VERBOSE,"Unregistering from Control::Container...\n");
71     if (!m_device.deleteElement(this)) {
72         debugWarning("Could not delete myself from Control::Container\n");
73     }
74    
75     // delete all our elements since we should have created
76     // them ourselves.
77     for ( Control::ElementVectorIterator it = m_Children.begin();
78       it != m_Children.end();
79       ++it )
80     {
81         debugOutput(DEBUG_LEVEL_NORMAL,"deleting %s...\n", (*it)->getName().c_str());
82         delete *it;
83     }
84 }
85
86 bool
87 Mixer::deleteElement(Element *e)
88 {
89     if (Control::Container::deleteElement(e)) {
90         delete e;
91         return true;
92     } else return false;
93 }
94
95 bool
96 Mixer::clearElements() {
97     // delete all our elements since we should have created
98     // them ourselves.
99     for ( Control::ElementVectorIterator it = m_Children.begin();
100       it != m_Children.end();
101       ++it )
102     {
103         delete *it;
104     }
105     m_Children.clear();
106    
107     return true;
108 }
109
110 bool
111 Mixer::addElementForFunctionBlock(FunctionBlock& b) {
112     bool retval=true;
113    
114     std::ostringstream ostrm;
115     ostrm << b.getName() << "_" << (int)(b.getId());
116    
117     debugOutput(DEBUG_LEVEL_NORMAL,"Adding element for functionblock %s...\n",
118         ostrm.str().c_str());
119
120     Control::Element *e=NULL;
121    
122     if (dynamic_cast<FunctionBlockSelector *>(&b) != NULL) {
123         FunctionBlockSelector *bf=dynamic_cast<FunctionBlockSelector *>(&b);
124         debugOutput( DEBUG_LEVEL_VERBOSE, "FB is a SelectorFunctionBlock\n");
125         e=new MixerFBSelector(*this, *bf);
126         if (e) {
127             e->setVerboseLevel(getDebugLevel());
128             retval &= Control::Container::addElement(e);
129         } else {
130             debugError("Control element creation failed\n");
131             retval &= false;
132         }
133     }
134     if (dynamic_cast<FunctionBlockFeature *>(&b) != NULL) {
135         FunctionBlockFeature *bf=dynamic_cast<FunctionBlockFeature *>(&b);
136         debugOutput( DEBUG_LEVEL_VERBOSE, "FB is a FeatureFunctionBlock\n");
137         e=new MixerFBFeature(*this, *bf);
138         if (e) {
139             e->setVerboseLevel(getDebugLevel());
140             retval &= Control::Container::addElement(e);
141         } else {
142             debugError("Control element creation failed\n");
143             retval &= false;
144         }
145     }
146
147     if (dynamic_cast<FunctionBlockEnhancedMixer *>(&b) != NULL) {
148         FunctionBlockEnhancedMixer *bf=dynamic_cast<FunctionBlockEnhancedMixer *>(&b);
149         debugOutput( DEBUG_LEVEL_VERBOSE, "FB is a FunctionBlockEnhancedMixer\n");
150         e=new EnhancedMixerFBFeature(*this, *bf);
151         if (e) {
152             e->setVerboseLevel(getDebugLevel());
153             retval &= Control::Container::addElement(e);
154         } else {
155             debugError("Control element creation failed\n");
156             retval &= false;
157         }
158     }
159    
160     if (!e) {
161         debugError("No control element created\n");
162         return false;
163     }
164
165     return retval;
166 }
167
168 bool
169 Mixer::addElementForAllFunctionBlocks() {
170     debugOutput(DEBUG_LEVEL_NORMAL,"Adding elements for functionblocks...\n");
171
172     BeBoB::SubunitAudio *asu =
173         dynamic_cast<BeBoB::SubunitAudio *>(m_device.getAudioSubunit(0));
174
175     if(asu == NULL) {
176         debugWarning("No BeBoB audio subunit found\n");
177         return false;
178     }
179     FunctionBlockVector functions=asu->getFunctionBlocks();
180
181     for ( FunctionBlockVector::iterator it = functions.begin();
182           it != functions.end();
183           ++it )
184     {
185         if (!addElementForFunctionBlock(*(*it))) {
186             std::ostringstream ostrm;
187             ostrm << (*it)->getName() << " " << (int)((*it)->getId());
188            
189             debugWarning("Failed to add element for function block %s\n",
190                 ostrm.str().c_str());
191         };
192     }
193     return true;
194 }
195
196 // --- element implementation classes
197
198 MixerFBFeature::MixerFBFeature(Mixer& parent, FunctionBlockFeature& s)
199 : Control::Continuous()
200 , m_Parent(parent)
201 , m_Slave(s)
202 {
203     std::ostringstream ostrm;
204     ostrm << s.getName() << "_" << (int)(s.getId());
205    
206     Control::Continuous::setName(ostrm.str());
207    
208     ostrm.str("");
209     ostrm << "Label for " << s.getName() << " " << (int)(s.getId());
210     setLabel(ostrm.str());
211    
212     ostrm.str("");
213     ostrm << "Description for " << s.getName() << " " << (int)(s.getId());
214     setDescription(ostrm.str());
215 }
216
217 bool
218 MixerFBFeature::setValue(double v)
219 {
220     return setValue(0, v);
221 }
222
223 bool
224 MixerFBFeature::setValue(int idx, double v)
225 {
226     int volume=(int)v;
227     debugOutput(DEBUG_LEVEL_NORMAL,"Set feature volume %d to %d...\n",
228         m_Slave.getId(), volume);
229
230     FunctionBlockCmd fbCmd( m_Parent.getParent().get1394Service(),
231                             FunctionBlockCmd::eFBT_Feature,
232                             m_Slave.getId(),
233                             FunctionBlockCmd::eCA_Current );
234     fbCmd.setNodeId( m_Parent.getParent().getNodeId() );
235     fbCmd.setSubunitId( 0x00 );
236     fbCmd.setCommandType( AVCCommand::eCT_Control );
237     fbCmd.m_pFBFeature->m_audioChannelNumber=idx; // m_channel
238     fbCmd.m_pFBFeature->m_controlSelector=FunctionBlockFeature::eCSE_Feature_Volume;
239     fbCmd.m_pFBFeature->m_pVolume->m_volume=volume;
240     fbCmd.setVerboseLevel( DEBUG_LEVEL_VERY_VERBOSE );
241
242     if ( !fbCmd.fire() ) {
243         debugError( "cmd failed\n" );
244         return false;
245     }
246
247 //     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
248 //         Util::CoutSerializer se;
249 //         fbCmd.serialize( se );
250 //     }
251    
252     if((fbCmd.getResponse() != AVCCommand::eR_Accepted)) {
253         debugWarning("fbCmd.getResponse() != AVCCommand::eR_Accepted\n");
254     }
255
256     return (fbCmd.getResponse() == AVCCommand::eR_Accepted);
257 }
258
259 double
260 MixerFBFeature::getValue()
261 {
262     return getValue(0);
263 }
264
265 double
266 MixerFBFeature::getValue(int idx)
267 {
268     debugOutput(DEBUG_LEVEL_NORMAL,"Get feature volume %d...\n",
269         m_Slave.getId());
270
271     FunctionBlockCmd fbCmd( m_Parent.getParent().get1394Service(),
272                             FunctionBlockCmd::eFBT_Feature,
273                             m_Slave.getId(),
274                             FunctionBlockCmd::eCA_Current );
275     fbCmd.setNodeId( m_Parent.getParent().getNodeId() );
276     fbCmd.setSubunitId( 0x00 );
277     fbCmd.setCommandType( AVCCommand::eCT_Status );
278     fbCmd.m_pFBFeature->m_audioChannelNumber=idx;
279     fbCmd.m_pFBFeature->m_controlSelector=FunctionBlockFeature::eCSE_Feature_Volume; // FIXME
280     fbCmd.m_pFBFeature->m_pVolume->m_volume=0;
281     fbCmd.setVerboseLevel( DEBUG_LEVEL_VERY_VERBOSE );
282
283     if ( !fbCmd.fire() ) {
284         debugError( "cmd failed\n" );
285         return 0;
286     }
287    
288 //     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
289 //         Util::CoutSerializer se;
290 //         fbCmd.serialize( se );
291 //     }
292
293     if((fbCmd.getResponse() != AVCCommand::eR_Implemented)) {
294         debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
295     }
296    
297     int16_t volume=(int16_t)(fbCmd.m_pFBFeature->m_pVolume->m_volume);
298    
299     return volume;
300 }
301
302 // --- element implementation classes
303
304 EnhancedMixerFBFeature::EnhancedMixerFBFeature(Mixer& parent, FunctionBlockEnhancedMixer& s)
305 : Control::Continuous()
306 , m_Parent(parent)
307 , m_Slave(s)
308 {
309     std::ostringstream ostrm;
310     ostrm << s.getName() << "_" << (int)(s.getId());
311    
312     Control::Continuous::setName(ostrm.str());
313    
314     ostrm.str("");
315     ostrm << "Label for " << s.getName() << " " << (int)(s.getId());
316     setLabel(ostrm.str());
317    
318     ostrm.str("");
319     ostrm << "Description for " << s.getName() << " " << (int)(s.getId());
320     setDescription(ostrm.str());
321 }
322
323 bool
324 EnhancedMixerFBFeature::setValue(double v)
325 {
326     int volume=(int)v;
327     debugOutput(DEBUG_LEVEL_NORMAL,"Set feature volume %d to %d...\n",
328                 m_Slave.getId(), volume);
329
330     return true;
331 }
332
333 double
334 EnhancedMixerFBFeature::getValue()
335 {
336     debugOutput(DEBUG_LEVEL_NORMAL,"Get feature volume %d...\n",
337                 m_Slave.getId());
338
339     return 0;
340 }
341
342 // --- element implementation classes
343
344 MixerFBSelector::MixerFBSelector(Mixer& parent, FunctionBlockSelector& s)
345 : Control::Discrete()
346 , m_Parent(parent)
347 , m_Slave(s)
348 {
349     std::ostringstream ostrm;
350     ostrm << s.getName() << "_" << (int)(s.getId());
351    
352     Control::Discrete::setName(ostrm.str());
353    
354     ostrm.str("");
355     ostrm << "Label for " << s.getName() << " " << (int)(s.getId());
356     setLabel(ostrm.str());
357    
358     ostrm.str("");
359     ostrm << "Description for " << s.getName() << " " << (int)(s.getId());
360     setDescription(ostrm.str());
361 }
362
363 bool
364 MixerFBSelector::setValue(int v)
365 {
366     debugOutput(DEBUG_LEVEL_NORMAL,"Set selector %d to %d...\n",
367         m_Slave.getId(), v);
368
369     FunctionBlockCmd fbCmd( m_Parent.getParent().get1394Service(),
370                             FunctionBlockCmd::eFBT_Selector,
371                             m_Slave.getId(),
372                             FunctionBlockCmd::eCA_Current );
373     fbCmd.setNodeId( m_Parent.getParent().getNodeId() );
374     fbCmd.setSubunitId( 0x00 );
375     fbCmd.setCommandType( AVCCommand::eCT_Control );
376     fbCmd.m_pFBSelector->m_inputFbPlugNumber=(v & 0xFF);
377     fbCmd.setVerboseLevel( DEBUG_LEVEL_VERY_VERBOSE );
378
379     if ( !fbCmd.fire() ) {
380         debugError( "cmd failed\n" );
381         return false;
382     }
383
384 //     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
385 //         Util::CoutSerializer se;
386 //         fbCmd.serialize( se );
387 //     }
388 //     
389     if((fbCmd.getResponse() != AVCCommand::eR_Accepted)) {
390         debugWarning("fbCmd.getResponse() != AVCCommand::eR_Accepted\n");
391     }
392
393     return (fbCmd.getResponse() == AVCCommand::eR_Accepted);
394 }
395
396 int
397 MixerFBSelector::getValue()
398 {
399     debugOutput(DEBUG_LEVEL_NORMAL,"Get selector %d...\n",
400         m_Slave.getId());
401
402     FunctionBlockCmd fbCmd( m_Parent.getParent().get1394Service(),
403                             FunctionBlockCmd::eFBT_Selector,
404                             m_Slave.getId(),
405                             FunctionBlockCmd::eCA_Current );
406     fbCmd.setNodeId( m_Parent.getParent().getNodeId()  );
407     fbCmd.setSubunitId( 0x00 );
408     fbCmd.setCommandType( AVCCommand::eCT_Status );
409     fbCmd.m_pFBSelector->m_inputFbPlugNumber=0;
410     fbCmd.setVerboseLevel( DEBUG_LEVEL_VERY_VERBOSE );
411
412     if ( !fbCmd.fire() ) {
413         debugError( "cmd failed\n" );
414         return 0;
415     }
416    
417 //     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
418 //         Util::CoutSerializer se;
419 //         fbCmd.serialize( se );
420 //     }
421
422     if((fbCmd.getResponse() != AVCCommand::eR_Implemented)) {
423         debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
424     }
425    
426     return fbCmd.m_pFBSelector->m_inputFbPlugNumber;
427 }
428
429
430 } // end of namespace BeBoB
Note: See TracBrowser for help on using the browser.