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

Revision 451, 14.3 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) 2005-2007 by Daniel Wagner
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/bebob_functionblock.h"
25 #include "bebob/bebob_avdevice_subunit.h"
26 #include "bebob/bebob_avdevice.h"
27 #include "libieee1394/configrom.h"
28
29 IMPL_DEBUG_MODULE( BeBoB::FunctionBlock, BeBoB::FunctionBlock, DEBUG_LEVEL_NORMAL );
30
31 BeBoB::FunctionBlock::FunctionBlock(
32     AvDeviceSubunit& subunit,
33     function_block_type_t type,
34     function_block_type_t subtype,
35     function_block_id_t id,
36     ESpecialPurpose purpose,
37     no_of_input_plugs_t nrOfInputPlugs,
38     no_of_output_plugs_t nrOfOutputPlugs,
39     int verbose )
40     : m_subunit( &subunit )
41     , m_type( type )
42     , m_subtype( subtype )
43     , m_id( id )
44     , m_purpose( purpose )
45     , m_nrOfInputPlugs( nrOfInputPlugs )
46     , m_nrOfOutputPlugs( nrOfOutputPlugs )
47     , m_verbose( verbose )
48 {
49     setDebugLevel( verbose );
50 }
51
52 BeBoB::FunctionBlock::FunctionBlock( const FunctionBlock& rhs )
53     : m_subunit( rhs.m_subunit )
54     , m_type( rhs.m_type )
55     , m_subtype( rhs.m_subtype )
56     , m_id( rhs.m_id )
57     , m_purpose( rhs.m_purpose )
58     , m_nrOfInputPlugs( rhs.m_nrOfInputPlugs )
59     , m_nrOfOutputPlugs( rhs.m_nrOfOutputPlugs )
60     , m_verbose( rhs.m_verbose )
61 {
62 }
63
64 BeBoB::FunctionBlock::FunctionBlock()
65 {
66 }
67
68 BeBoB::FunctionBlock::~FunctionBlock()
69 {
70     for ( AvPlugVector::iterator it = m_plugs.begin();
71           it != m_plugs.end();
72           ++it )
73     {
74         delete *it;
75     }
76
77 }
78
79 bool
80 BeBoB::FunctionBlock::discover()
81 {
82     debugOutput( DEBUG_LEVEL_NORMAL,
83                  "discover function block %s (nr of input plugs = %d, "
84                  "nr of output plugs = %d)\n",
85                  getName(),
86                  m_nrOfInputPlugs,
87                  m_nrOfOutputPlugs );
88
89     if ( !discoverPlugs( AvPlug::eAPD_Input, m_nrOfInputPlugs ) ) {
90         debugError( "Could not discover input plug for '%s'\n",
91                     getName() );
92         return false;
93     }
94
95     if ( !discoverPlugs( AvPlug::eAPD_Output, m_nrOfOutputPlugs ) ) {
96         debugError( "Could not discover output plugs for '%s'\n",
97                     getName() );
98         return false;
99     }
100
101     return true;
102 }
103
104 bool
105 BeBoB::FunctionBlock::discoverPlugs( AvPlug::EAvPlugDirection plugDirection,
106                                      plug_id_t plugMaxId )
107 {
108     for ( int plugId = 0; plugId < plugMaxId; ++plugId ) {
109         AvPlug* plug = new AvPlug(
110             m_subunit->getAvDevice().get1394Service(),
111             m_subunit->getAvDevice().getConfigRom(),
112             m_subunit->getAvDevice().getPlugManager(),
113             m_subunit->getSubunitType(),
114             m_subunit->getSubunitId(),
115             m_type,
116             m_id,
117             AvPlug::eAPA_FunctionBlockPlug,
118             plugDirection,
119             plugId,
120             m_verbose );
121
122         if ( !plug || !plug->discover() ) {
123             debugError( "plug discovering failed for plug %d\n",
124                         plugId );
125             delete plug;
126             return false;
127         }
128
129         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
130                      plug->getName() );
131         m_plugs.push_back( plug );
132     }
133
134     return true;
135 }
136
137 bool
138 BeBoB::FunctionBlock::discoverConnections()
139 {
140     debugOutput( DEBUG_LEVEL_VERBOSE,
141                  "discover connections function block %s\n",
142                  getName() );
143
144     for ( AvPlugVector::iterator it = m_plugs.begin();
145           it != m_plugs.end();
146           ++it )
147     {
148         AvPlug* plug = *it;
149         if ( !plug->discoverConnections() ) {
150             debugError( "Could not discover plug connections\n" );
151             return false;
152         }
153     }
154     return true;
155 }
156
157 bool
158 serializeAvPlugVector( Glib::ustring basePath,
159                        Util::IOSerialize& ser,
160                        const BeBoB::AvPlugVector& vec )
161 {
162     bool result = true;
163     int i = 0;
164     for ( BeBoB::AvPlugVector::const_iterator it = vec.begin();
165           it != vec.end();
166           ++it )
167     {
168         std::ostringstream strstrm;
169         strstrm << basePath << i;
170         result &= ser.write( strstrm.str(), ( *it )->getGlobalId() );
171         i++;
172     }
173     return result;
174 }
175
176 bool
177 deserializeAvPlugVector( Glib::ustring basePath,
178                          Util::IODeserialize& deser,
179                          BeBoB::AvDevice& avDevice,
180                          BeBoB::AvPlugVector& vec )
181 {
182     int i = 0;
183     bool bFinished = false;
184     bool result = true;
185     do {
186         plug_id_t plugId;
187         std::ostringstream strstrm;
188         strstrm << basePath << i;
189
190         result &= deser.read( strstrm.str(), plugId );
191         BeBoB::AvPlug* pPlug = avDevice.getPlugManager().getPlug( plugId );
192
193         if ( pPlug ) {
194             vec.push_back( pPlug );
195             i++;
196         } else {
197             bFinished = true;
198         }
199     } while ( !bFinished );
200
201     return result;
202 }
203
204 bool
205 BeBoB::FunctionBlock::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const
206 {
207     bool result;
208
209     result  = ser.write( basePath + "m_type", m_type );
210     result &= ser.write( basePath + "m_subtype", m_subtype );
211     result &= ser.write( basePath + "m_id", m_id );
212     result &= ser.write( basePath + "m_purpose", m_purpose );
213     result &= ser.write( basePath + "m_nrOfInputPlugs", m_nrOfInputPlugs );
214     result &= ser.write( basePath + "m_nrOfOutputPlugs", m_nrOfOutputPlugs );
215     result &= ser.write( basePath + "m_verbose", m_verbose );
216     result &= serializeAvPlugVector( basePath + "m_plugs", ser, m_plugs );
217
218     return result;
219 }
220
221 BeBoB::FunctionBlock*
222 BeBoB::FunctionBlock::deserialize( Glib::ustring basePath,
223                                    Util::IODeserialize& deser,
224                                    AvDevice& avDevice,
225                                    AvDeviceSubunit& subunit )
226 {
227     bool result;
228     function_block_type_t type;
229     function_block_type_t subtype;
230     FunctionBlock* pFB = 0;
231
232     result  = deser.read( basePath + "m_type", type );
233     result &= deser.read( basePath + "m_subtype", subtype );
234     if ( !result ) {
235         return 0;
236     }
237
238     switch ( type ) {
239     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector:
240         pFB = new FunctionBlockSelector;
241         break;
242     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature:
243         pFB = new FunctionBlockFeature;
244         break;
245     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing:
246         if ( subtype == ExtendedSubunitInfoCmd::ePT_EnhancedMixer ) {
247             pFB = new FunctionBlockEnhancedMixer;
248         } else {
249             pFB = new FunctionBlockProcessing;
250         }
251         break;
252     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec:
253         pFB = new FunctionBlockCodec;
254         break;
255     default:
256         pFB = 0;
257     }
258
259     if ( !pFB ) {
260         return 0;
261     }
262
263     pFB->m_subunit = &subunit;
264     pFB->m_type = type;
265     pFB->m_subtype = subtype;
266
267     result &= deser.read( basePath + "m_id", pFB->m_id );
268     result &= deser.read( basePath + "m_purpose", pFB->m_purpose );
269     result &= deser.read( basePath + "m_nrOfInputPlugs", pFB->m_nrOfInputPlugs );
270     result &= deser.read( basePath + "m_nrOfOutputPlugs", pFB->m_nrOfOutputPlugs );
271     result &= deser.read( basePath + "m_verbose", pFB->m_verbose );
272     result &= deserializeAvPlugVector( basePath + "m_plugs", deser, avDevice, pFB->m_plugs );
273
274     return 0;
275 }
276
277 ///////////////////////
278
279 BeBoB::FunctionBlockSelector::FunctionBlockSelector(
280     AvDeviceSubunit& subunit,
281     function_block_id_t id,
282     ESpecialPurpose purpose,
283     no_of_input_plugs_t nrOfInputPlugs,
284     no_of_output_plugs_t nrOfOutputPlugs,
285     int verbose )
286     : FunctionBlock( subunit,
287                      eFBT_AudioSubunitSelector,
288                      0,
289                      id,
290                      purpose,
291                      nrOfInputPlugs,
292                      nrOfOutputPlugs,
293                      verbose )
294 {
295 }
296
297 BeBoB::FunctionBlockSelector::FunctionBlockSelector(
298     const FunctionBlockSelector& rhs )
299     : FunctionBlock( rhs )
300 {
301 }
302
303 BeBoB::FunctionBlockSelector::FunctionBlockSelector()
304     : FunctionBlock()
305 {
306 }
307
308 BeBoB::FunctionBlockSelector::~FunctionBlockSelector()
309 {
310 }
311
312 const char*
313 BeBoB::FunctionBlockSelector::getName()
314 {
315     return "Selector";
316 }
317
318 bool
319 BeBoB::FunctionBlockSelector::serializeChild( Glib::ustring basePath,
320                                               Util::IOSerialize& ser ) const
321 {
322     return true;
323 }
324
325 bool
326 BeBoB::FunctionBlockSelector::deserializeChild( Glib::ustring basePath,
327                                                 Util::IODeserialize& deser,
328                                                 AvDevice& avDevice )
329 {
330     return true;
331 }
332
333 ///////////////////////
334
335 BeBoB::FunctionBlockFeature::FunctionBlockFeature(
336     AvDeviceSubunit& subunit,
337     function_block_id_t id,
338     ESpecialPurpose purpose,
339     no_of_input_plugs_t nrOfInputPlugs,
340     no_of_output_plugs_t nrOfOutputPlugs,
341     int verbose )
342     : FunctionBlock( subunit,
343                      eFBT_AudioSubunitFeature,
344                      0,
345                      id,
346                      purpose,
347                      nrOfInputPlugs,
348                      nrOfOutputPlugs,
349                      verbose )
350 {
351 }
352
353 BeBoB::FunctionBlockFeature::FunctionBlockFeature(
354     const FunctionBlockFeature& rhs )
355     : FunctionBlock( rhs )
356 {
357 }
358
359 BeBoB::FunctionBlockFeature::FunctionBlockFeature()
360     : FunctionBlock()
361 {
362 }
363
364 BeBoB::FunctionBlockFeature::~FunctionBlockFeature()
365 {
366 }
367
368 const char*
369 BeBoB::FunctionBlockFeature::getName()
370 {
371     return "Feature";
372 }
373
374 bool
375 BeBoB::FunctionBlockFeature::serializeChild( Glib::ustring basePath,
376                                              Util::IOSerialize& ser ) const
377 {
378     return true;
379 }
380
381 bool
382 BeBoB::FunctionBlockFeature::deserializeChild( Glib::ustring basePath,
383                                                Util::IODeserialize& deser,
384                                                AvDevice& avDevice )
385 {
386     return true;
387 }
388
389 ///////////////////////
390
391 BeBoB::FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer(
392     AvDeviceSubunit& subunit,
393     function_block_id_t id,
394     ESpecialPurpose purpose,
395     no_of_input_plugs_t nrOfInputPlugs,
396     no_of_output_plugs_t nrOfOutputPlugs,
397     int verbose )
398     : FunctionBlock( subunit,
399                      eFBT_AudioSubunitProcessing,
400                      ExtendedSubunitInfoCmd::ePT_EnhancedMixer,
401                      id,
402                      purpose,
403                      nrOfInputPlugs,
404                      nrOfOutputPlugs,
405                      verbose )
406 {
407 }
408
409 BeBoB::FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer(
410     const FunctionBlockEnhancedMixer& rhs )
411     : FunctionBlock( rhs )
412 {
413 }
414
415 BeBoB::FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer()
416     : FunctionBlock()
417 {
418 }
419
420 BeBoB::FunctionBlockEnhancedMixer::~FunctionBlockEnhancedMixer()
421 {
422 }
423
424 const char*
425 BeBoB::FunctionBlockEnhancedMixer::getName()
426 {
427     return "EnhancedMixer";
428 }
429
430 bool
431 BeBoB::FunctionBlockEnhancedMixer::serializeChild( Glib::ustring basePath,
432                                                    Util::IOSerialize& ser ) const
433 {
434     return true;
435 }
436
437 bool
438 BeBoB::FunctionBlockEnhancedMixer::deserializeChild( Glib::ustring basePath,
439                                                      Util::IODeserialize& deser,
440                                                      AvDevice& avDevice )
441 {
442     return true;
443 }
444
445 ///////////////////////
446
447 BeBoB::FunctionBlockProcessing::FunctionBlockProcessing(
448     AvDeviceSubunit& subunit,
449     function_block_id_t id,
450     ESpecialPurpose purpose,
451     no_of_input_plugs_t nrOfInputPlugs,
452     no_of_output_plugs_t nrOfOutputPlugs,
453     int verbose )
454     : FunctionBlock( subunit,
455                      eFBT_AudioSubunitProcessing,
456                      0,
457                      id,
458                      purpose,
459                      nrOfInputPlugs,
460                      nrOfOutputPlugs,
461                      verbose )
462 {
463 }
464
465 BeBoB::FunctionBlockProcessing::FunctionBlockProcessing(
466     const FunctionBlockProcessing& rhs )
467     : FunctionBlock( rhs )
468 {
469 }
470
471 BeBoB::FunctionBlockProcessing::FunctionBlockProcessing()
472     : FunctionBlock()
473 {
474 }
475
476 BeBoB::FunctionBlockProcessing::~FunctionBlockProcessing()
477 {
478 }
479
480 const char*
481 BeBoB::FunctionBlockProcessing::getName()
482 {
483     return "Dummy Processing";
484 }
485
486 bool
487 BeBoB::FunctionBlockProcessing::serializeChild( Glib::ustring basePath,
488                                                 Util::IOSerialize& ser ) const
489 {
490     return true;
491 }
492
493 bool
494 BeBoB::FunctionBlockProcessing::deserializeChild( Glib::ustring basePath,
495                                                   Util::IODeserialize& deser,
496                                                   AvDevice& avDevice )
497 {
498     return true;
499 }
500
501 ///////////////////////
502
503 BeBoB::FunctionBlockCodec::FunctionBlockCodec(
504     AvDeviceSubunit& subunit,
505     function_block_id_t id,
506     ESpecialPurpose purpose,
507     no_of_input_plugs_t nrOfInputPlugs,
508     no_of_output_plugs_t nrOfOutputPlugs,
509     int verbose )
510     : FunctionBlock( subunit,
511                      eFBT_AudioSubunitCodec,
512                      0,
513                      id,
514                      purpose,
515                      nrOfInputPlugs,
516                      nrOfOutputPlugs,
517                      verbose )
518 {
519 }
520
521 BeBoB::FunctionBlockCodec::FunctionBlockCodec( const FunctionBlockCodec& rhs )
522     : FunctionBlock( rhs )
523 {
524 }
525
526 BeBoB::FunctionBlockCodec::FunctionBlockCodec()
527     : FunctionBlock()
528 {
529 }
530
531 BeBoB::FunctionBlockCodec::~FunctionBlockCodec()
532 {
533 }
534
535 const char*
536 BeBoB::FunctionBlockCodec::getName()
537 {
538     return "Dummy Codec";
539 }
540
541 bool
542 BeBoB::FunctionBlockCodec::serializeChild( Glib::ustring basePath,
543                                            Util::IOSerialize& ser ) const
544 {
545     return true;
546 }
547
548 bool
549 BeBoB::FunctionBlockCodec::deserializeChild( Glib::ustring basePath,
550                                              Util::IODeserialize& deser,
551                                              AvDevice& avDevice )
552 {
553     return true;
554 }
Note: See TracBrowser for help on using the browser.