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

Revision 451, 47.3 kB (checked in by ppalmers, 17 years ago)

- First attempt at a OSC controlled mixer. The level of

abstraction is very low, meaning that you have to know
how the function blocks work. It however allows control
applications to be written and to experiment with them.

- This version only does Selector function blocks.

The following message switches the phase88 input to the

  • front (or is is back?)
    /devicemanager/dev0/GenericMixer set selector 10 0
  • back (or is it front?)
    /devicemanager/dev0/GenericMixer set selector 10 1

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