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

Revision 828, 13.9 kB (checked in by wagi, 15 years ago)

FunctionBlockEnhancedMixer::discover: enable code

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 program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
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 #include "libutil/cmd_serialize.h"
30
31 using namespace AVC;
32
33 namespace BeBoB {
34
35 IMPL_DEBUG_MODULE( FunctionBlock, FunctionBlock, DEBUG_LEVEL_NORMAL );
36
37 FunctionBlock::FunctionBlock(
38     AVC::Subunit& subunit,
39     function_block_type_t type,
40     function_block_type_t subtype,
41     function_block_id_t id,
42     ESpecialPurpose purpose,
43     no_of_input_plugs_t nrOfInputPlugs,
44     no_of_output_plugs_t nrOfOutputPlugs,
45     int verbose )
46     : m_subunit( &subunit )
47     , m_type( type )
48     , m_subtype( subtype )
49     , m_id( id )
50     , m_purpose( purpose )
51     , m_nrOfInputPlugs( nrOfInputPlugs )
52     , m_nrOfOutputPlugs( nrOfOutputPlugs )
53     , m_verbose( verbose )
54 {
55     setDebugLevel( verbose );
56 }
57
58 FunctionBlock::FunctionBlock( const FunctionBlock& rhs )
59     : m_subunit( rhs.m_subunit )
60     , m_type( rhs.m_type )
61     , m_subtype( rhs.m_subtype )
62     , m_id( rhs.m_id )
63     , m_purpose( rhs.m_purpose )
64     , m_nrOfInputPlugs( rhs.m_nrOfInputPlugs )
65     , m_nrOfOutputPlugs( rhs.m_nrOfOutputPlugs )
66     , m_verbose( rhs.m_verbose )
67 {
68 }
69
70 FunctionBlock::FunctionBlock()
71 {
72 }
73
74 FunctionBlock::~FunctionBlock()
75 {
76     for ( PlugVector::iterator it = m_plugs.begin();
77           it != m_plugs.end();
78           ++it )
79     {
80         delete *it;
81     }
82
83 }
84
85 bool
86 FunctionBlock::discover()
87 {
88     debugOutput( DEBUG_LEVEL_NORMAL,
89                  "discover function block %s (nr of input plugs = %d, "
90                  "nr of output plugs = %d)\n",
91                  getName(),
92                  m_nrOfInputPlugs,
93                  m_nrOfOutputPlugs );
94
95     if ( !discoverPlugs( AVC::Plug::eAPD_Input, m_nrOfInputPlugs ) ) {
96         debugError( "Could not discover input plug for '%s'\n",
97                     getName() );
98         return false;
99     }
100
101     if ( !discoverPlugs( AVC::Plug::eAPD_Output, m_nrOfOutputPlugs ) ) {
102         debugError( "Could not discover output plugs for '%s'\n",
103                     getName() );
104         return false;
105     }
106
107     return true;
108 }
109
110 bool
111 FunctionBlock::discoverPlugs( AVC::Plug::EPlugDirection plugDirection,
112                               plug_id_t plugMaxId )
113 {
114     for ( int plugId = 0; plugId < plugMaxId; ++plugId ) {
115         AVC::Plug* plug = new BeBoB::Plug(
116             &m_subunit->getUnit(),
117             m_subunit,
118             m_type,
119             m_id,
120             AVC::Plug::eAPA_FunctionBlockPlug,
121             plugDirection,
122             plugId);
123
124         if ( !plug || !plug->discover() ) {
125             debugError( "plug discovering failed for plug %d\n",
126                         plugId );
127             delete plug;
128             return false;
129         }
130
131         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
132                      plug->getName() );
133         m_plugs.push_back( plug );
134     }
135
136     return true;
137 }
138
139 bool
140 FunctionBlock::discoverConnections()
141 {
142     debugOutput( DEBUG_LEVEL_VERBOSE,
143                  "discover connections function block %s\n",
144                  getName() );
145
146     for ( PlugVector::iterator it = m_plugs.begin();
147           it != m_plugs.end();
148           ++it )
149     {
150         BeBoB::Plug* plug = dynamic_cast<BeBoB::Plug*>(*it);
151         if(!plug) {
152             debugError("BUG: not a bebob plug\n");
153             return false;
154         }
155         if ( !plug->discoverConnections() ) {
156             debugError( "Could not discover plug connections\n" );
157             return false;
158         }
159     }
160     return true;
161 }
162
163 bool
164 FunctionBlock::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const
165 {
166     bool result;
167
168     result  = ser.write( basePath + "m_type", m_type );
169     result &= ser.write( basePath + "m_subtype", m_subtype );
170     result &= ser.write( basePath + "m_id", m_id );
171     result &= ser.write( basePath + "m_purpose", m_purpose );
172     result &= ser.write( basePath + "m_nrOfInputPlugs", m_nrOfInputPlugs );
173     result &= ser.write( basePath + "m_nrOfOutputPlugs", m_nrOfOutputPlugs );
174     result &= serializePlugVector( basePath + "m_plugs", ser, m_plugs );
175
176     return result;
177 }
178
179 FunctionBlock*
180 FunctionBlock::deserialize( Glib::ustring basePath,
181                             Util::IODeserialize& deser,
182                             AVC::Unit& unit,
183                             AVC::Subunit& subunit )
184 {
185     bool result;
186     function_block_type_t type;
187     function_block_type_t subtype;
188     FunctionBlock* pFB = 0;
189
190     result  = deser.read( basePath + "m_type", type );
191     result &= deser.read( basePath + "m_subtype", subtype );
192     if ( !result ) {
193         return 0;
194     }
195
196     switch ( type ) {
197     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector:
198         pFB = new FunctionBlockSelector;
199         break;
200     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature:
201         pFB = new FunctionBlockFeature;
202         break;
203     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing:
204         if ( subtype == ExtendedSubunitInfoCmd::ePT_EnhancedMixer ) {
205             pFB = new FunctionBlockEnhancedMixer;
206         } else {
207             pFB = new FunctionBlockProcessing;
208         }
209         break;
210     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec:
211         pFB = new FunctionBlockCodec;
212         break;
213     default:
214         pFB = 0;
215     }
216
217     if ( !pFB ) {
218         return 0;
219     }
220
221     pFB->m_subunit = &subunit;
222     pFB->m_type = type;
223     pFB->m_subtype = subtype;
224
225     result &= deser.read( basePath + "m_id", pFB->m_id );
226     result &= deser.read( basePath + "m_purpose", pFB->m_purpose );
227     result &= deser.read( basePath + "m_nrOfInputPlugs", pFB->m_nrOfInputPlugs );
228     result &= deser.read( basePath + "m_nrOfOutputPlugs", pFB->m_nrOfOutputPlugs );
229     result &= deserializePlugVector( basePath + "m_plugs", deser,
230                                      unit.getPlugManager(), pFB->m_plugs );
231
232     return 0;
233 }
234
235 ///////////////////////
236
237 FunctionBlockSelector::FunctionBlockSelector(
238     AVC::Subunit& subunit,
239     function_block_id_t id,
240     ESpecialPurpose purpose,
241     no_of_input_plugs_t nrOfInputPlugs,
242     no_of_output_plugs_t nrOfOutputPlugs,
243     int verbose )
244     : FunctionBlock( subunit,
245                      eFBT_AudioSubunitSelector,
246                      0,
247                      id,
248                      purpose,
249                      nrOfInputPlugs,
250                      nrOfOutputPlugs,
251                      verbose )
252 {
253 }
254
255 FunctionBlockSelector::FunctionBlockSelector(
256     const FunctionBlockSelector& rhs )
257     : FunctionBlock( rhs )
258 {
259 }
260
261 FunctionBlockSelector::FunctionBlockSelector()
262     : FunctionBlock()
263 {
264 }
265
266 FunctionBlockSelector::~FunctionBlockSelector()
267 {
268 }
269
270 const char*
271 FunctionBlockSelector::getName()
272 {
273     return "Selector";
274 }
275
276 bool
277 FunctionBlockSelector::serializeChild( Glib::ustring basePath,
278                                        Util::IOSerialize& ser ) const
279 {
280     return true;
281 }
282
283 bool
284 FunctionBlockSelector::deserializeChild( Glib::ustring basePath,
285                                          Util::IODeserialize& deser,
286                                          AvDevice& unit )
287 {
288     return true;
289 }
290
291 ///////////////////////
292
293 FunctionBlockFeature::FunctionBlockFeature(
294     AVC::Subunit& subunit,
295     function_block_id_t id,
296     ESpecialPurpose purpose,
297     no_of_input_plugs_t nrOfInputPlugs,
298     no_of_output_plugs_t nrOfOutputPlugs,
299     int verbose )
300     : FunctionBlock( subunit,
301                      eFBT_AudioSubunitFeature,
302                      0,
303                      id,
304                      purpose,
305                      nrOfInputPlugs,
306                      nrOfOutputPlugs,
307                      verbose )
308 {
309 }
310
311 FunctionBlockFeature::FunctionBlockFeature(
312     const FunctionBlockFeature& rhs )
313     : FunctionBlock( rhs )
314 {
315 }
316
317 FunctionBlockFeature::FunctionBlockFeature()
318     : FunctionBlock()
319 {
320 }
321
322 FunctionBlockFeature::~FunctionBlockFeature()
323 {
324 }
325
326 const char*
327 FunctionBlockFeature::getName()
328 {
329     return "Feature";
330 }
331
332 bool
333 FunctionBlockFeature::serializeChild( Glib::ustring basePath,
334                                       Util::IOSerialize& ser ) const
335 {
336     return true;
337 }
338
339 bool
340 FunctionBlockFeature::deserializeChild( Glib::ustring basePath,
341                                         Util::IODeserialize& deser,
342                                         AvDevice& unit )
343 {
344     return true;
345 }
346
347 ///////////////////////
348
349 FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer(
350     AVC::Subunit& subunit,
351     function_block_id_t id,
352     ESpecialPurpose purpose,
353     no_of_input_plugs_t nrOfInputPlugs,
354     no_of_output_plugs_t nrOfOutputPlugs,
355     int verbose )
356     : FunctionBlock( subunit,
357                      eFBT_AudioSubunitProcessing,
358                      ExtendedSubunitInfoCmd::ePT_EnhancedMixer,
359                      id,
360                      purpose,
361                      nrOfInputPlugs,
362                      nrOfOutputPlugs,
363                      verbose )
364 {
365 }
366
367 FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer(
368     const FunctionBlockEnhancedMixer& rhs )
369     : FunctionBlock( rhs )
370 {
371 }
372
373 FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer()
374     : FunctionBlock()
375 {
376 }
377
378 FunctionBlockEnhancedMixer::~FunctionBlockEnhancedMixer()
379 {
380 }
381
382 bool
383 FunctionBlockEnhancedMixer::discover()
384 {
385     if (!FunctionBlock::discover())
386         return false;
387
388     AVC::FunctionBlockCmd fbCmd( m_subunit->getUnit().get1394Service(),
389                                  FunctionBlockCmd::eFBT_Processing,
390                                  m_id,
391                                  FunctionBlockCmd::eCA_Current);
392     fbCmd.setNodeId( m_subunit->getUnit().getConfigRom().getNodeId() );
393     fbCmd.setSubunitId( 0x00 );
394     fbCmd.setCommandType( AVCCommand::eCT_Status );
395     // fbCmd.setVerboseLevel( DEBUG_LEVEL_VERY_VERBOSE );
396
397     // Ok, this enhanced  mixer setting here is just a hack, we need
398     // a sane way to set processing features (read pointer management)
399     AVC::FunctionBlockProcessingEnhancedMixer em;
400     delete fbCmd.m_pFBProcessing->m_pMixer;
401     fbCmd.m_pFBProcessing->m_pMixer = 0;
402     fbCmd.m_pFBProcessing->m_pEnhancedMixer = em.clone();
403    
404     if ( !fbCmd.fire() ) {
405         debugError( "cmd failed\n" );
406         return false;
407     }
408    
409 //     if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
410 //         Util::Cmd::CoutSerializer se;
411 //         fbCmd.serialize( se );
412 //     }
413
414     if((fbCmd.getResponse() != AVCCommand::eR_Implemented)) {
415         debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
416     }
417    
418     return true;
419 }
420
421
422 const char*
423 FunctionBlockEnhancedMixer::getName()
424 {
425     return "EnhancedMixer";
426 }
427
428 bool
429 FunctionBlockEnhancedMixer::serializeChild( Glib::ustring basePath,
430                                             Util::IOSerialize& ser ) const
431 {
432     return true;
433 }
434
435 bool
436 FunctionBlockEnhancedMixer::deserializeChild( Glib::ustring basePath,
437                                               Util::IODeserialize& deser,
438                                               AvDevice& unit )
439 {
440     return true;
441 }
442
443 ///////////////////////
444
445 FunctionBlockProcessing::FunctionBlockProcessing(
446     AVC::Subunit& subunit,
447     function_block_id_t id,
448     ESpecialPurpose purpose,
449     no_of_input_plugs_t nrOfInputPlugs,
450     no_of_output_plugs_t nrOfOutputPlugs,
451     int verbose )
452     : FunctionBlock( subunit,
453                      eFBT_AudioSubunitProcessing,
454                      0,
455                      id,
456                      purpose,
457                      nrOfInputPlugs,
458                      nrOfOutputPlugs,
459                      verbose )
460 {
461 }
462
463 FunctionBlockProcessing::FunctionBlockProcessing(
464     const FunctionBlockProcessing& rhs )
465     : FunctionBlock( rhs )
466 {
467 }
468
469 FunctionBlockProcessing::FunctionBlockProcessing()
470     : FunctionBlock()
471 {
472 }
473
474 FunctionBlockProcessing::~FunctionBlockProcessing()
475 {
476 }
477
478 const char*
479 FunctionBlockProcessing::getName()
480 {
481     return "Dummy Processing";
482 }
483
484 bool
485 FunctionBlockProcessing::serializeChild( Glib::ustring basePath,
486                                          Util::IOSerialize& ser ) const
487 {
488     return true;
489 }
490
491 bool
492 FunctionBlockProcessing::deserializeChild( Glib::ustring basePath,
493                                            Util::IODeserialize& deser,
494                                            AvDevice& unit )
495 {
496     return true;
497 }
498
499 ///////////////////////
500
501 FunctionBlockCodec::FunctionBlockCodec(
502     AVC::Subunit& subunit,
503     function_block_id_t id,
504     ESpecialPurpose purpose,
505     no_of_input_plugs_t nrOfInputPlugs,
506     no_of_output_plugs_t nrOfOutputPlugs,
507     int verbose )
508     : FunctionBlock( subunit,
509                      eFBT_AudioSubunitCodec,
510                      0,
511                      id,
512                      purpose,
513                      nrOfInputPlugs,
514                      nrOfOutputPlugs,
515                      verbose )
516 {
517 }
518
519 FunctionBlockCodec::FunctionBlockCodec( const FunctionBlockCodec& rhs )
520     : FunctionBlock( rhs )
521 {
522 }
523
524 FunctionBlockCodec::FunctionBlockCodec()
525     : FunctionBlock()
526 {
527 }
528
529 FunctionBlockCodec::~FunctionBlockCodec()
530 {
531 }
532
533 const char*
534 FunctionBlockCodec::getName()
535 {
536     return "Dummy Codec";
537 }
538
539 bool
540 FunctionBlockCodec::serializeChild( Glib::ustring basePath,
541                                     Util::IOSerialize& ser ) const
542 {
543     return true;
544 }
545
546 bool
547 FunctionBlockCodec::deserializeChild( Glib::ustring basePath,
548                                       Util::IODeserialize& deser,
549                                       AvDevice& unit )
550 {
551     return true;
552 }
553
554 }
Note: See TracBrowser for help on using the browser.