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

Revision 451, 7.1 kB (checked in by ppalmers, 15 years ago)

- First attempt at a OSC controlled mixer. The level of

abstraction is very low, meaning that you have to know
how the function blocks work. It however allows control
applications to be written and to experiment with them.

- This version only does Selector function blocks.

The following message switches the phase88 input to the

  • front (or is is back?)
    /devicemanager/dev0/GenericMixer set selector 10 0
  • back (or is it front?)
    /devicemanager/dev0/GenericMixer set selector 10 1

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 "bebob/GenericMixer.h"
25
26 #include "bebob/bebob_avdevice.h"
27 #include "bebob/bebob_avdevice_subunit.h"
28
29 #include "libosc/OscNode.h"
30 #include "libosc/OscMessage.h"
31 #include "libosc/OscResponse.h"
32
33 #include "libavc/avc_function_block.h"
34 #include "libavc/avc_serialize.h"
35
36 #include "libieee1394/ieee1394service.h"
37
38 #include <sstream>
39 #include <assert.h>
40
41 using namespace OSC;
42
43 namespace BeBoB {
44
45 IMPL_DEBUG_MODULE( GenericMixer, GenericMixer, DEBUG_LEVEL_NORMAL );
46
47 GenericMixer::GenericMixer(
48                 Ieee1394Service& ieee1394service,
49                 AvDevice &d)
50     : OSC::OscNode("GenericMixer")
51     , m_p1394Service( ieee1394service )
52     , m_device(d)
53 {
54
55 }
56
57 GenericMixer::~GenericMixer() {
58
59 }
60
61 OscResponse
62 GenericMixer::processOscMessage(OscMessage *m) {
63     debugOutput(DEBUG_LEVEL_NORMAL, "Message\n");
64    
65     unsigned int nbArgs=m->nbArguments();
66     if (nbArgs>=1) {
67         OscArgument arg0=m->getArgument(0);
68         if(arg0.isString()) { // first argument should be a string command
69             string cmd=arg0.getString();
70             debugOutput( DEBUG_LEVEL_NORMAL, "(%p) CMD? %s\n", this, cmd.c_str());
71             if(cmd == "list") {
72                 debugOutput( DEBUG_LEVEL_NORMAL, "Listing mixer elements...\n");
73                 OscMessage rm=mixerListChildren();
74                 return OscResponse(rm);
75             }
76             if(cmd == "set") {
77                 debugOutput( DEBUG_LEVEL_NORMAL, "setting mixer element...\n");
78                 bool args_ok=true;
79                 args_ok &= (nbArgs>=3);
80                 args_ok &= (m->getArgument(1).isString());
81                 args_ok &= (m->getArgument(2).isInt());
82
83                 if (!args_ok) {
84                     debugWarning("set: Wrong nb of arguments\n");
85                     return OscResponse(OscResponse::eError);
86                 }
87
88                 string type=m->getArgument(1).getString();
89                 int id=m->getArgument(2).getInt();
90                
91                 if (type == "selector") {
92                     if ( !(nbArgs==4)) {
93                         debugWarning("set selector: Wrong nb of arguments\n");
94                         return OscResponse(OscResponse::eError);
95                     }
96                     if(!(m->getArgument(3).isInt64() || m->getArgument(3).isFloat())) {
97                         debugWarning("set selector: Wrong argument type\n");
98                         return OscResponse(OscResponse::eError);
99                     }
100                        
101                     int value=m->getArgument(3).getInt();
102                    
103                     if (m->getArgument(3).isFloat()) {
104                         value=(int)(m->getArgument(3).getFloat());
105                     }
106                    
107                     return mixerSetSelectorValue(id, value);
108                 }
109                
110                 return OscResponse(OscResponse::eError);
111             }
112             if(cmd == "get") {
113                 debugOutput( DEBUG_LEVEL_NORMAL, "getting mixer element...\n");
114                 bool args_ok=true;
115                 args_ok &= (nbArgs>=3);
116                 args_ok &= (m->getArgument(1).isString());
117                 args_ok &= (m->getArgument(2).isInt());
118
119                 if (!args_ok) return OscResponse(OscResponse::eError);
120
121                 string type=m->getArgument(1).getString();
122                 int id=m->getArgument(2).getInt();
123                
124                 if (type == "selector") {
125                     return mixerGetSelectorValue(id);
126                 }
127                
128                 return OscResponse(OscResponse::eError);
129
130             }
131         }
132     }
133     debugWarning("Unhandled OSC message!\n");
134     // default action: don't change response
135     return OscResponse(OscResponse::eUnhandled);
136 }
137
138 OscMessage
139 GenericMixer::mixerListChildren() {
140     OscMessage m;
141
142     debugOutput(DEBUG_LEVEL_NORMAL,"Listing mixer elements...\n");
143
144     assert(m_device.getAudioSubunit(0)); // FIXME!!
145     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
146
147     for ( FunctionBlockVector::iterator it = functions.begin();
148           it != functions.end();
149           ++it )
150     {
151         std::ostringstream ostrm;
152         ostrm << (*it)->getName() << "/" << (int)((*it)->getId());
153         m.addArgument(ostrm.str());
154     }
155
156     m.print();
157     return m;
158 }
159
160 OscResponse
161 GenericMixer::mixerGetSelectorValue(int fb_id) {
162     OscMessage m;
163    
164     debugOutput(DEBUG_LEVEL_NORMAL,"Get selector %d value...\n",
165         fb_id);
166
167     FunctionBlockCmd fbCmd( m_p1394Service,
168                             FunctionBlockCmd::eFBT_Selector,
169                             fb_id,
170                             FunctionBlockCmd::eCA_Current );
171     fbCmd.setNodeId( m_device.getNodeId() );
172     fbCmd.setSubunitId( 0x00 );
173     fbCmd.setCommandType( AVCCommand::eCT_Status );
174     fbCmd.m_pFBSelector->m_inputFbPlugNumber=0xFF;
175
176     fbCmd.setVerbose( getDebugLevel() );
177    
178     if ( !fbCmd.fire() ) {
179         debugError( "FunctionBlockCmd failed\n" );
180         return OscResponse(OscResponse::eError);
181     }
182
183     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
184         CoutSerializer se;
185         fbCmd.serialize( se );
186     }
187    
188     if (fbCmd.getResponse() != AVCCommand::eR_Accepted) {
189         return OscResponse(OscResponse::eError);
190     }
191    
192     m.addArgument((int32_t)(fbCmd.m_pFBSelector->m_inputFbPlugNumber));
193
194     return OscResponse(m);
195 }
196
197 OscResponse
198 GenericMixer::mixerSetSelectorValue(int fb_id, int value) {
199     OscMessage m;
200    
201     debugOutput(DEBUG_LEVEL_NORMAL,"Set selector %d to %d...\n",
202         fb_id, value);
203
204     FunctionBlockCmd fbCmd( m_p1394Service,
205                             FunctionBlockCmd::eFBT_Selector,
206                             fb_id,
207                             FunctionBlockCmd::eCA_Current );
208     fbCmd.setNodeId( m_device.getNodeId() );
209     fbCmd.setSubunitId( 0x00 );
210     fbCmd.setCommandType( AVCCommand::eCT_Control );
211     fbCmd.m_pFBSelector->m_inputFbPlugNumber=(value & 0xFF);
212
213     fbCmd.setVerbose( getDebugLevel() );
214    
215     if ( !fbCmd.fire() ) {
216         debugError( "FunctionBlockCmd failed\n" );
217         return OscResponse(OscResponse::eError);
218     }
219
220     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
221         CoutSerializer se;
222         fbCmd.serialize( se );
223     }
224
225     if (fbCmd.getResponse() != AVCCommand::eR_Accepted) {
226         return OscResponse(OscResponse::eError);
227     }
228    
229     return OscResponse(m);
230 }
231
232
233 } // end of namespace BeBoB
Note: See TracBrowser for help on using the browser.