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

Revision 462, 26.0 kB (checked in by ppalmers, 17 years ago)

- Rework the OSC space to something more usable

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 <string>
39 #include <sstream>
40 #include <iostream>
41
42 #include <assert.h>
43
44 using namespace OSC;
45
46 namespace BeBoB {
47
48 template <class T>
49 bool from_string(T& t,
50                  const std::string& s,
51                  std::ios_base& (*f)(std::ios_base&))
52 {
53   std::istringstream iss(s);
54   return !(iss >> f >> t).fail();
55 }
56
57 IMPL_DEBUG_MODULE( GenericMixer, GenericMixer, DEBUG_LEVEL_NORMAL );
58
59 GenericMixer::GenericMixer(
60                 Ieee1394Service& ieee1394service,
61                 AvDevice &d)
62     : OSC::OscNode("GenericMixer")
63     , m_p1394Service( ieee1394service )
64     , m_device(d)
65 {
66
67 }
68
69 GenericMixer::~GenericMixer() {
70
71 }
72
73 OscResponse
74 GenericMixer::processOscMessage(OscMessage *m) {
75     debugOutput( DEBUG_LEVEL_NORMAL, "PROCESS: %s\n", m->getPath().c_str());
76    
77     std::string path=m->getPath();
78    
79     // delete leading slashes
80     if(path.find_first_of('/')==0) path=path.substr(1,path.size());
81
82     // delete trailing slashes
83     if(path.find_last_of('/')==path.size()-1) path=path.substr(0,path.size()-1);
84    
85     std::string target="";
86     std::string newpath="";
87    
88     if (path == "") return processOscMessageRoot(m);
89    
90     // not targetted at the root node, continue processing
91     int firstsep=path.find_first_of('/');
92     if (firstsep == -1) { // this will most likely be a list request
93         target=path;
94         newpath="";
95     } else {
96         target=path.substr(0,firstsep);
97         newpath=path.substr(firstsep+1);
98     }
99    
100     if(target == "Selector") return processOscMessageSelector(newpath, m);
101     if(target == "Feature") return processOscMessageFeature(newpath, m);
102     if(target == "Processing") return processOscMessageProcessing(newpath, m);
103    
104     // unhandled
105     return OscResponse(OscResponse::eUnhandled);
106 }
107
108 //// MIXER ROOT MESSAGES
109
110 OscResponse
111 GenericMixer::processOscMessageRoot(OscMessage *m) {
112
113     unsigned int nbArgs=m->nbArguments();
114     if (nbArgs>=1) {
115         OscArgument arg0=m->getArgument(0);
116         if(arg0.isString()) { // first argument should be a string command
117             string cmd=arg0.getString();
118             debugOutput( DEBUG_LEVEL_NORMAL, "(%p) CMD: %s\n", this, cmd.c_str());
119            
120             if(cmd == "list") {
121                 debugOutput( DEBUG_LEVEL_NORMAL, "Listing root elements...\n");
122                 return OscResponse(rootListChildren());
123             }
124 //             if(cmd == "params") {
125 //                 debugOutput( DEBUG_LEVEL_NORMAL, "Listing root params...\n");
126 //                 return OscResponse(rootListParams());
127 //             }
128 //             if(cmd == "get") {
129 //                 
130 //             }
131 //             if(cmd == "set") {
132 //                 
133 //             }
134             return OscResponse(OscResponse::eUnhandled);
135         } else {
136             debugWarning("Wrong command datatype\n");
137             return OscResponse(OscResponse::eError);
138         }
139     } else {
140         debugWarning("Not enough arguments\n");
141         return OscResponse(OscResponse::eError);
142     }
143 }
144
145 OscResponse
146 GenericMixer::rootListChildren() {
147     OscMessage m;
148
149     debugOutput(DEBUG_LEVEL_NORMAL,"Listing root elements...\n");
150
151     assert(m_device.getAudioSubunit(0)); // FIXME!!
152     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
153
154     bool hasSelector=false;
155     bool hasFeature=false;
156     bool hasProcessing=false;
157     bool hasCodec=false;
158
159     for ( FunctionBlockVector::iterator it = functions.begin();
160           it != functions.end();
161           ++it )
162     {
163         hasSelector |= (((*it)->getType())==FunctionBlockCmd::eFBT_Selector);
164         hasFeature |= (((*it)->getType())==FunctionBlockCmd::eFBT_Feature);
165         hasProcessing |= (((*it)->getType())==FunctionBlockCmd::eFBT_Processing);
166         hasCodec |= (((*it)->getType())==FunctionBlockCmd::eFBT_Codec);
167     }
168
169     if (hasSelector) m.addArgument("Selector");
170     if (hasFeature) m.addArgument("Feature");
171     if (hasProcessing) m.addArgument("Processing");
172     if (hasCodec) m.addArgument("Codec");
173
174     return OscResponse(m);
175 }
176
177 //// SELECTOR MESSAGES
178
179 OscResponse
180 GenericMixer::processOscMessageSelector(std::string path, OscMessage *m) {
181     debugOutput( DEBUG_LEVEL_NORMAL, "Selector: %s\n", path.c_str());
182    
183     // delete leading slashes
184     if(path.find_first_of('/')==0) path=path.substr(1,path.size());
185
186     // delete trailing slashes
187     if(path.find_last_of('/')==path.size()-1) path=path.substr(0,path.size()-1);
188    
189     int id=-1;
190     if ((path != "") && (!from_string<int>(id, path, std::dec))) {
191         debugWarning( "could not get id\n" );
192         return OscResponse(OscResponse::eError);
193     }
194    
195     unsigned int nbArgs=m->nbArguments();
196     if (nbArgs>=1) {
197         OscArgument arg0=m->getArgument(0);
198         if(arg0.isString()) { // first argument should be a string command
199             string cmd=arg0.getString();
200             debugOutput( DEBUG_LEVEL_NORMAL, "(%p) CMD: %s\n", this, cmd.c_str());
201            
202             if(cmd == "list") {
203                 debugOutput( DEBUG_LEVEL_NORMAL, "Listing selector elements...\n");
204                 return selectorListChildren(id);
205             }
206             if(cmd == "params") {
207                 debugOutput( DEBUG_LEVEL_NORMAL, "Listing selector %d params...\n", id);
208                 return selectorListParams(id);
209             }
210             if(cmd == "get") {
211                 if (nbArgs<2 || !m->getArgument(1).isString()) {
212                     debugWarning("Argument error\n");
213                     m->print();
214                     return OscResponse(OscResponse::eError);
215                 }
216                 debugOutput( DEBUG_LEVEL_NORMAL, "Getting selector params %s...\n",
217                     m->getArgument(1).getString().c_str());
218                 return selectorGetParam(id,m->getArgument(1).getString(), m);
219             }
220             if(cmd == "set") {
221                 if (nbArgs<3 || !m->getArgument(1).isString() || !m->getArgument(2).isNumeric()) {
222                     debugWarning("Argument error\n");
223                     m->print();
224                     return OscResponse(OscResponse::eError);
225                 }
226                 debugOutput( DEBUG_LEVEL_NORMAL, "Setting selector param %s...\n",
227                     m->getArgument(1).getString().c_str());
228                 return selectorSetParam(id,m->getArgument(1).getString(), m);
229             }
230             return OscResponse(OscResponse::eUnhandled);
231         } else {
232             debugWarning("Wrong command datatype\n");
233             return OscResponse(OscResponse::eError);
234         }
235     } else {
236         debugWarning("Not enough arguments\n");
237         return OscResponse(OscResponse::eError);
238     }
239 }
240
241 /*
242             if(cmd == "set") {
243                 debugOutput( DEBUG_LEVEL_NORMAL, "setting mixer element...\n");
244                 bool args_ok=true;
245                 args_ok &= (nbArgs>=3);
246                 args_ok &= (m->getArgument(1).isString());
247                 args_ok &= (m->getArgument(2).isInt());
248
249                 if (!args_ok) {
250                     debugWarning("set: Wrong nb of arguments\n");
251                     return OscResponse(OscResponse::eError);
252                 }
253
254                 string type=m->getArgument(1).getString();
255                 int id=m->getArgument(2).getInt();
256                
257                 if (type == "selector") {
258                     if ( !(nbArgs==4)) {
259                         debugWarning("set selector: Wrong nb of arguments\n");
260                         return OscResponse(OscResponse::eError);
261                     }
262                     if(!m->getArgument(3).isNumeric()) {
263                         debugWarning("set selector: Wrong argument type\n");
264                         return OscResponse(OscResponse::eError);
265                     }
266                     int value=m->getArgument(3).toInt();
267                    
268                     return setSelectorValue(id, value);
269                 }
270                
271                 if (type == "volume") {
272                     if ( !(nbArgs>=5)) {
273                         debugWarning("set volume: Wrong nb of arguments\n");
274                         return OscResponse(OscResponse::eError);
275                     }
276                     if(!m->getArgument(3).isNumeric()) {
277                         debugWarning("set volume: Wrong argument (3) type\n");
278                         return OscResponse(OscResponse::eError);
279                     }
280                     if(!m->getArgument(4).isNumeric()) {
281                         debugWarning("set volume: Wrong argument (4) type\n");
282                         return OscResponse(OscResponse::eError);
283                     }
284                    
285                     int channel=m->getArgument(3).toInt();
286                     int volume=m->getArgument(4).toInt();
287                    
288                     return mixerSetFeatureVolumeValue(id, channel, volume);
289                 }
290
291                 return OscResponse(OscResponse::eError);
292             }
293             if(cmd == "get") {
294                 debugOutput( DEBUG_LEVEL_NORMAL, "getting mixer element...\n");
295                 bool args_ok=true;
296                 args_ok &= (nbArgs>=3);
297                 args_ok &= (m->getArgument(1).isString());
298                 args_ok &= (m->getArgument(2).isInt());
299
300                 if (!args_ok) return OscResponse(OscResponse::eError);
301
302                 string type=m->getArgument(1).getString();
303                 int id=m->getArgument(2).getInt();
304                
305                 if (type == "selector") {
306                     return mixerGetSelectorValue(id);
307                 }
308                
309                 if (type == "volume") {
310                     if ( !(nbArgs==6)) {
311                         debugWarning("set volume: Wrong nb of arguments\n");
312                         return OscResponse(OscResponse::eError);
313                     }
314                     if(!m->getArgument(3).isNumeric()) {
315                         debugWarning("set volume: Wrong argument (3) type\n");
316                         return OscResponse(OscResponse::eError);
317                     }
318
319                     int channel=m->getArgument(3).toInt();
320                    
321                     return mixerGetFeatureVolumeValue(id, channel);
322                 }
323                
324                 return OscResponse(OscResponse::eError);
325
326             }
327         }
328     }
329     debugWarning("Unhandled OSC message!\n");
330     // default action: don't change response
331     return OscResponse(OscResponse::eUnhandled);
332 }*/
333
334 OscResponse
335 GenericMixer::selectorListChildren(int id) {
336     OscMessage m;
337
338     if (id != -1) return m;
339
340     debugOutput(DEBUG_LEVEL_NORMAL,"Listing selector elements...\n");
341    
342     assert(m_device.getAudioSubunit(0)); // FIXME!!
343     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
344
345     for ( FunctionBlockVector::iterator it = functions.begin();
346           it != functions.end();
347           ++it )
348     {
349         std::ostringstream ostrm;
350         if (((*it)->getType()) == FunctionBlockCmd::eFBT_Selector) {
351             ostrm << (int)((*it)->getId());
352             m.addArgument(ostrm.str());
353         }
354     }
355     return OscResponse(m);
356 }
357
358 OscResponse
359 GenericMixer::selectorListParams(int id) {
360     OscMessage m;
361
362     if (id == -1) return m;
363
364     debugOutput(DEBUG_LEVEL_NORMAL,"Listing selector params...\n");
365    
366     assert(m_device.getAudioSubunit(0)); // FIXME!!
367     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
368
369     for ( FunctionBlockVector::iterator it = functions.begin();
370           it != functions.end();
371           ++it )
372     {
373         std::ostringstream ostrm;
374         if ((((*it)->getType()) == FunctionBlockCmd::eFBT_Selector)
375             && (((*it)->getId()) == id))
376         {
377             m.addArgument("name");
378             m.addArgument("value");
379         }
380     }
381     return OscResponse(m);
382 }
383
384 OscResponse
385 GenericMixer::selectorGetParam(int id, std::string p, OscMessage *src) {
386     OscMessage m;
387
388     if (id == -1) return m;
389
390     debugOutput(DEBUG_LEVEL_NORMAL,"Getting selector parameter: '%s'\n", p.c_str());
391    
392     assert(m_device.getAudioSubunit(0)); // FIXME!!
393     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
394
395     for ( FunctionBlockVector::iterator it = functions.begin();
396           it != functions.end();
397           ++it )
398     {
399         std::ostringstream ostrm;
400         if ((((*it)->getType()) == FunctionBlockCmd::eFBT_Selector)
401             && (((*it)->getId()) == id))
402         {
403             if (p=="name") {
404                 m.addArgument("testname");
405             } else if (p=="value") {
406                 int value;
407                 if( getSelectorValue(id, value) ) {
408                     m.addArgument(value);
409                 }
410             }
411         }
412     }
413     return OscResponse(m);
414 }
415
416 OscResponse
417 GenericMixer::selectorSetParam(int id, std::string p, OscMessage *src) {
418     OscMessage m;
419
420     if (id == -1) return m;
421
422     debugOutput(DEBUG_LEVEL_NORMAL,"Setting selector parameter: '%s'\n", p.c_str());
423    
424     assert(m_device.getAudioSubunit(0)); // FIXME!!
425     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
426
427     for ( FunctionBlockVector::iterator it = functions.begin();
428           it != functions.end();
429           ++it )
430     {
431         std::ostringstream ostrm;
432         if ((((*it)->getType()) == FunctionBlockCmd::eFBT_Selector)
433             && (((*it)->getId()) == id))
434         {
435             if (p=="name") {
436
437             } else if (p=="value") {
438                 assert(src->nbArguments()>=3);
439                 int value=src->getArgument(2).toInt();
440                 if( ! setSelectorValue(id, value) ) {
441                     return OscResponse(OscResponse::eError);
442                 }
443             }
444         }
445     }
446     return OscResponse(m);
447 }
448
449 bool
450 GenericMixer::getSelectorValue(int fb_id, int &value) {
451     debugOutput(DEBUG_LEVEL_NORMAL,"Get selector %d value...\n",
452         fb_id);
453
454     FunctionBlockCmd fbCmd( m_p1394Service,
455                             FunctionBlockCmd::eFBT_Selector,
456                             fb_id,
457                             FunctionBlockCmd::eCA_Current );
458     fbCmd.setNodeId( m_device.getNodeId() );
459     fbCmd.setSubunitId( 0x00 );
460     fbCmd.setCommandType( AVCCommand::eCT_Status );
461     fbCmd.m_pFBSelector->m_inputFbPlugNumber=0xFF;
462
463     fbCmd.setVerbose( getDebugLevel() );
464    
465     if ( !fbCmd.fire() ) {
466         debugError( "FunctionBlockCmd failed\n" );
467         return false;
468     }
469
470     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
471         CoutSerializer se;
472         fbCmd.serialize( se );
473     }
474    
475     value=(int)(fbCmd.m_pFBSelector->m_inputFbPlugNumber);
476     return (fbCmd.getResponse() == AVCCommand::eR_Implemented);
477 }
478
479 bool
480 GenericMixer::setSelectorValue(int fb_id, int value) {
481     debugOutput(DEBUG_LEVEL_NORMAL,"Set selector %d to %d...\n",
482         fb_id, value);
483
484     FunctionBlockCmd fbCmd( m_p1394Service,
485                             FunctionBlockCmd::eFBT_Selector,
486                             fb_id,
487                             FunctionBlockCmd::eCA_Current );
488     fbCmd.setNodeId( m_device.getNodeId() );
489     fbCmd.setSubunitId( 0x00 );
490     fbCmd.setCommandType( AVCCommand::eCT_Control );
491     fbCmd.m_pFBSelector->m_inputFbPlugNumber=(value & 0xFF);
492
493     fbCmd.setVerbose( getDebugLevel() );
494    
495     if ( !fbCmd.fire() ) {
496         debugError( "FunctionBlockCmd failed\n" );
497         return false;
498     }
499
500     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
501         CoutSerializer se;
502         fbCmd.serialize( se );
503     }
504
505     return (fbCmd.getResponse() == AVCCommand::eR_Accepted);
506 }
507
508
509 //// FEATURE
510 OscResponse
511 GenericMixer::processOscMessageFeature(std::string path, OscMessage *m) {
512     debugOutput( DEBUG_LEVEL_NORMAL, "Feature: %s\n", path.c_str());
513     // delete leading slashes
514     if(path.find_first_of('/')==0) path=path.substr(1,path.size());
515
516     // delete trailing slashes
517     if(path.find_last_of('/')==path.size()-1) path=path.substr(0,path.size()-1);
518    
519     int id=-1;
520     if ((path != "") && (!from_string<int>(id, path, std::dec))) {
521         debugWarning( "could not get id\n" );
522         return OscResponse(OscResponse::eError);
523     }
524    
525     unsigned int nbArgs=m->nbArguments();
526     if (nbArgs>=1) {
527         OscArgument arg0=m->getArgument(0);
528         if(arg0.isString()) { // first argument should be a string command
529             string cmd=arg0.getString();
530             debugOutput( DEBUG_LEVEL_NORMAL, "(%p) CMD: %s\n", this, cmd.c_str());
531            
532             if(cmd == "list") {
533                 debugOutput( DEBUG_LEVEL_NORMAL, "Listing feature elements...\n");
534                 return featureListChildren(id);
535             }
536             if(cmd == "params") {
537                 debugOutput( DEBUG_LEVEL_NORMAL, "Listing feature %d params...\n", id);
538                 return featureListParams(id);
539             }
540             if(cmd == "get") {
541                 if (nbArgs<2 || !m->getArgument(1).isString()) {
542                     debugWarning("Argument error\n");
543                     m->print();
544                     return OscResponse(OscResponse::eError);
545                 }
546                 debugOutput( DEBUG_LEVEL_NORMAL, "Getting feature param %s...\n",
547                     m->getArgument(1).getString().c_str());
548                 return featureGetParam(id,m->getArgument(1).getString(), m);
549             }
550             if(cmd == "set") {
551                 if (nbArgs<3 || !m->getArgument(1).isString()) {
552                     debugWarning("Argument error\n");
553                     m->print();
554                     return OscResponse(OscResponse::eError);
555                 }
556                 debugOutput( DEBUG_LEVEL_NORMAL, "Setting feature param %s...\n",
557                     m->getArgument(1).getString().c_str());
558                 return featureSetParam(id,m->getArgument(1).getString(), m);
559             }
560             return OscResponse(OscResponse::eUnhandled);
561         } else {
562             debugWarning("Wrong command datatype\n");
563             return OscResponse(OscResponse::eError);
564         }
565     } else {
566         debugWarning("Not enough arguments\n");
567         return OscResponse(OscResponse::eError);
568     }
569
570 }
571
572 OscResponse
573 GenericMixer::featureListChildren(int id) {
574     OscMessage m;
575
576     if (id != -1) return m;
577
578     debugOutput(DEBUG_LEVEL_NORMAL,"Listing feature elements...\n");
579    
580     assert(m_device.getAudioSubunit(0)); // FIXME!!
581     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
582
583     for ( FunctionBlockVector::iterator it = functions.begin();
584           it != functions.end();
585           ++it )
586     {
587         std::ostringstream ostrm;
588         if (((*it)->getType()) == FunctionBlockCmd::eFBT_Feature) {
589             ostrm << (int)((*it)->getId());
590             m.addArgument(ostrm.str());
591         }
592     }
593     return OscResponse(m);
594 }
595
596 OscResponse
597 GenericMixer::featureListParams(int id) {
598     OscMessage m;
599
600     if (id == -1) return m;
601
602     debugOutput(DEBUG_LEVEL_NORMAL,"Listing feature params...\n");
603    
604     assert(m_device.getAudioSubunit(0)); // FIXME!!
605     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
606
607     for ( FunctionBlockVector::iterator it = functions.begin();
608           it != functions.end();
609           ++it )
610     {
611         std::ostringstream ostrm;
612         if ((((*it)->getType()) == FunctionBlockCmd::eFBT_Feature)
613             && (((*it)->getId()) == id))
614         {
615             m.addArgument("name");
616             m.addArgument("volume");
617         }
618     }
619     return OscResponse(m);
620 }
621
622 OscResponse
623 GenericMixer::featureGetParam(int id, std::string p, OscMessage *src) {
624     OscMessage m;
625
626     if (id == -1) return m;
627    
628     debugOutput(DEBUG_LEVEL_NORMAL,"Getting feature parameter: '%s'\n", p.c_str());
629    
630     assert(m_device.getAudioSubunit(0)); // FIXME!!
631     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
632
633     for ( FunctionBlockVector::iterator it = functions.begin();
634           it != functions.end();
635           ++it )
636     {
637         std::ostringstream ostrm;
638         if ((((*it)->getType()) == FunctionBlockCmd::eFBT_Feature)
639             && (((*it)->getId()) == id))
640         {
641             if (p=="name") {
642                 m.addArgument("testname");
643             } else if (p=="volume") {
644                 if (src->nbArguments()<3) return OscResponse(OscResponse::eError);
645                 int value;
646                 int channel=src->getArgument(2).toInt();
647                
648                 if( getFeatureVolumeValue(id, channel, value) ) {
649                     m.addArgument(value);
650                 }
651             }
652         }
653     }
654     return OscResponse(m);
655 }
656
657 OscResponse
658 GenericMixer::featureSetParam(int id, std::string p, OscMessage *src) {
659     OscMessage m;
660
661     if (id == -1) return m;
662
663     debugOutput(DEBUG_LEVEL_NORMAL,"Setting feature parameter: '%s'\n", p.c_str());
664    
665     assert(m_device.getAudioSubunit(0)); // FIXME!!
666     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
667
668     for ( FunctionBlockVector::iterator it = functions.begin();
669           it != functions.end();
670           ++it )
671     {
672         std::ostringstream ostrm;
673         if ((((*it)->getType()) == FunctionBlockCmd::eFBT_Feature)
674             && (((*it)->getId()) == id))
675         {
676             if (p=="name") {
677                 m.addArgument("testname");
678             } else if (p=="volume") {
679                 if (src->nbArguments()<4) return OscResponse(OscResponse::eError);
680                 int channel=src->getArgument(2).toInt();
681                 int value=src->getArgument(3).toInt();;
682                
683                 if( !setFeatureVolumeValue(id, channel, value) ) {
684                     return OscResponse(OscResponse::eError);
685                 }
686             }
687         }
688     }
689     return OscResponse(m);
690 }
691
692
693 bool
694 GenericMixer::getFeatureVolumeValue(int fb_id, int channel, int &volume) {
695     OscMessage m;
696    
697     debugOutput(DEBUG_LEVEL_NORMAL,"Get feature volume %d channel %d...\n",
698         fb_id, channel);
699
700     FunctionBlockCmd fbCmd( m_p1394Service,
701                             FunctionBlockCmd::eFBT_Feature,
702                             fb_id,
703                             FunctionBlockCmd::eCA_Current );
704     fbCmd.setNodeId( m_device.getNodeId()  );
705     fbCmd.setSubunitId( 0x00 );
706     fbCmd.setCommandType( AVCCommand::eCT_Status );
707     fbCmd.m_pFBFeature->m_audioChannelNumber=channel;
708     fbCmd.m_pFBFeature->m_controlSelector=FunctionBlockFeature::eCSE_Feature_Volume;
709     fbCmd.m_pFBFeature->m_pVolume->m_volume=0;
710
711     if ( !fbCmd.fire() ) {
712         debugError( "cmd failed\n" );
713         return false;
714     }
715    
716     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
717         CoutSerializer se;
718         fbCmd.serialize( se );
719     }
720
721     volume=(int)(fbCmd.m_pFBFeature->m_pVolume->m_volume);
722    
723     return (fbCmd.getResponse() == AVCCommand::eR_Implemented);
724 }
725
726 bool
727 GenericMixer::setFeatureVolumeValue(int fb_id, int channel,
728                                         int volume) {
729     debugOutput(DEBUG_LEVEL_NORMAL,"Set feature volume %d channel %d to %d...\n",
730         fb_id, channel, volume);
731
732     FunctionBlockCmd fbCmd( m_p1394Service,
733                             FunctionBlockCmd::eFBT_Feature,
734                             fb_id,
735                             FunctionBlockCmd::eCA_Current );
736     fbCmd.setNodeId( m_device.getNodeId()  );
737     fbCmd.setSubunitId( 0x00 );
738     fbCmd.setCommandType( AVCCommand::eCT_Control );
739     fbCmd.m_pFBFeature->m_audioChannelNumber=channel;
740     fbCmd.m_pFBFeature->m_controlSelector=FunctionBlockFeature::eCSE_Feature_Volume;
741     fbCmd.m_pFBFeature->m_pVolume->m_volume=volume;
742
743     if ( !fbCmd.fire() ) {
744         debugError( "cmd failed\n" );
745         return false;
746     }
747
748     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
749         CoutSerializer se;
750         fbCmd.serialize( se );
751     }
752
753     return (fbCmd.getResponse() == AVCCommand::eR_Accepted);
754 }
755
756 //// PROCESSING
757
758 OscResponse
759 GenericMixer::processOscMessageProcessing(std::string path, OscMessage *m) {
760     debugOutput( DEBUG_LEVEL_NORMAL, "Processing: %s\n", path.c_str());
761     return OscResponse(OscResponse::eUnhandled);
762 }
763
764 OscResponse
765 GenericMixer::processingListChildren(int id) {
766     OscMessage m;
767    
768     if (id != -1) return m;
769    
770     debugOutput(DEBUG_LEVEL_NORMAL,"Listing processing elements...\n");
771
772     assert(m_device.getAudioSubunit(0)); // FIXME!!
773     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
774
775     for ( FunctionBlockVector::iterator it = functions.begin();
776           it != functions.end();
777           ++it )
778     {
779         std::ostringstream ostrm;
780         if (((*it)->getType()) == FunctionBlockCmd::eFBT_Processing) {
781             ostrm << (int)((*it)->getId());
782             m.addArgument(ostrm.str());
783         }
784     }
785     return OscResponse(m);
786 }
787
788 //// CODEC
789
790 OscResponse
791 GenericMixer::codecListChildren(int id) {
792     OscMessage m;
793
794     if (id != -1) return m;
795    
796     debugOutput(DEBUG_LEVEL_NORMAL,"Listing codec elements...\n");
797
798     assert(m_device.getAudioSubunit(0)); // FIXME!!
799     FunctionBlockVector functions=m_device.getAudioSubunit(0)->getFunctionBlocks();
800
801     for ( FunctionBlockVector::iterator it = functions.begin();
802           it != functions.end();
803           ++it )
804     {
805         std::ostringstream ostrm;
806         if (((*it)->getType()) == FunctionBlockCmd::eFBT_Codec) {
807             ostrm << (int)((*it)->getId());
808             m.addArgument(ostrm.str());
809         }
810     }
811     return OscResponse(m);
812 }
813
814 } // end of namespace BeBoB
Note: See TracBrowser for help on using the browser.