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

Revision 424, 47.4 kB (checked in by pieterpalmers, 16 years ago)

- The library can now be started in 'slave mode', creating a BounceSlaveDevice?.

On a discovering node, this slave device is discovered as a BounceDevice?.
Streaming does not work yet, something wrong with the timestamps.

- Implemented the 'snoop mode', that allows a client to 'snoop' the streams

between another host and a device. It is only implemented for BeBoB devices.
The channel numbers and stream configuration are automatically detected.
Note that it currently relies on a rather hackish support for reading the
{i,o}PCR plugs by using private functions of libiec61883

- changed jack backend to support these two new features

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