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

Revision 734, 14.0 kB (checked in by ppalmers, 16 years ago)

merge ppalmers-streaming branch

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