root/branches/libffado-scons_porting_work/src/bebob/bebob_avdevice.cpp

Revision 547, 53.6 kB (checked in by arnonym, 15 years ago)

Port ppalmers fixes for spdif to this scons branch. This will affect nothing in the end, as the transition from scons-branch to trunk will involve only the build-system and (almost) no sources...

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