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

Revision 404, 49.3 kB (checked in by pieterpalmers, 16 years ago)

- introduce support framework for DICE and Metric Halo
- change probe/discovery code to make adding devices easier
- made conditional compilation effectively work.

./configure now has the following switches:

--enable-bebob build BeBoB support (default=yes)
--enable-motu build Motu support (default=no)
--enable-dice build DICE support (default=no)
--enable-metric-halo build Metric Halo support (note: completely useless)

(default=no)

--enable-rme build RME support (note: completely useless)

(default=no)

--enable-bounce build Bounce device support (default=no)
--enable-all-devices build support for all supported devices (default=no)

these now turn on/off compilation effectively.

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