root/trunk/libffado/src/bebob/bebob_avdevice.cpp

Revision 476, 47.4 kB (checked in by ppalmers, 15 years ago)

Add device ID for M-Audio Solo

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