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

Revision 415, 43.3 kB (checked in by pieterpalmers, 16 years ago)

ieee1394service:
- implemented 64bit compare-swap-lock operation (needed for DICE)
- small name change of (un)registerARMhandler to (un)registerARMHandler

iavdevice.h:
- made the stream start/stop functions return bool instead of int
- updated function documentation for consistency and to reflect changes

BeBoB avdevice:
- replaced the 2 fixed streamprocessor pointers with a 2 vectors of streamprocessors
- implemented the 'snoop mode' (cannot be activated yet)

libstreaming:
- removed unused 'type' attribute from AmdtpPortInfo? & children

mh_avdevice, motu_avdevice, rme_avdevice:
- replaced m_1394service with m_p1394service for consistence

maudio_avdevice.cpp:
- removed unused code

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