root/trunk/libfreebob/src/bebob/bebob_avdevice_subunit.cpp

Revision 378, 17.1 kB (checked in by wagi, 17 years ago)

FunctionBlock?: De/Serialize added

Line 
1 /* bebob_avdevice_subunit.cpp
2  * Copyright (C) 2005,06,07 by Daniel Wagner
3  *
4  * This file is part of FreeBoB.
5  *
6  * FreeBoB is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * FreeBoB is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FreeBoB; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA.
19  */
20
21 #include "bebob/bebob_functionblock.h"
22 #include "bebob/bebob_avdevice_subunit.h"
23 #include "bebob/bebob_avdevice.h"
24 #include "bebob/bebob_avplug.h"
25 #include "configrom.h"
26
27 #include "libfreebobavc/avc_plug_info.h"
28 #include "libfreebobavc/avc_extended_stream_format.h"
29 #include "libfreebobavc/avc_serialize.h"
30
31 #include <sstream>
32
33 IMPL_DEBUG_MODULE( BeBoB::AvDeviceSubunit, BeBoB::AvDeviceSubunit, DEBUG_LEVEL_VERBOSE );
34
35 ////////////////////////////////////////////
36
37 BeBoB::AvDeviceSubunit::AvDeviceSubunit( AvDevice& avDevice,
38                                          AVCCommand::ESubunitType type,
39                                          subunit_t id,
40                                          int verboseLevel )
41     : m_avDevice( &avDevice )
42     , m_sbType( type )
43     , m_sbId( id )
44     , m_verboseLevel( verboseLevel )
45 {
46     setDebugLevel( m_verboseLevel );
47 }
48
49 BeBoB::AvDeviceSubunit::AvDeviceSubunit()
50 {
51 }
52
53 BeBoB::AvDeviceSubunit::~AvDeviceSubunit()
54 {
55     for ( AvPlugVector::iterator it = m_plugs.begin();
56           it != m_plugs.end();
57           ++it )
58     {
59         delete *it;
60     }
61 }
62
63 bool
64 BeBoB::AvDeviceSubunit::discover()
65 {
66     if ( !discoverPlugs() ) {
67         debugError( "plug discovering failed\n" );
68         return false;
69     }
70
71     return true;
72 }
73
74 bool
75 BeBoB::AvDeviceSubunit::discoverPlugs()
76 {
77     PlugInfoCmd plugInfoCmd( m_avDevice->get1394Service(),
78                              PlugInfoCmd::eSF_SerialBusIsochronousAndExternalPlug );
79     plugInfoCmd.setNodeId( m_avDevice->getConfigRom().getNodeId() );
80     plugInfoCmd.setCommandType( AVCCommand::eCT_Status );
81     plugInfoCmd.setSubunitType( m_sbType );
82     plugInfoCmd.setSubunitId( m_sbId );
83     plugInfoCmd.setVerbose( m_verboseLevel );
84
85     if ( !plugInfoCmd.fire() ) {
86         debugError( "plug info command failed\n" );
87         return false;
88     }
89
90     debugOutput( DEBUG_LEVEL_NORMAL, "number of source plugs = %d\n",
91                  plugInfoCmd.m_sourcePlugs );
92     debugOutput( DEBUG_LEVEL_NORMAL, "number of destination output "
93                  "plugs = %d\n", plugInfoCmd.m_destinationPlugs );
94
95     if ( !discoverPlugs( AvPlug::eAPD_Input,
96                          plugInfoCmd.m_destinationPlugs ) )
97     {
98         debugError( "destination plug discovering failed\n" );
99         return false;
100     }
101
102     if ( !discoverPlugs(  AvPlug::eAPD_Output,
103                           plugInfoCmd.m_sourcePlugs ) )
104     {
105         debugError( "source plug discovering failed\n" );
106         return false;
107     }
108
109     return true;
110 }
111
112 bool
113 BeBoB::AvDeviceSubunit::discoverConnections()
114 {
115     for ( AvPlugVector::iterator it = m_plugs.begin();
116           it != m_plugs.end();
117           ++it )
118     {
119         AvPlug* plug = *it;
120         if ( !plug->discoverConnections() ) {
121             debugError( "plug connection discovering failed ('%s')\n",
122                         plug->getName() );
123             return false;
124         }
125     }
126
127     return true;
128 }
129
130 bool
131 BeBoB::AvDeviceSubunit::discoverPlugs(AvPlug::EAvPlugDirection plugDirection,
132                                       plug_id_t plugMaxId )
133 {
134     for ( int plugIdx = 0;
135           plugIdx < plugMaxId;
136           ++plugIdx )
137     {
138         AVCCommand::ESubunitType subunitType =
139             static_cast<AVCCommand::ESubunitType>( getSubunitType() );
140         AvPlug* plug = new AvPlug( m_avDevice->get1394Service(),
141                                    m_avDevice->getConfigRom(),
142                                    m_avDevice->getPlugManager(),
143                                    subunitType,
144                                    getSubunitId(),
145                                    0xff,
146                                    0xff,
147                                    AvPlug::eAPA_SubunitPlug,
148                                    plugDirection,
149                                    plugIdx,
150                                    m_verboseLevel );
151         if ( !plug || !plug->discover() ) {
152             debugError( "plug discover failed\n" );
153             return false;
154         }
155
156         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
157                      plug->getName() );
158         m_plugs.push_back( plug );
159     }
160     return true;
161 }
162
163 bool
164 BeBoB::AvDeviceSubunit::addPlug( AvPlug& plug )
165 {
166     m_plugs.push_back( &plug );
167     return true;
168 }
169
170
171 BeBoB::AvPlug*
172 BeBoB::AvDeviceSubunit::getPlug(AvPlug::EAvPlugDirection direction, plug_id_t plugId)
173 {
174     for ( AvPlugVector::iterator it = m_plugs.begin();
175           it != m_plugs.end();
176           ++it )
177     {
178         AvPlug* plug = *it;
179         if ( ( plug->getPlugId() == plugId )
180             && ( plug->getDirection() == direction ) )
181         {
182             return plug;
183         }
184     }
185     return 0;
186 }
187
188
189 bool
190 BeBoB::AvDeviceSubunit::serialize( Glib::ustring basePath,
191                                    Util::IOSerialize& ser ) const
192 {
193     bool result;
194
195     result  = ser.write( basePath + "m_sbType", m_sbType );
196     result &= ser.write( basePath + "m_sbId", m_sbId );
197     result &= ser.write( basePath + "m_verboseLevel", m_verboseLevel );
198     result &= serializeChild( basePath, ser );
199
200     return result;
201 }
202
203 BeBoB::AvDeviceSubunit*
204 BeBoB::AvDeviceSubunit::deserialize( Glib::ustring basePath,
205                                      Util::IODeserialize& deser,
206                                      AvDevice& avDevice )
207 {
208     bool result;
209     AVCCommand::ESubunitType sbType;
210     result  = deser.read( basePath + "m_sbType", sbType );
211
212     AvDeviceSubunit* pSubunit = 0;
213     switch( sbType ) {
214     case AVCCommand::eST_Audio:
215         pSubunit = new AvDeviceSubunitAudio;
216         break;
217     case AVCCommand::eST_Music:
218         pSubunit = new AvDeviceSubunitMusic;
219         break;
220     default:
221         pSubunit = 0;
222     }
223
224     if ( !pSubunit ) {
225         return 0;
226     }
227
228     pSubunit->m_avDevice = &avDevice;
229     pSubunit->m_sbType = sbType;
230     result &= deser.read( basePath + "m_sbId", pSubunit->m_sbId );
231     result &= deser.read( basePath + "m_verboseLevel", pSubunit->m_verboseLevel );
232     result &= pSubunit->deserializeChild( basePath, deser, avDevice );
233
234     if ( !result ) {
235         delete pSubunit;
236         return 0;
237     }
238
239     return pSubunit;
240 }
241
242 ////////////////////////////////////////////
243
244 BeBoB::AvDeviceSubunitAudio::AvDeviceSubunitAudio( AvDevice& avDevice,
245                                                    subunit_t id,
246                                                    int verboseLevel )
247     : AvDeviceSubunit( avDevice, AVCCommand::eST_Audio, id, verboseLevel )
248 {
249 }
250
251 BeBoB::AvDeviceSubunitAudio::AvDeviceSubunitAudio()
252     : AvDeviceSubunit()
253 {
254 }
255
256 BeBoB::AvDeviceSubunitAudio::~AvDeviceSubunitAudio()
257 {
258     for ( FunctionBlockVector::iterator it = m_functions.begin();
259           it != m_functions.end();
260           ++it )
261     {
262         delete *it;
263     }
264 }
265
266 bool
267 BeBoB::AvDeviceSubunitAudio::discover()
268 {
269     if ( !AvDeviceSubunit::discover() ) {
270         return false;
271     }
272
273     if ( !discoverFunctionBlocks() ) {
274         debugError( "function block discovering failed\n" );
275         return false;
276     }
277
278     return true;
279 }
280
281 bool
282 BeBoB::AvDeviceSubunitAudio::discoverConnections()
283 {
284     if ( !AvDeviceSubunit::discoverConnections() ) {
285         return false;
286     }
287
288     for ( FunctionBlockVector::iterator it = m_functions.begin();
289           it != m_functions.end();
290           ++it )
291     {
292         FunctionBlock* function = *it;
293         if ( !function->discoverConnections() ) {
294             debugError( "functionblock connection discovering failed ('%s')\n",
295                         function->getName() );
296             return false;
297         }
298     }
299
300     return true;
301 }
302
303 const char*
304 BeBoB::AvDeviceSubunitAudio::getName()
305 {
306     return "AudioSubunit";
307 }
308
309 bool
310 BeBoB::AvDeviceSubunitAudio::discoverFunctionBlocks()
311 {
312     if ( !discoverFunctionBlocksDo(
313              ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector) )
314     {
315         debugError( "Could not discover function block selector\n" );
316         return false;
317     }
318     if ( !discoverFunctionBlocksDo(
319              ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature) )
320     {
321         debugError( "Could not discover function block feature\n" );
322         return false;
323     }
324     if ( !discoverFunctionBlocksDo(
325              ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing) )
326     {
327         debugError( "Could not discover function block processing\n" );
328         return false;
329     }
330     if ( !discoverFunctionBlocksDo(
331              ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec) )
332     {
333         debugError( "Could not discover function block codec\n" );
334         return false;
335     }
336
337     return true;
338 }
339
340 bool
341 BeBoB::AvDeviceSubunitAudio::discoverFunctionBlocksDo(
342     ExtendedSubunitInfoCmd::EFunctionBlockType fbType )
343 {
344     int page = 0;
345     bool cmdSuccess = false;
346     bool finished = false;
347
348     do {
349         ExtendedSubunitInfoCmd
350             extSubunitInfoCmd( m_avDevice->get1394Service() );
351         extSubunitInfoCmd.setNodeId( m_avDevice->getConfigRom().getNodeId() );
352         extSubunitInfoCmd.setCommandType( AVCCommand::eCT_Status );
353         extSubunitInfoCmd.setSubunitId( getSubunitId() );
354         extSubunitInfoCmd.setSubunitType( getSubunitType() );
355         extSubunitInfoCmd.setVerbose( m_verboseLevel );
356
357         extSubunitInfoCmd.m_fbType = fbType;
358         extSubunitInfoCmd.m_page = page;
359
360         cmdSuccess = extSubunitInfoCmd.fire();
361         if ( cmdSuccess
362              && ( extSubunitInfoCmd.getResponse()
363                   == AVCCommand::eR_Implemented ) )
364         {
365             for ( ExtendedSubunitInfoPageDataVector::iterator it =
366                       extSubunitInfoCmd.m_infoPageDatas.begin();
367                   cmdSuccess
368                       && ( it != extSubunitInfoCmd.m_infoPageDatas.end() );
369                   ++it )
370             {
371                 cmdSuccess = createFunctionBlock( fbType, **it );
372             }
373             if ( ( extSubunitInfoCmd.m_infoPageDatas.size() != 0 )
374                  && ( extSubunitInfoCmd.m_infoPageDatas.size() == 5 ) )
375             {
376                 page++;
377             } else {
378                 finished = true;
379             }
380         } else {
381             finished = true;
382         }
383     } while ( cmdSuccess && !finished );
384
385     return cmdSuccess;
386 }
387
388 bool
389 BeBoB::AvDeviceSubunitAudio::createFunctionBlock(
390     ExtendedSubunitInfoCmd::EFunctionBlockType fbType,
391     ExtendedSubunitInfoPageData& data )
392 {
393     FunctionBlock::ESpecialPurpose purpose
394         = convertSpecialPurpose(  data.m_functionBlockSpecialPupose );
395
396     FunctionBlock* fb = 0;
397
398     switch ( fbType ) {
399     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector:
400     {
401         fb = new FunctionBlockSelector( *this,
402                                         data.m_functionBlockId,
403                                         purpose,
404                                         data.m_noOfInputPlugs,
405                                         data.m_noOfOutputPlugs,
406                                         m_verboseLevel );
407     }
408     break;
409     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature:
410     {
411         fb = new FunctionBlockFeature( *this,
412                                        data.m_functionBlockId,
413                                        purpose,
414                                        data.m_noOfInputPlugs,
415                                        data.m_noOfOutputPlugs,
416                                        m_verboseLevel );
417     }
418     break;
419     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing:
420     {
421         switch ( data.m_functionBlockType ) {
422         case ExtendedSubunitInfoCmd::ePT_EnhancedMixer:
423         {
424             fb = new FunctionBlockEnhancedMixer( *this,
425                                                  data.m_functionBlockId,
426                                                  purpose,
427                                                  data.m_noOfInputPlugs,
428                                                  data.m_noOfOutputPlugs,
429                                                  m_verboseLevel );
430         }
431         break;
432         case ExtendedSubunitInfoCmd::ePT_Mixer:
433         case ExtendedSubunitInfoCmd::ePT_Generic:
434         case ExtendedSubunitInfoCmd::ePT_UpDown:
435         case ExtendedSubunitInfoCmd::ePT_DolbyProLogic:
436         case ExtendedSubunitInfoCmd::ePT_3DStereoExtender:
437         case ExtendedSubunitInfoCmd::ePT_Reverberation:
438         case ExtendedSubunitInfoCmd::ePT_Chorus:
439         case ExtendedSubunitInfoCmd::ePT_DynamicRangeCompression:
440         default:
441             fb = new FunctionBlockProcessing( *this,
442                                               data.m_functionBlockId,
443                                               purpose,
444                                               data.m_noOfInputPlugs,
445                                               data.m_noOfOutputPlugs,
446                                               m_verboseLevel );
447             debugWarning( "Dummy function block processing created. "
448                           "Implementation is missing\n" );
449         }
450     }
451     break;
452     case ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec:
453     {
454         fb = new FunctionBlockCodec( *this,
455                                      data.m_functionBlockId,
456                                      purpose,
457                                      data.m_noOfInputPlugs,
458                                      data.m_noOfOutputPlugs,
459                                      m_verboseLevel );
460         debugWarning( "Dummy function block codec created. "
461                       "Implementation is missing\n" );
462     }
463     break;
464     default:
465         debugError( "Unhandled function block type found\n" );
466         return false;
467     }
468
469     if ( !fb ) {
470         debugError( "Could create function block\n" );
471         return false;
472     }
473     if ( !fb->discover() ) {
474         debugError( "Could not discover function block %s\n",
475                     fb->getName() );
476         delete fb;
477         return false;
478     }
479     m_functions.push_back( fb );
480
481     return true;
482 }
483
484 BeBoB::FunctionBlock::ESpecialPurpose
485 BeBoB::AvDeviceSubunitAudio::convertSpecialPurpose(
486     function_block_special_purpose_t specialPurpose )
487 {
488     FunctionBlock::ESpecialPurpose p;
489     switch ( specialPurpose ) {
490     case ExtendedSubunitInfoPageData::eSP_InputGain:
491         p  = FunctionBlock::eSP_InputGain;
492         break;
493     case ExtendedSubunitInfoPageData::eSP_OutputVolume:
494         p = FunctionBlock::eSP_OutputVolume;
495     break;
496     default:
497         p = FunctionBlock::eSP_NoSpecialPurpose;
498     }
499     return p;
500 }
501
502 bool
503 BeBoB::AvDeviceSubunitAudio::serializeChild( Glib::ustring basePath,
504                                              Util::IOSerialize& ser ) const
505 {
506     bool result = true;
507     int i = 0;
508
509     for ( FunctionBlockVector::const_iterator it = m_functions.begin();
510           it != m_functions.end();
511           ++it )
512     {
513         FunctionBlock* pFB = *it;
514         std::ostringstream strstrm;
515         strstrm << basePath << "FunctionBlock" << i << "/";
516
517         result &= pFB->serialize( strstrm.str() , ser );
518
519         i++;
520     }
521
522     return result;
523 }
524
525 bool
526 BeBoB::AvDeviceSubunitAudio::deserializeChild( Glib::ustring basePath,
527                                                Util::IODeserialize& deser,
528                                                AvDevice& avDevice )
529 {
530     int i = 0;
531     bool bFinished = false;
532     do {
533         std::ostringstream strstrm;
534         strstrm << basePath << "FunctionBlock" << i << "/";
535         FunctionBlock* pFB = FunctionBlock::deserialize( strstrm.str(),
536                                                          deser,
537                                                          avDevice,
538                                                          *this );
539         if ( pFB ) {
540             m_functions.push_back( pFB );
541             i++;
542         } else {
543             bFinished = true;
544         }
545     } while ( !bFinished );
546
547     return true;
548 }
549
550 ////////////////////////////////////////////
551
552 BeBoB::AvDeviceSubunitMusic::AvDeviceSubunitMusic( AvDevice& avDevice,
553                                                    subunit_t id,
554                                                    int verboseLevel )
555     : AvDeviceSubunit( avDevice, AVCCommand::eST_Music, id, verboseLevel )
556 {
557 }
558
559 BeBoB::AvDeviceSubunitMusic::AvDeviceSubunitMusic()
560     : AvDeviceSubunit()
561 {
562 }
563
564 BeBoB::AvDeviceSubunitMusic::~AvDeviceSubunitMusic()
565 {
566 }
567
568 const char*
569 BeBoB::AvDeviceSubunitMusic::getName()
570 {
571     return "MusicSubunit";
572 }
573
574 bool
575 BeBoB::AvDeviceSubunitMusic::serializeChild( Glib::ustring basePath,
576                                              Util::IOSerialize& ser ) const
577 {
578     return true;
579 }
580
581 bool
582 BeBoB::AvDeviceSubunitMusic::deserializeChild( Glib::ustring basePath,
583                                                Util::IODeserialize& deser,
584                                                AvDevice& avDevice )
585 {
586     return true;
587 }
Note: See TracBrowser for help on using the browser.