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

Revision 618, 26.1 kB (checked in by ppalmers, 16 years ago)

move serialization routines to libutil such that they can be used for non-AVC stuff too (fireworks EFC)

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