root/branches/streaming-rework/src/bebob/bebob_avdevice.cpp

Revision 395, 48.4 kB (checked in by pieterpalmers, 16 years ago)

debugmodule.cpp:
- removed path from the source file name when printing debug messages

IsoStream?.cpp, StreamProcessor?.cpp:
- debug message modifications

StreamProcessorManager?.cpp:
- removed obsolete debug code

AmdtpStreamProcessor?.cpp:
- debug message modifications
- removed DLL that calculates framerate, as it is also calculated in the

TimestampedBuffer?

- converted code to use the new offset feature of the TimestampedBuffer?
- converted code to use the new frame timestamp calculation feature

of the TimestampedBuffer?

- first try at xmit sync code (unfinished)
- fixed 'unable to start' bug in receive SP

bebob_avdevice.cpp:
- added some #ifdef code to test with xmit SP's only (temporary)

TimestampedBuffer?.cpp:
- add offset feature
- add abitrary frame timestamp calculation

Line 
1 /* bebob_avdevice.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_avdevice.h"
22 #include "bebob/bebob_avdevice_subunit.h"
23 #include "configrom.h"
24
25 #include "libfreebobavc/avc_plug_info.h"
26 #include "libfreebobavc/avc_extended_plug_info.h"
27 #include "libfreebobavc/avc_subunit_info.h"
28 #include "libfreebobavc/avc_extended_stream_format.h"
29 #include "libfreebobavc/avc_serialize.h"
30 #include "libfreebobavc/ieee1394service.h"
31 #include "libfreebobavc/avc_definitions.h"
32
33 #include "debugmodule/debugmodule.h"
34
35 #include <iostream>
36 #include <sstream>
37
38 namespace BeBoB {
39
40 IMPL_DEBUG_MODULE( AvDevice, AvDevice, DEBUG_LEVEL_NORMAL );
41
42 AvDevice::AvDevice( std::auto_ptr< ConfigRom >( configRom ),
43                     Ieee1394Service& ieee1394service,
44                     int nodeId,
45                     int verboseLevel )
46     : m_pConfigRom( configRom )
47     , m_p1394Service( &ieee1394service )
48     , m_verboseLevel( verboseLevel )
49     , m_pPlugManager( new AvPlugManager( verboseLevel ) )
50     , m_activeSyncInfo( 0 )
51     , m_id( 0 )
52     , m_receiveProcessor ( 0 )
53     , m_receiveProcessorBandwidth ( -1 )
54     , m_transmitProcessor ( 0 )
55     , m_transmitProcessorBandwidth ( -1 )
56 {
57     setDebugLevel( verboseLevel );
58     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::AvDevice (NodeID %d)\n",
59                  nodeId );
60 }
61
62 AvDevice::AvDevice()
63     : m_pConfigRom( 0 )
64     , m_p1394Service( 0 )
65     , m_verboseLevel( 0 )
66     , m_pPlugManager( 0 )
67     , m_activeSyncInfo( 0 )
68     , m_id( 0 )
69     , m_receiveProcessor ( 0 )
70     , m_receiveProcessorBandwidth ( -1 )
71     , m_transmitProcessor ( 0 )
72     , m_transmitProcessorBandwidth ( -1 )
73 {
74 }
75
76 AvDevice::~AvDevice()
77 {
78     for ( AvDeviceSubunitVector::iterator it = m_subunits.begin();
79           it != m_subunits.end();
80           ++it )
81     {
82         delete *it;
83     }
84     for ( AvPlugConnectionVector::iterator it = m_plugConnections.begin();
85           it != m_plugConnections.end();
86           ++it )
87     {
88         delete *it;
89     }
90     for ( AvPlugVector::iterator it = m_pcrPlugs.begin();
91           it != m_pcrPlugs.end();
92           ++it )
93     {
94         delete *it;
95     }
96     for ( AvPlugVector::iterator it = m_externalPlugs.begin();
97           it != m_externalPlugs.end();
98           ++it )
99     {
100         delete *it;
101     }
102 }
103
104 ConfigRom&
105 AvDevice::getConfigRom() const
106 {
107     return *m_pConfigRom;
108 }
109
110 struct VendorModelEntry {
111     unsigned int vendor_id;
112     unsigned int model_id;
113 };
114
115 static VendorModelEntry supportedDeviceList[] =
116 {
117     {0x00000f, 0x00010065},  // Mackie, Onyx Firewire
118
119     {0x0003db, 0x00010048},  // Apogee Electronics, Rosetta 200
120
121     {0x0007f5, 0x00010048},  // BridgeCo, RD Audio1
122
123     {0x000a92, 0x00010000},  // PreSonus FIREBOX
124     {0x000a92, 0x00010066},  // PreSonus FirePOD
125
126     {0x000aac, 0x00000003},  // TerraTec Electronic GmbH, Phase 88 FW
127     {0x000aac, 0x00000004},  // TerraTec Electronic GmbH, Phase X24 FW (model version 4)
128     {0x000aac, 0x00000007},  // TerraTec Electronic GmbH, Phase X24 FW (model version 7)
129
130     {0x000f1b, 0x00010064},  // ESI, Quatafire 610
131
132     {0x00130e, 0x00000003},  // Focusrite, Pro26IO (Saffire 26)
133
134     {0x0040ab, 0x00010048},  // EDIROL, FA-101
135     {0x0040ab, 0x00010049},  // EDIROL, FA-66
136 };
137
138 bool
139 AvDevice::probe( ConfigRom& configRom )
140 {
141     unsigned int vendorId = configRom.getNodeVendorId();
142     unsigned int modelId = configRom.getModelId();
143
144     for ( unsigned int i = 0;
145           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
146           ++i )
147     {
148         if ( ( supportedDeviceList[i].vendor_id == vendorId )
149              && ( supportedDeviceList[i].model_id == modelId ) )
150         {
151             return true;
152         }
153     }
154
155     return false;
156 }
157
158 bool
159 AvDevice::discover()
160 {
161     if ( !enumerateSubUnits() ) {
162         debugError( "Could not enumarate sub units\n" );
163         return false;
164     }
165
166     if ( !discoverPlugs() ) {
167         debugError( "Detecting plugs failed\n" );
168         return false;
169     }
170
171     if ( !discoverPlugConnections() ) {
172         debugError( "Detecting plug connections failed\n" );
173         return false;
174     }
175
176     if ( !discoverSubUnitsPlugConnections() ) {
177         debugError( "Detecting plug connnection failed\n" );
178         return false;
179     }
180
181     if ( !discoverSyncModes() ) {
182         debugError( "Detecting sync modes failed\n" );
183         return false;
184     }
185
186     return true;
187 }
188
189 bool
190 AvDevice::discoverPlugs()
191 {
192     //////////////////////////////////////////////
193     // Get number of available isochronous input
194     // and output plugs of unit
195
196     PlugInfoCmd plugInfoCmd( *m_p1394Service );
197     plugInfoCmd.setNodeId( m_pConfigRom->getNodeId() );
198     plugInfoCmd.setCommandType( AVCCommand::eCT_Status );
199     plugInfoCmd.setVerbose( m_verboseLevel );
200
201     if ( !plugInfoCmd.fire() ) {
202         debugError( "plug info command failed\n" );
203         return false;
204     }
205
206     debugOutput( DEBUG_LEVEL_NORMAL, "number of iso input plugs = %d\n",
207                  plugInfoCmd.m_serialBusIsochronousInputPlugs );
208     debugOutput( DEBUG_LEVEL_NORMAL, "number of iso output plugs = %d\n",
209                  plugInfoCmd.m_serialBusIsochronousOutputPlugs );
210     debugOutput( DEBUG_LEVEL_NORMAL, "number of external input plugs = %d\n",
211                  plugInfoCmd.m_externalInputPlugs );
212     debugOutput( DEBUG_LEVEL_NORMAL, "number of external output plugs = %d\n",
213                  plugInfoCmd.m_externalOutputPlugs );
214
215     if ( !discoverPlugsPCR( AvPlug::eAPD_Input,
216                             plugInfoCmd.m_serialBusIsochronousInputPlugs ) )
217     {
218         debugError( "pcr input plug discovering failed\n" );
219         return false;
220     }
221
222     if ( !discoverPlugsPCR( AvPlug::eAPD_Output,
223                             plugInfoCmd.m_serialBusIsochronousOutputPlugs ) )
224     {
225         debugError( "pcr output plug discovering failed\n" );
226         return false;
227     }
228
229     if ( !discoverPlugsExternal( AvPlug::eAPD_Input,
230                                  plugInfoCmd.m_externalInputPlugs ) )
231     {
232         debugError( "external input plug discovering failed\n" );
233         return false;
234     }
235
236     if ( !discoverPlugsExternal( AvPlug::eAPD_Output,
237                                  plugInfoCmd.m_externalOutputPlugs ) )
238     {
239         debugError( "external output plug discovering failed\n" );
240         return false;
241     }
242
243     return true;
244 }
245
246 bool
247 AvDevice::discoverPlugsPCR( AvPlug::EAvPlugDirection plugDirection,
248                             plug_id_t plugMaxId )
249 {
250     for ( int plugId = 0;
251           plugId < plugMaxId;
252           ++plugId )
253     {
254         AvPlug* plug  = new AvPlug( *m_p1394Service,
255                                     *m_pConfigRom,
256                                     *m_pPlugManager,
257                                     AVCCommand::eST_Unit,
258                                     0xff,
259                                     0xff,
260                                     0xff,
261                                     AvPlug::eAPA_PCR,
262                                     plugDirection,
263                                     plugId,
264                                     m_verboseLevel );
265         if ( !plug || !plug->discover() ) {
266             debugError( "plug discovering failed\n" );
267             delete plug;
268             return false;
269         }
270
271         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
272                      plug->getName() );
273         m_pcrPlugs.push_back( plug );
274     }
275
276     return true;
277 }
278
279 bool
280 AvDevice::discoverPlugsExternal( AvPlug::EAvPlugDirection plugDirection,
281                                  plug_id_t plugMaxId )
282 {
283     for ( int plugId = 0;
284           plugId < plugMaxId;
285           ++plugId )
286     {
287         AvPlug* plug  = new AvPlug( *m_p1394Service,
288                                     *m_pConfigRom,
289                                     *m_pPlugManager,
290                                     AVCCommand::eST_Unit,
291                                     0xff,
292                                     0xff,
293                                     0xff,
294                                     AvPlug::eAPA_ExternalPlug,
295                                     plugDirection,
296                                     plugId,
297                                     m_verboseLevel );
298         if ( !plug || !plug->discover() ) {
299             debugError( "plug discovering failed\n" );
300             return false;
301         }
302
303         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
304                      plug->getName() );
305         m_externalPlugs.push_back( plug );
306     }
307
308     return true;
309 }
310
311 bool
312 AvDevice::discoverPlugConnections()
313 {
314     for ( AvPlugVector::iterator it = m_pcrPlugs.begin();
315           it != m_pcrPlugs.end();
316           ++it )
317     {
318         AvPlug* plug = *it;
319         if ( !plug->discoverConnections() ) {
320             debugError( "Could not discover plug connections\n" );
321             return false;
322         }
323     }
324     for ( AvPlugVector::iterator it = m_externalPlugs.begin();
325           it != m_externalPlugs.end();
326           ++it )
327     {
328         AvPlug* plug = *it;
329         if ( !plug->discoverConnections() ) {
330             debugError( "Could not discover plug connections\n" );
331             return false;
332         }
333     }
334
335     return true;
336 }
337
338 bool
339 AvDevice::discoverSubUnitsPlugConnections()
340 {
341     for ( AvDeviceSubunitVector::iterator it = m_subunits.begin();
342           it != m_subunits.end();
343           ++it )
344     {
345         AvDeviceSubunit* subunit = *it;
346         if ( !subunit->discoverConnections() ) {
347             debugError( "Subunit '%s'  plug connections failed\n",
348                         subunit->getName() );
349             return false;
350         }
351     }
352     return true;
353 }
354
355 bool
356 AvDevice::discoverSyncModes()
357 {
358     // Following possible sync plugs exists:
359     // - Music subunit sync output plug = internal sync (CSP)
360     // - Unit input plug 0 = SYT match
361     // - Unit input plut 1 = Sync stream
362     //
363     // If last sync mode is reported it is mostelikely not
364     // implemented *sic*
365     //
366     // Following sync sources are device specific:
367     // - All unit external input plugs which have a
368     //   sync information (WS, SPDIF, ...)
369
370     // First we have to find the sync input and output plug
371     // in the music subunit.
372
373     // Note PCR input means 1394bus-to-device where as
374     // MSU input means subunit-to-device
375
376     AvPlugVector syncPCRInputPlugs = getPlugsByType( m_pcrPlugs,
377                                                      AvPlug::eAPD_Input,
378                                                      AvPlug::eAPT_Sync );
379     if ( !syncPCRInputPlugs.size() ) {
380         debugWarning( "No PCR sync input plug found\n" );
381     }
382
383     AvPlugVector syncPCROutputPlugs = getPlugsByType( m_pcrPlugs,
384                                                       AvPlug::eAPD_Output,
385                                                       AvPlug::eAPT_Sync );
386     if ( !syncPCROutputPlugs.size() ) {
387         debugWarning( "No PCR sync output plug found\n" );
388     }
389
390     AvPlugVector isoPCRInputPlugs = getPlugsByType( m_pcrPlugs,
391                                                     AvPlug::eAPD_Input,
392                                                     AvPlug::eAPT_IsoStream );
393     if ( !isoPCRInputPlugs.size() ) {
394         debugWarning( "No PCR iso input plug found\n" );
395
396     }
397
398     AvPlugVector isoPCROutputPlugs = getPlugsByType( m_pcrPlugs,
399                                                     AvPlug::eAPD_Output,
400                                                     AvPlug::eAPT_IsoStream );
401     if ( !isoPCROutputPlugs.size() ) {
402         debugWarning( "No PCR iso output plug found\n" );
403
404     }
405
406     AvPlugVector digitalPCRInputPlugs = getPlugsByType( m_externalPlugs,
407                                                     AvPlug::eAPD_Input,
408                                                     AvPlug::eAPT_Digital );
409
410     AvPlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType(
411         AVCCommand::eST_Music,
412         0,
413         0xff,
414         0xff,
415         AvPlug::eAPA_SubunitPlug,
416         AvPlug::eAPD_Input,
417         AvPlug::eAPT_Sync );
418     if ( !syncMSUInputPlugs.size() ) {
419         debugWarning( "No sync input plug for MSU subunit found\n" );
420     }
421
422     AvPlugVector syncMSUOutputPlugs = m_pPlugManager->getPlugsByType(
423         AVCCommand::eST_Music,
424         0,
425         0xff,
426         0xff,
427         AvPlug::eAPA_SubunitPlug,
428         AvPlug::eAPD_Output,
429         AvPlug::eAPT_Sync );
430     if ( !syncMSUOutputPlugs.size() ) {
431         debugWarning( "No sync output plug for MSU subunit found\n" );
432     }
433
434     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Input Plugs:\n" );
435     showAvPlugs( syncPCRInputPlugs );
436     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Output Plugs:\n" );
437     showAvPlugs( syncPCROutputPlugs );
438     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Input Plugs:\n" );
439     showAvPlugs( isoPCRInputPlugs );
440     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Output Plugs:\n" );
441     showAvPlugs( isoPCROutputPlugs );
442     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR digital Input Plugs:\n" );
443     showAvPlugs( digitalPCRInputPlugs );
444     debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Input Plugs:\n" );
445     showAvPlugs( syncMSUInputPlugs );
446     debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Output Plugs:\n" );
447     showAvPlugs( syncMSUOutputPlugs );
448
449     // Check all possible PCR input to MSU input connections
450     // -> sync stream input
451     checkSyncConnectionsAndAddToList( syncPCRInputPlugs,
452                                       syncMSUInputPlugs,
453                                       "Sync Stream Input" );
454
455     // Check all possible MSU output to PCR output connections
456     // -> sync stream output
457     checkSyncConnectionsAndAddToList( syncMSUOutputPlugs,
458                                       syncPCROutputPlugs,
459                                       "Sync Stream Output" );
460
461     // Check all PCR iso input to MSU input connections
462     // -> SYT match
463     checkSyncConnectionsAndAddToList( isoPCRInputPlugs,
464                                       syncMSUInputPlugs,
465                                       "Syt Match" );
466
467     // Check all MSU sync output to MSU input connections
468     // -> CSP
469     checkSyncConnectionsAndAddToList( syncMSUOutputPlugs,
470                                       syncMSUInputPlugs,
471                                       "Internal (CSP)" );
472
473     // Check all external PCR digital input to MSU input connections
474     // -> SPDIF/ADAT sync
475     checkSyncConnectionsAndAddToList( digitalPCRInputPlugs,
476                                       syncMSUInputPlugs,
477                                       "Digital Input Sync" );
478
479     // Currently active connection signal source cmd, command type
480     // status, source unknown, destination MSU sync input plug
481
482     for ( AvPlugVector::const_iterator it = syncMSUInputPlugs.begin();
483           it != syncMSUInputPlugs.end();
484           ++it )
485     {
486         AvPlug* msuPlug = *it;
487         for ( AvPlugVector::const_iterator jt =
488                   msuPlug->getInputConnections().begin();
489               jt != msuPlug->getInputConnections().end();
490               ++jt )
491         {
492             AvPlug* plug = *jt;
493
494             for ( SyncInfoVector::iterator it = m_syncInfos.begin();
495                   it != m_syncInfos.end();
496                   ++it )
497             {
498                 SyncInfo* pSyncInfo = &*it;
499                 if ( ( pSyncInfo->m_source == plug )
500                      && ( pSyncInfo->m_destination == msuPlug ) )
501                 {
502                     m_activeSyncInfo = pSyncInfo;
503                     break;
504                 }
505             }
506             debugOutput( DEBUG_LEVEL_NORMAL,
507                          "Active Sync Connection: '%s' -> '%s'\n",
508                          plug->getName(),
509                          msuPlug->getName() );
510         }
511     }
512
513     return true;
514 }
515
516 bool
517 AvDevice::enumerateSubUnits()
518 {
519     bool musicSubunitFound=false;
520     bool audioSubunitFound=false;
521
522     SubUnitInfoCmd subUnitInfoCmd( *m_p1394Service );
523     //subUnitInfoCmd.setVerbose( 1 );
524     subUnitInfoCmd.setCommandType( AVCCommand::eCT_Status );
525
526     // BeBoB has always exactly one audio and one music subunit. This
527     // means is fits into the first page of the SubUnitInfo command.
528     // So there is no need to do more than needed
529
530     subUnitInfoCmd.m_page = 0;
531     subUnitInfoCmd.setNodeId( m_pConfigRom->getNodeId() );
532     subUnitInfoCmd.setVerbose( m_verboseLevel );
533     if ( !subUnitInfoCmd.fire() ) {
534         debugError( "Subunit info command failed\n" );
535         // shouldn't this be an error situation?
536         return false;
537     }
538
539     for ( int i = 0; i < subUnitInfoCmd.getNrOfValidEntries(); ++i ) {
540         subunit_type_t subunit_type
541             = subUnitInfoCmd.m_table[i].m_subunit_type;
542
543         unsigned int subunitId = getNrOfSubunits( subunit_type );
544
545         debugOutput( DEBUG_LEVEL_VERBOSE,
546                      "subunit_id = %2d, subunit_type = %2d (%s)\n",
547                      subunitId,
548                      subunit_type,
549                      subunitTypeToString( subunit_type ) );
550
551         AvDeviceSubunit* subunit = 0;
552         switch( subunit_type ) {
553         case AVCCommand::eST_Audio:
554             subunit = new AvDeviceSubunitAudio( *this,
555                                                 subunitId,
556                                                 m_verboseLevel );
557             if ( !subunit ) {
558                 debugFatal( "Could not allocate AvDeviceSubunitAudio\n" );
559                 return false;
560             }
561
562             m_subunits.push_back( subunit );
563             audioSubunitFound=true;
564
565             break;
566         case AVCCommand::eST_Music:
567             subunit = new AvDeviceSubunitMusic( *this,
568                                                 subunitId,
569                                                 m_verboseLevel );
570             if ( !subunit ) {
571                 debugFatal( "Could not allocate AvDeviceSubunitMusic\n" );
572                 return false;
573             }
574
575             m_subunits.push_back( subunit );
576             musicSubunitFound=true;
577
578             break;
579         default:
580             debugOutput( DEBUG_LEVEL_NORMAL,
581                          "Unsupported subunit found, subunit_type = %d (%s)\n",
582                          subunit_type,
583                          subunitTypeToString( subunit_type ) );
584             continue;
585
586         }
587
588         if ( !subunit->discover() ) {
589             debugError( "enumerateSubUnits: Could not discover "
590                         "subunit_id = %2d, subunit_type = %2d (%s)\n",
591                         subunitId,
592                         subunit_type,
593                         subunitTypeToString( subunit_type ) );
594             delete subunit;
595             return false;
596         }
597
598     }
599
600     // a BeBoB always has an audio and a music subunit
601     return (musicSubunitFound && audioSubunitFound);
602 }
603
604
605 AvDeviceSubunit*
606 AvDevice::getSubunit( subunit_type_t subunitType,
607                       subunit_id_t subunitId ) const
608 {
609     for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin();
610           it != m_subunits.end();
611           ++it )
612     {
613         AvDeviceSubunit* subunit = *it;
614         if ( ( subunitType == subunit->getSubunitType() )
615              && ( subunitId == subunit->getSubunitId() ) )
616         {
617             return subunit;
618         }
619     }
620
621     return 0;
622 }
623
624
625 unsigned int
626 AvDevice::getNrOfSubunits( subunit_type_t subunitType ) const
627 {
628     unsigned int nrOfSubunits = 0;
629
630     for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin();
631           it != m_subunits.end();
632           ++it )
633     {
634         AvDeviceSubunit* subunit = *it;
635         if ( subunitType == subunit->getSubunitType() ) {
636             nrOfSubunits++;
637         }
638     }
639
640     return nrOfSubunits;
641 }
642
643 AvPlugConnection*
644 AvDevice::getPlugConnection( AvPlug& srcPlug ) const
645 {
646     for ( AvPlugConnectionVector::const_iterator it
647               = m_plugConnections.begin();
648           it != m_plugConnections.end();
649           ++it )
650     {
651         AvPlugConnection* plugConnection = *it;
652         if ( &( plugConnection->getSrcPlug() ) == &srcPlug ) {
653             return plugConnection;
654         }
655     }
656
657     return 0;
658 }
659
660 AvPlug*
661 AvDevice::getPlugById( AvPlugVector& plugs,
662                        AvPlug::EAvPlugDirection plugDirection,
663                        int id )
664 {
665     for ( AvPlugVector::iterator it = plugs.begin();
666           it != plugs.end();
667           ++it )
668     {
669         AvPlug* plug = *it;
670         if ( ( id == plug->getPlugId() )
671              && ( plugDirection == plug->getPlugDirection() ) )
672         {
673             return plug;
674         }
675     }
676
677     return 0;
678 }
679
680 AvPlugVector
681 AvDevice::getPlugsByType( AvPlugVector& plugs,
682                           AvPlug::EAvPlugDirection plugDirection,
683                           AvPlug::EAvPlugType type)
684 {
685     AvPlugVector plugVector;
686     for ( AvPlugVector::iterator it = plugs.begin();
687           it != plugs.end();
688           ++it )
689     {
690         AvPlug* plug = *it;
691         if ( ( type == plug->getPlugType() )
692              && ( plugDirection == plug->getPlugDirection() ) )
693         {
694             plugVector.push_back( plug );
695         }
696     }
697
698     return plugVector;
699 }
700
701 AvPlug*
702 AvDevice::getSyncPlug( int maxPlugId, AvPlug::EAvPlugDirection )
703 {
704     return 0;
705 }
706
707 bool
708 AvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency )
709 {
710
711     AvPlug* plug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
712     if ( !plug ) {
713         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
714         return false;
715     }
716
717     if ( !setSamplingFrequencyPlug( *plug,
718                                     AvPlug::eAPD_Input,
719                                     samplingFrequency ) )
720     {
721         debugError( "setSampleRate: Setting sample rate failed\n" );
722         return false;
723     }
724
725     plug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output,  0 );
726     if ( !plug ) {
727         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
728         return false;
729     }
730
731     if ( !setSamplingFrequencyPlug( *plug,
732                                     AvPlug::eAPD_Output,
733                                     samplingFrequency ) )
734     {
735         debugError( "setSampleRate: Setting sample rate failed\n" );
736         return false;
737     }
738
739
740     debugOutput( DEBUG_LEVEL_VERBOSE,
741                  "setSampleRate: Set sample rate to %d\n",
742                  convertESamplingFrequency( samplingFrequency ) );
743     return true;
744 }
745
746 int
747 AvDevice::getSamplingFrequency( ) {
748     AvPlug* inputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
749     if ( !inputPlug ) {
750         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
751         return false;
752     }
753     AvPlug* outputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output, 0 );
754     if ( !outputPlug ) {
755         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
756         return false;
757     }
758
759     int samplerate_playback=inputPlug->getSampleRate();
760     int samplerate_capture=outputPlug->getSampleRate();
761
762     if (samplerate_playback != samplerate_capture) {
763         debugWarning("Samplerates for capture and playback differ!\n");
764     }
765     return samplerate_capture;
766 }
767
768
769 bool
770 AvDevice::setSamplingFrequencyPlug( AvPlug& plug,
771                                     AvPlug::EAvPlugDirection direction,
772                                     ESamplingFrequency samplingFrequency )
773 {
774
775     ExtendedStreamFormatCmd extStreamFormatCmd(
776         *m_p1394Service,
777         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList );
778     UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
779                                      plug.getPlugId() );
780
781     extStreamFormatCmd.setPlugAddress(
782         PlugAddress(
783             AvPlug::convertPlugDirection(direction ),
784             PlugAddress::ePAM_Unit,
785             unitPlugAddress ) );
786
787     extStreamFormatCmd.setNodeId( m_pConfigRom->getNodeId() );
788     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
789
790     int i = 0;
791     bool cmdSuccess = false;
792     bool correctFormatFound = false;
793
794     do {
795         extStreamFormatCmd.setIndexInStreamFormat( i );
796         extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
797         extStreamFormatCmd.setVerbose( m_verboseLevel );
798
799         cmdSuccess = extStreamFormatCmd.fire();
800
801         if ( cmdSuccess
802              && ( extStreamFormatCmd.getResponse() ==
803                   AVCCommand::eR_Implemented ) )
804         {
805             ESamplingFrequency foundFreq = eSF_DontCare;
806
807             FormatInformation* formatInfo =
808                 extStreamFormatCmd.getFormatInformation();
809             FormatInformationStreamsCompound* compoundStream
810                 = dynamic_cast< FormatInformationStreamsCompound* > (
811                     formatInfo->m_streams );
812             if ( compoundStream ) {
813                 foundFreq =
814                     static_cast< ESamplingFrequency >(
815                         compoundStream->m_samplingFrequency );
816             }
817
818             FormatInformationStreamsSync* syncStream
819                 = dynamic_cast< FormatInformationStreamsSync* > (
820                     formatInfo->m_streams );
821             if ( syncStream ) {
822                 foundFreq =
823                     static_cast< ESamplingFrequency >(
824                         syncStream->m_samplingFrequency );
825             }
826
827             if ( foundFreq == samplingFrequency )
828             {
829                 correctFormatFound = true;
830                 break;
831             }
832         }
833
834         ++i;
835     } while ( cmdSuccess
836               && ( extStreamFormatCmd.getResponse() ==
837                    ExtendedStreamFormatCmd::eR_Implemented ) );
838
839     if ( !cmdSuccess ) {
840         debugError( "setSampleRatePlug: Failed to retrieve format info\n" );
841         return false;
842     }
843
844     if ( !correctFormatFound ) {
845         debugError( "setSampleRatePlug: %s plug %d does not support "
846                     "sample rate %d\n",
847                     plug.getName(),
848                     plug.getPlugId(),
849                     convertESamplingFrequency( samplingFrequency ) );
850         return false;
851     }
852
853     extStreamFormatCmd.setSubFunction(
854         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand );
855     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Control );
856     extStreamFormatCmd.setVerbose( m_verboseLevel );
857
858     if ( !extStreamFormatCmd.fire() ) {
859         debugError( "setSampleRate: Could not set sample rate %d "
860                     "to %s plug %d\n",
861                     convertESamplingFrequency( samplingFrequency ),
862                     plug.getName(),
863                     plug.getPlugId() );
864         return false;
865     }
866
867     return true;
868 }
869
870 void
871 AvDevice::showDevice() const
872 {
873     m_pPlugManager->showPlugs();
874 }
875
876 void
877 AvDevice::showAvPlugs( AvPlugVector& plugs ) const
878 {
879     int i = 0;
880     for ( AvPlugVector::const_iterator it = plugs.begin();
881           it != plugs.end();
882           ++it, ++i )
883     {
884         AvPlug* plug = *it;
885         debugOutput( DEBUG_LEVEL_VERBOSE, "Plug %d\n", i );
886         plug->showPlug();
887     }
888 }
889
890 bool
891 AvDevice::checkSyncConnectionsAndAddToList( AvPlugVector& plhs,
892                                             AvPlugVector& prhs,
893                                             std::string syncDescription )
894 {
895     for ( AvPlugVector::iterator plIt = plhs.begin();
896           plIt != plhs.end();
897           ++plIt )
898     {
899         AvPlug* pl = *plIt;
900         for ( AvPlugVector::iterator prIt = prhs.begin();
901               prIt != prhs.end();
902               ++prIt )
903         {
904             AvPlug* pr = *prIt;
905             if ( pl->inquireConnnection( *pr ) ) {
906                 m_syncInfos.push_back( SyncInfo( *pl, *pr, syncDescription ) );
907                 debugOutput( DEBUG_LEVEL_NORMAL,
908                              "Sync connection '%s' -> '%s'\n",
909                              pl->getName(),
910                              pr->getName() );
911             }
912         }
913     }
914     return true;
915 }
916
917 bool AvDevice::setActiveSync(const SyncInfo& syncInfo)
918 {
919     return syncInfo.m_source->setConnection( *syncInfo.m_destination );
920 }
921
922 bool AvDevice::setId( unsigned int id)
923 {
924     // FIXME: decent ID system nescessary
925     m_id=id;
926         return true;
927 }
928
929 bool
930 AvDevice::prepare() {
931     ///////////
932     // get plugs
933
934     AvPlug* inputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
935     if ( !inputPlug ) {
936         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
937         return false;
938     }
939     AvPlug* outputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output, 0 );
940     if ( !outputPlug ) {
941         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
942         return false;
943     }
944
945     int samplerate=outputPlug->getSampleRate();
946     m_receiveProcessor=new FreebobStreaming::AmdtpReceiveStreamProcessor(
947                              m_p1394Service->getPort(),
948                              samplerate,
949                              outputPlug->getNrOfChannels());
950
951     if(!m_receiveProcessor->init()) {
952         debugFatal("Could not initialize receive processor!\n");
953         return false;
954     }
955
956     if (!addPlugToProcessor(*outputPlug,m_receiveProcessor,
957         FreebobStreaming::AmdtpAudioPort::E_Capture)) {
958         debugFatal("Could not add plug to processor!\n");
959         return false;
960     }
961
962     // do the transmit processor
963 //     if (m_snoopMode) {
964 //         // we are snooping, so these are receive too.
965 //         samplerate=inputPlug->getSampleRate();
966 //         m_receiveProcessor2=new FreebobStreaming::AmdtpReceiveStreamProcessor(
967 //                                   channel,
968 //                                   m_1394Service->getPort(),
969 //                                   samplerate,
970 //                                   inputPlug->getNrOfChannels());
971 //
972 //         if(!m_receiveProcessor2->init()) {
973 //             debugFatal("Could not initialize snooping receive processor!\n");
974 //             return false;
975 //         }
976 //         if (!addPlugToProcessor(*inputPlug,m_receiveProcessor2,
977 //             FreebobStreaming::AmdtpAudioPort::E_Capture)) {
978 //             debugFatal("Could not add plug to processor!\n");
979 //             return false;
980 //         }
981 //     } else {
982         // do the transmit processor
983         samplerate=inputPlug->getSampleRate();
984         m_transmitProcessor=new FreebobStreaming::AmdtpTransmitStreamProcessor(
985                                 m_p1394Service->getPort(),
986                                 samplerate,
987                                 inputPlug->getNrOfChannels());
988
989         if(!m_transmitProcessor->init()) {
990             debugFatal("Could not initialize transmit processor!\n");
991             return false;
992
993         }
994
995         if (!addPlugToProcessor(*inputPlug,m_transmitProcessor,
996             FreebobStreaming::AmdtpAudioPort::E_Playback)) {
997             debugFatal("Could not add plug to processor!\n");
998             return false;
999         }
1000 //     }
1001
1002     return true;
1003 }
1004
1005 bool
1006 AvDevice::addPlugToProcessor(
1007     AvPlug& plug,
1008     FreebobStreaming::StreamProcessor *processor,
1009     FreebobStreaming::AmdtpAudioPort::E_Direction direction) {
1010
1011     AvPlug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
1012     for ( AvPlug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
1013           it != clusterInfos.end();
1014           ++it )
1015     {
1016         const AvPlug::ClusterInfo* clusterInfo = &( *it );
1017
1018         AvPlug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
1019         for ( AvPlug::ChannelInfoVector::const_iterator it = channelInfos.begin();
1020               it != channelInfos.end();
1021               ++it )
1022         {
1023             const AvPlug::ChannelInfo* channelInfo = &( *it );
1024             std::ostringstream portname;
1025
1026             portname << "dev" << m_id << "_" << channelInfo->m_name;
1027
1028             FreebobStreaming::Port *p=NULL;
1029             switch(clusterInfo->m_portType) {
1030             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
1031             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
1032             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
1033             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
1034             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
1035                 p=new FreebobStreaming::AmdtpAudioPort(
1036                         portname.str(),
1037                         direction,
1038                         // \todo: streaming backend expects indexing starting from 0
1039                         // but bebob reports it starting from 1. Decide where
1040                         // and how to handle this (pp: here)
1041                         channelInfo->m_streamPosition - 1,
1042                         channelInfo->m_location,
1043                         FreebobStreaming::AmdtpPortInfo::E_MBLA,
1044                         clusterInfo->m_portType
1045                 );
1046                 break;
1047
1048             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
1049                 p=new FreebobStreaming::AmdtpMidiPort(
1050                         portname.str(),
1051                         direction,
1052                         // \todo: streaming backend expects indexing starting from 0
1053                         // but bebob reports it starting from 1. Decide where
1054                         // and how to handle this (pp: here)
1055                         channelInfo->m_streamPosition - 1,
1056                         channelInfo->m_location,
1057                         FreebobStreaming::AmdtpPortInfo::E_Midi,
1058                         clusterInfo->m_portType
1059                 );
1060
1061                 break;
1062             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
1063             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
1064             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
1065             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
1066             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
1067             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
1068             default:
1069             // unsupported
1070                 break;
1071             }
1072
1073             if (!p) {
1074                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
1075             } else {
1076
1077                 if (!processor->addPort(p)) {
1078                     debugWarning("Could not register port with stream processor\n");
1079                     return false;
1080                 }
1081             }
1082          }
1083     }
1084     return true;
1085 }
1086
1087 #ifdef TEST_XMIT_ONLY
1088 int
1089 AvDevice::getStreamCount() {
1090 //     return 2; // one receive, one transmit
1091     return 1; // one receive, one transmit
1092 }
1093
1094 FreebobStreaming::StreamProcessor *
1095 AvDevice::getStreamProcessorByIndex(int i) {
1096     switch (i) {
1097     case 0:
1098 //         return m_receiveProcessor;
1099 //     case 1:
1100 //         if (m_snoopMode) {
1101 //             return m_receiveProcessor2;
1102 //         } else {
1103             return m_transmitProcessor;
1104 //         }
1105     default:
1106         return NULL;
1107     }
1108     return 0;
1109 }
1110
1111 // FIXME: error checking
1112 int
1113 AvDevice::startStreamByIndex(int i) {
1114     int iso_channel=0;
1115     int plug=0;
1116     int hostplug=-1;
1117
1118 //     if (m_snoopMode) {
1119 //
1120 //         switch (i) {
1121 //         case 0:
1122 //             // snooping doesn't use CMP, but obtains the info of the channel
1123 //             // from the target plug
1124 //
1125 //             // TODO: get isochannel from plug
1126 //
1127 //             // set the channel obtained by the connection management
1128 //             m_receiveProcessor->setChannel(iso_channel);
1129 //             break;
1130 //         case 1:
1131 //             // snooping doesn't use CMP, but obtains the info of the channel
1132 //             // from the target plug
1133 //
1134 //             // TODO: get isochannel from plug
1135 //
1136 //             // set the channel obtained by the connection management
1137 //             m_receiveProcessor2->setChannel(iso_channel);
1138 //
1139 //             break;
1140 //         default:
1141 //             return 0;
1142 //         }
1143 //     } else {
1144
1145         switch (i) {
1146         case 0:
1147 //             // do connection management: make connection
1148 //             iso_channel = iec61883_cmp_connect(
1149 //                 m_p1394Service->getHandle(),
1150 //                 m_pConfigRom->getNodeId() | 0xffc0,
1151 //                 &plug,
1152 //                 raw1394_get_local_id (m_p1394Service->getHandle()),
1153 //                 &hostplug,
1154 //                 &m_receiveProcessorBandwidth);
1155 //
1156 //             // set the channel obtained by the connection management
1157 //             m_receiveProcessor->setChannel(iso_channel);
1158 //             break;
1159 //         case 1:
1160             // do connection management: make connection
1161             iso_channel = iec61883_cmp_connect(
1162                 m_p1394Service->getHandle(),
1163                 raw1394_get_local_id (m_p1394Service->getHandle()),
1164                 &hostplug,
1165                 m_pConfigRom->getNodeId() | 0xffc0,
1166                 &plug,
1167                 &m_transmitProcessorBandwidth);
1168
1169             // set the channel obtained by the connection management
1170             m_transmitProcessor->setChannel(iso_channel);
1171             break;
1172         default:
1173             return -1;
1174         }
1175 //     }
1176
1177     if (iso_channel < 0) return -1;
1178    
1179     return 0;
1180
1181 }
1182
1183 // FIXME: error checking
1184 int
1185 AvDevice::stopStreamByIndex(int i) {
1186     // do connection management: break connection
1187
1188     int plug=0;
1189     int hostplug=-1;
1190 //     if (m_snoopMode) {
1191 //         switch (i) {
1192 //         case 0:
1193 //             // do connection management: break connection
1194 //
1195 //             break;
1196 //         case 1:
1197 //             // do connection management: break connection
1198 //
1199 //             break;
1200 //         default:
1201 //             return 0;
1202 //         }
1203 //     } else {
1204         switch (i) {
1205         case 0:
1206 //             // do connection management: break connection
1207 //             iec61883_cmp_disconnect(
1208 //                 m_p1394Service->getHandle(),
1209 //                 m_pConfigRom->getNodeId() | 0xffc0,
1210 //                 plug,
1211 //                 raw1394_get_local_id (m_p1394Service->getHandle()),
1212 //                 hostplug,
1213 //                 m_receiveProcessor->getChannel(),
1214 //                 m_receiveProcessorBandwidth);
1215 //
1216 //             break;
1217 //         case 1:
1218             // do connection management: break connection
1219             iec61883_cmp_disconnect(
1220                 m_p1394Service->getHandle(),
1221                 raw1394_get_local_id (m_p1394Service->getHandle()),
1222                 hostplug,
1223                 m_pConfigRom->getNodeId() | 0xffc0,
1224                 plug,
1225                 m_transmitProcessor->getChannel(),
1226                 m_transmitProcessorBandwidth);
1227
1228             break;
1229         default:
1230             return 0;
1231         }
1232 //     }
1233
1234     return 0;
1235 }
1236 #else
1237 int
1238 AvDevice::getStreamCount() {
1239     return 2; // one receive, one transmit
1240 }
1241
1242 FreebobStreaming::StreamProcessor *
1243 AvDevice::getStreamProcessorByIndex(int i) {
1244     switch (i) {
1245     case 0:
1246         return m_receiveProcessor;
1247     case 1:
1248 //         if (m_snoopMode) {
1249 //             return m_receiveProcessor2;
1250 //         } else {
1251             return m_transmitProcessor;
1252 //         }
1253     default:
1254         return NULL;
1255     }
1256     return 0;
1257 }
1258
1259 // FIXME: error checking
1260 int
1261 AvDevice::startStreamByIndex(int i) {
1262     int iso_channel=0;
1263     int plug=0;
1264     int hostplug=-1;
1265
1266 //     if (m_snoopMode) {
1267 //
1268 //         switch (i) {
1269 //         case 0:
1270 //             // snooping doesn't use CMP, but obtains the info of the channel
1271 //             // from the target plug
1272 //
1273 //             // TODO: get isochannel from plug
1274 //
1275 //             // set the channel obtained by the connection management
1276 //             m_receiveProcessor->setChannel(iso_channel);
1277 //             break;
1278 //         case 1:
1279 //             // snooping doesn't use CMP, but obtains the info of the channel
1280 //             // from the target plug
1281 //
1282 //             // TODO: get isochannel from plug
1283 //
1284 //             // set the channel obtained by the connection management
1285 //             m_receiveProcessor2->setChannel(iso_channel);
1286 //
1287 //             break;
1288 //         default:
1289 //             return 0;
1290 //         }
1291 //     } else {
1292
1293         switch (i) {
1294         case 0:
1295             // do connection management: make connection
1296             iso_channel = iec61883_cmp_connect(
1297                 m_p1394Service->getHandle(),
1298                 m_pConfigRom->getNodeId() | 0xffc0,
1299                 &plug,
1300                 raw1394_get_local_id (m_p1394Service->getHandle()),
1301                 &hostplug,
1302                 &m_receiveProcessorBandwidth);
1303
1304             // set the channel obtained by the connection management
1305             m_receiveProcessor->setChannel(iso_channel);
1306             break;
1307         case 1:
1308             // do connection management: make connection
1309             iso_channel = iec61883_cmp_connect(
1310                 m_p1394Service->getHandle(),
1311                 raw1394_get_local_id (m_p1394Service->getHandle()),
1312                 &hostplug,
1313                 m_pConfigRom->getNodeId() | 0xffc0,
1314                 &plug,
1315                 &m_transmitProcessorBandwidth);
1316
1317             // set the channel obtained by the connection management
1318             m_transmitProcessor->setChannel(iso_channel);
1319             break;
1320         default:
1321             return -1;
1322         }
1323 //     }
1324
1325     if (iso_channel < 0) return -1;
1326    
1327     return 0;
1328
1329 }
1330
1331 // FIXME: error checking
1332 int
1333 AvDevice::stopStreamByIndex(int i) {
1334     // do connection management: break connection
1335
1336     int plug=0;
1337     int hostplug=-1;
1338 //     if (m_snoopMode) {
1339 //         switch (i) {
1340 //         case 0:
1341 //             // do connection management: break connection
1342 //
1343 //             break;
1344 //         case 1:
1345 //             // do connection management: break connection
1346 //
1347 //             break;
1348 //         default:
1349 //             return 0;
1350 //         }
1351 //     } else {
1352         switch (i) {
1353         case 0:
1354             // do connection management: break connection
1355             iec61883_cmp_disconnect(
1356                 m_p1394Service->getHandle(),
1357                 m_pConfigRom->getNodeId() | 0xffc0,
1358                 plug,
1359                 raw1394_get_local_id (m_p1394Service->getHandle()),
1360                 hostplug,
1361                 m_receiveProcessor->getChannel(),
1362                 m_receiveProcessorBandwidth);
1363
1364             break;
1365         case 1:
1366             // do connection management: break connection
1367             iec61883_cmp_disconnect(
1368                 m_p1394Service->getHandle(),
1369                 raw1394_get_local_id (m_p1394Service->getHandle()),
1370                 hostplug,
1371                 m_pConfigRom->getNodeId() | 0xffc0,
1372                 plug,
1373                 m_transmitProcessor->getChannel(),
1374                 m_transmitProcessorBandwidth);
1375
1376             break;
1377         default:
1378             return 0;
1379         }
1380 //     }
1381
1382     return 0;
1383 }
1384 #endif
1385
1386 template <typename T> bool serializeVector( Glib::ustring path,
1387                                             Util::IOSerialize& ser,
1388                                             const T& vec )
1389 {
1390     bool result = true; // if vec.size() == 0
1391     int i = 0;
1392     for ( typename T::const_iterator it = vec.begin(); it != vec.end(); ++it ) {
1393         std::ostringstream strstrm;
1394         strstrm << path << i;
1395         result &= ( *it )->serialize( strstrm.str() + "/", ser );
1396         i++;
1397     }
1398     return result;
1399 }
1400
1401 template <typename T, typename VT> bool deserializeVector( Glib::ustring path,
1402                                                            Util::IODeserialize& deser,
1403                                                            AvDevice& avDevice,
1404                                                            VT& vec )
1405 {
1406     int i = 0;
1407     bool bFinished = false;
1408     do {
1409         std::ostringstream strstrm;
1410         strstrm << path << i << "/";
1411         T* ptr = T::deserialize( strstrm.str(),
1412                                  deser,
1413                                  avDevice );
1414         if ( ptr ) {
1415             vec.push_back( ptr );
1416             i++;
1417         } else {
1418             bFinished = true;
1419         }
1420     } while ( !bFinished );
1421
1422     return true;
1423 }
1424
1425 bool
1426 AvDevice::serializeSyncInfoVector( Glib::ustring basePath,
1427                                    Util::IOSerialize& ser,
1428                                    const SyncInfoVector& vec )
1429 {
1430     bool result = true;
1431     int i = 0;
1432
1433     for ( SyncInfoVector::const_iterator it = vec.begin();
1434           it != vec.end();
1435           ++it )
1436     {
1437         const SyncInfo& info = *it;
1438
1439         std::ostringstream strstrm;
1440         strstrm << basePath << i << "/";
1441
1442         result &= ser.write( strstrm.str() + "m_source", info.m_source->getGlobalId() );
1443         result &= ser.write( strstrm.str() + "m_destination", info.m_destination->getGlobalId() );
1444         result &= ser.write( strstrm.str() + "m_description", Glib::ustring( info.m_description ) );
1445
1446         i++;
1447     }
1448
1449     return result;
1450 }
1451
1452 bool
1453 AvDevice::deserializeSyncInfoVector( Glib::ustring basePath,
1454                                      Util::IODeserialize& deser,
1455                                      AvDevice& avDevice,
1456                                      SyncInfoVector& vec )
1457 {
1458     int i = 0;
1459     bool bFinished = false;
1460     do {
1461         bool result;
1462         std::ostringstream strstrm;
1463         strstrm << basePath << i << "/";
1464
1465         plug_id_t sourceId;
1466         plug_id_t destinationId;
1467         Glib::ustring description;
1468
1469         result  = deser.read( strstrm.str() + "m_source", sourceId );
1470         result &= deser.read( strstrm.str() + "m_destination", destinationId );
1471         result &= deser.read( strstrm.str() + "m_description", description );
1472
1473         if ( result ) {
1474             SyncInfo syncInfo;
1475             syncInfo.m_source = avDevice.getPlugManager().getPlug( sourceId );
1476             syncInfo.m_destination = avDevice.getPlugManager().getPlug( destinationId );
1477             syncInfo.m_description = description;
1478
1479             vec.push_back( syncInfo );
1480             i++;
1481         } else {
1482             bFinished = true;
1483         }
1484     } while ( !bFinished );
1485
1486     return true;
1487 }
1488
1489 static bool
1490 deserializeAvPlugUpdateConnections( Glib::ustring path,
1491                                     Util::IODeserialize& deser,
1492                                     AvPlugVector& vec )
1493 {
1494     bool result = true;
1495     for ( AvPlugVector::iterator it = vec.begin();
1496           it != vec.end();
1497           ++it )
1498     {
1499         AvPlug* pPlug = *it;
1500         result &= pPlug->deserializeUpdate( path, deser );
1501     }
1502     return result;
1503 }
1504
1505 bool
1506 AvDevice::serialize( Glib::ustring basePath,
1507                      Util::IOSerialize& ser ) const
1508 {
1509     bool result;
1510     result  = m_pConfigRom->serialize( basePath + "m_pConfigRom/", ser );
1511     result &= ser.write( basePath + "m_verboseLevel", m_verboseLevel );
1512     result &= m_pPlugManager->serialize( basePath + "AvPlug", ser ); // serialize all av plugs
1513     result &= serializeVector( basePath + "PlugConnection", ser, m_plugConnections );
1514     result &= serializeVector( basePath + "Subunit", ser, m_subunits );
1515     result &= serializeSyncInfoVector( basePath + "SyncInfo", ser, m_syncInfos );
1516
1517     int i = 0;
1518     for ( SyncInfoVector::const_iterator it = m_syncInfos.begin();
1519           it != m_syncInfos.end();
1520           ++it )
1521     {
1522         const SyncInfo& info = *it;
1523         if ( m_activeSyncInfo == &info ) {
1524             result &= ser.write( basePath + "m_activeSyncInfo",  i );
1525             break;
1526         }
1527         i++;
1528     }
1529
1530     result &= ser.write( basePath + "m_id", m_id );
1531
1532     return result;
1533 }
1534
1535 AvDevice*
1536 AvDevice::deserialize( Glib::ustring basePath,
1537                        Util::IODeserialize& deser,
1538                        Ieee1394Service& ieee1394Service )
1539 {
1540     AvDevice* pDev = new AvDevice;
1541
1542     if ( pDev ) {
1543         pDev->m_pConfigRom = std::auto_ptr<ConfigRom> (
1544             ConfigRom::deserialize( basePath + "m_pConfigRom/", deser, ieee1394Service )
1545             );
1546         if ( !pDev->m_pConfigRom.get() ) {
1547             delete pDev;
1548             return 0;
1549         }
1550
1551         pDev->m_p1394Service = &ieee1394Service;
1552         bool result;
1553         result  = deser.read( basePath + "m_verboseLevel", pDev->m_verboseLevel );
1554         pDev->m_pPlugManager = AvPlugManager::deserialize( basePath + "AvPlug", deser, *pDev );
1555         if ( !pDev->m_pPlugManager ) {
1556             delete pDev;
1557             return 0;
1558         }
1559         result &= deserializeAvPlugUpdateConnections( basePath + "AvPlug", deser, pDev->m_pcrPlugs );
1560         result &= deserializeAvPlugUpdateConnections( basePath + "AvPlug", deser, pDev->m_externalPlugs );
1561         result &= deserializeVector<AvPlugConnection>( basePath + "PlugConnnection", deser, *pDev, pDev->m_plugConnections );
1562         result &= deserializeVector<AvDeviceSubunit>( basePath + "Subunit",  deser, *pDev, pDev->m_subunits );
1563         result &= deserializeSyncInfoVector( basePath + "SyncInfo", deser, *pDev, pDev->m_syncInfos );
1564
1565         unsigned int i;
1566         result &= deser.read( basePath + "m_activeSyncInfo", i );
1567
1568         if ( result ) {
1569             if ( i < pDev->m_syncInfos.size() ) {
1570                 pDev->m_activeSyncInfo = &pDev->m_syncInfos[i];
1571             }
1572         }
1573
1574         result &= deser.read( basePath + "m_id", pDev->m_id );
1575     }
1576
1577     return pDev;
1578 }
1579
1580 } // end of namespace
Note: See TracBrowser for help on using the browser.