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

Revision 419, 44.0 kB (checked in by pieterpalmers, 17 years ago)

namespace simplification

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