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

Revision 408, 44.0 kB (checked in by pieterpalmers, 16 years ago)

- Implemented a mechanism to allocate and deallocate iso channels in a generic manner, being by cmp or otherwise.

- cleaned all commented out code from RME, as it is getting increasingly outdated.

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