root/branches/libffado-2.0/src/bebob/bebob_mixer.cpp

Revision 1321, 8.9 kB (checked in by wagi, 12 years ago)

Implement getMinimum and getMaximum for the generic mixer.
This makes the input volume fader working for the FA-101.

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(&d)
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(&parent)
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     return m_Parent.getParent().setFeatureFBVolumeCurrent(m_Slave.getId(), idx, volume);
230 }
231
232 double
233 MixerFBFeature::getValue()
234 {
235     return getValue(0);
236 }
237
238 double
239 MixerFBFeature::getValue(int idx)
240 {
241     debugOutput(DEBUG_LEVEL_NORMAL,"Get feature volume %d...\n",
242         m_Slave.getId());
243
244     return m_Parent.getParent().getFeatureFBVolumeCurrent(m_Slave.getId(), idx);
245 }
246
247 double
248 MixerFBFeature::getMinimum()
249 {
250     debugOutput(DEBUG_LEVEL_NORMAL,"Get feature minimum volume %d...\n",
251         m_Slave.getId());
252
253     return m_Parent.getParent().getFeatureFBVolumeMinimum(m_Slave.getId(), 0);
254 }
255
256 double
257 MixerFBFeature::getMaximum()
258 {
259     debugOutput(DEBUG_LEVEL_NORMAL,"Get feature maximum volume %d...\n",
260         m_Slave.getId());
261
262     return m_Parent.getParent().getFeatureFBVolumeMaximum(m_Slave.getId(), 0);
263 }
264
265 // --- element implementation classes
266
267 EnhancedMixerFBFeature::EnhancedMixerFBFeature(Mixer& parent, FunctionBlockEnhancedMixer& s)
268 : Control::Continuous(&parent)
269 , m_Parent(parent)
270 , m_Slave(s)
271 {
272     std::ostringstream ostrm;
273     ostrm << s.getName() << "_" << (int)(s.getId());
274    
275     Control::Continuous::setName(ostrm.str());
276    
277     ostrm.str("");
278     ostrm << "Label for " << s.getName() << " " << (int)(s.getId());
279     setLabel(ostrm.str());
280    
281     ostrm.str("");
282     ostrm << "Description for " << s.getName() << " " << (int)(s.getId());
283     setDescription(ostrm.str());
284 }
285
286 bool
287 EnhancedMixerFBFeature::setValue(double v)
288 {
289     debugOutput(DEBUG_LEVEL_NORMAL,"Set feature volume %d to %d...\n",
290                 m_Slave.getId(), (int)v);
291
292     return true;
293 }
294
295 double
296 EnhancedMixerFBFeature::getValue()
297 {
298     debugOutput(DEBUG_LEVEL_NORMAL,"Get feature volume %d...\n",
299                 m_Slave.getId());
300
301     return 0;
302 }
303
304 // --- element implementation classes
305
306 MixerFBSelector::MixerFBSelector(Mixer& parent, FunctionBlockSelector& s)
307 : Control::Discrete(&parent)
308 , m_Parent(parent)
309 , m_Slave(s)
310 {
311     std::ostringstream ostrm;
312     ostrm << s.getName() << "_" << (int)(s.getId());
313    
314     Control::Discrete::setName(ostrm.str());
315    
316     ostrm.str("");
317     ostrm << "Label for " << s.getName() << " " << (int)(s.getId());
318     setLabel(ostrm.str());
319    
320     ostrm.str("");
321     ostrm << "Description for " << s.getName() << " " << (int)(s.getId());
322     setDescription(ostrm.str());
323 }
324
325 bool
326 MixerFBSelector::setValue(int v)
327 {
328     debugOutput(DEBUG_LEVEL_NORMAL,"Set selector %d to %d...\n",
329         m_Slave.getId(), v);
330     return m_Parent.getParent().setSelectorFBValue(m_Slave.getId(), v);
331 }
332
333 int
334 MixerFBSelector::getValue()
335 {
336     debugOutput(DEBUG_LEVEL_NORMAL,"Get selector %d...\n",
337         m_Slave.getId());
338     return m_Parent.getParent().getSelectorFBValue(m_Slave.getId());
339 }
340
341
342 } // end of namespace BeBoB
Note: See TracBrowser for help on using the browser.