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

Revision 330, 26.3 kB (checked in by wagi, 17 years ago)

Presonous FirePOD ids added

Line 
1 /* bebob_avdevice.cpp
2  * Copyright (C) 2005,06 by Daniel Wagner
3  *
4  * This file is part of FreeBoB.
5  *
6  * FreeBoB is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * FreeBoB is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FreeBoB; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA.
19  */
20
21 #include "bebob/bebob_avdevice.h"
22 #include "bebob/bebob_avdevice_subunit.h"
23 #include "configrom.h"
24
25 #include "libfreebobavc/avc_plug_info.h"
26 #include "libfreebobavc/avc_extended_plug_info.h"
27 #include "libfreebobavc/avc_subunit_info.h"
28 #include "libfreebobavc/avc_extended_stream_format.h"
29 #include "libfreebobavc/serialize.h"
30 #include "libfreebobavc/ieee1394service.h"
31 #include "libfreebobavc/avc_definitions.h"
32
33 #include "debugmodule/debugmodule.h"
34
35 #include <iostream>
36
37 namespace BeBoB {
38
39 IMPL_DEBUG_MODULE( AvDevice, AvDevice, DEBUG_LEVEL_NORMAL );
40
41 AvDevice::AvDevice( std::auto_ptr< ConfigRom >( configRom ),
42                     Ieee1394Service& ieee1394service,
43                     int nodeId,
44                     int verboseLevel )
45     :  m_configRom( configRom )
46     , m_1394Service( &ieee1394service )
47     , m_nodeId( nodeId )
48     , m_verboseLevel( verboseLevel )
49     , m_plugManager( verboseLevel )
50     , m_activeSyncInfo( 0 )
51 {
52     if ( m_verboseLevel ) {
53         setDebugLevel( DEBUG_LEVEL_VERBOSE );
54     }
55     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::AvDevice (NodeID %d)\n",
56                  nodeId );
57 }
58
59 AvDevice::~AvDevice()
60 {
61     for ( AvDeviceSubunitVector::iterator it = m_subunits.begin();
62           it != m_subunits.end();
63           ++it )
64     {
65         delete *it;
66     }
67     for ( AvPlugConnectionVector::iterator it = m_plugConnections.begin();
68           it != m_plugConnections.end();
69           ++it )
70     {
71         delete *it;
72     }
73     for ( AvPlugVector::iterator it = m_pcrPlugs.begin();
74           it != m_pcrPlugs.end();
75           ++it )
76     {
77         delete *it;
78     }
79     for ( AvPlugVector::iterator it = m_externalPlugs.begin();
80           it != m_externalPlugs.end();
81           ++it )
82     {
83         delete *it;
84     }
85 }
86
87 ConfigRom&
88 AvDevice::getConfigRom() const
89 {
90     return *m_configRom;
91 }
92
93 struct VendorModelEntry {
94     unsigned int vendor_id;
95     unsigned int model_id;
96 };
97
98 static VendorModelEntry supportedDeviceList[] =
99 {
100     {0x00000f, 0x00010065},  // Mackie, Onyx Firewire
101
102     {0x0003db, 0x00010048},  // Apogee Electronics, Rosetta 200
103
104     {0x0007f5, 0x00010048},  // BridgeCo, RD Audio1
105
106     {0x000a92, 0x00010066},  // Presonous FirePOD
107
108     {0x000aac, 0x00000004},  // TerraTec Electronic GmbH, Phase X24 FW (model version 4)
109     {0x000aac, 0x00000007},  // TerraTec Electronic GmbH, Phase X24 FW (model version 7)
110
111     {0x000f1b, 0x00010064},  // ESI, Quatafire 610
112
113     {0x0040ab, 0x00010048},  // EDIROL, FA-101
114     {0x0040ab, 0x00010049},  // EDIROL, FA-66
115
116     {0x00130e, 0x00000003},  // Focusrite, Pro26IO (Saffire 26)
117 };
118
119 bool
120 AvDevice::probe( ConfigRom& configRom )
121 {
122     unsigned int vendorId = configRom.getNodeVendorId();
123     unsigned int modelId = configRom.getModelId();
124
125     for ( unsigned int i = 0;
126           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
127           ++i )
128     {
129         if ( ( supportedDeviceList[i].vendor_id == vendorId )
130              && ( supportedDeviceList[i].model_id == modelId ) )
131         {
132             return true;
133         }
134     }
135
136     return false;
137 }
138
139 bool
140 AvDevice::discover()
141 {
142     if ( !enumerateSubUnits() ) {
143         debugError( "Could not enumarate sub units\n" );
144         return false;
145     }
146
147     if ( !discoverPlugs() ) {
148         debugError( "Detecting plugs failed\n" );
149         return false;
150     }
151
152     if ( !discoverPlugConnections() ) {
153         debugError( "Detecting plug connections failed\n" );
154         return false;
155     }
156
157     if ( !discoverSubUnitsPlugConnections() ) {
158         debugError( "Detecting plug connnection failed\n" );
159         return false;
160     }
161
162     if ( !discoverSyncModes() ) {
163         debugError( "Detecting sync modes failed\n" );
164         return false;
165     }
166
167     return true;
168 }
169
170 bool
171 AvDevice::discoverPlugs()
172 {
173     //////////////////////////////////////////////
174     // Get number of available isochronous input
175     // and output plugs of unit
176
177     PlugInfoCmd plugInfoCmd( m_1394Service );
178     plugInfoCmd.setNodeId( m_nodeId );
179     plugInfoCmd.setCommandType( AVCCommand::eCT_Status );
180     plugInfoCmd.setVerbose( m_verboseLevel );
181
182     if ( !plugInfoCmd.fire() ) {
183         debugError( "plug info command failed\n" );
184         return false;
185     }
186
187     debugOutput( DEBUG_LEVEL_NORMAL, "number of iso input plugs = %d\n",
188                  plugInfoCmd.m_serialBusIsochronousInputPlugs );
189     debugOutput( DEBUG_LEVEL_NORMAL, "number of iso output plugs = %d\n",
190                  plugInfoCmd.m_serialBusIsochronousOutputPlugs );
191     debugOutput( DEBUG_LEVEL_NORMAL, "number of external input plugs = %d\n",
192                  plugInfoCmd.m_externalInputPlugs );
193     debugOutput( DEBUG_LEVEL_NORMAL, "number of external output plugs = %d\n",
194                  plugInfoCmd.m_externalOutputPlugs );
195
196     if ( !discoverPlugsPCR( AvPlug::eAPD_Input,
197                             plugInfoCmd.m_serialBusIsochronousInputPlugs ) )
198     {
199         debugError( "pcr input plug discovering failed\n" );
200         return false;
201     }
202
203     if ( !discoverPlugsPCR( AvPlug::eAPD_Output,
204                             plugInfoCmd.m_serialBusIsochronousOutputPlugs ) )
205     {
206         debugError( "pcr output plug discovering failed\n" );
207         return false;
208     }
209
210     if ( !discoverPlugsExternal( AvPlug::eAPD_Input,
211                                  plugInfoCmd.m_externalInputPlugs ) )
212     {
213         debugError( "external input plug discovering failed\n" );
214         return false;
215     }
216
217     if ( !discoverPlugsExternal( AvPlug::eAPD_Output,
218                                  plugInfoCmd.m_externalOutputPlugs ) )
219     {
220         debugError( "external output plug discovering failed\n" );
221         return false;
222     }
223
224     return true;
225 }
226
227 bool
228 AvDevice::discoverPlugsPCR( AvPlug::EAvPlugDirection plugDirection,
229                             plug_id_t plugMaxId )
230 {
231     for ( int plugId = 0;
232           plugId < plugMaxId;
233           ++plugId )
234     {
235         AvPlug* plug  = new AvPlug( *m_1394Service,
236                                     m_nodeId,
237                                     m_plugManager,
238                                     AVCCommand::eST_Unit,
239                                     0xff,
240                                     0xff,
241                                     0xff,
242                                     AvPlug::eAPA_PCR,
243                                     plugDirection,
244                                     plugId,
245                                     m_verboseLevel );
246         if ( !plug || !plug->discover() ) {
247             debugError( "plug discovering failed\n" );
248             delete plug;
249             return false;
250         }
251
252         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
253                      plug->getName() );
254         m_pcrPlugs.push_back( plug );
255     }
256
257     return true;
258 }
259
260 bool
261 AvDevice::discoverPlugsExternal( AvPlug::EAvPlugDirection plugDirection,
262                                  plug_id_t plugMaxId )
263 {
264     for ( int plugId = 0;
265           plugId < plugMaxId;
266           ++plugId )
267     {
268         AvPlug* plug  = new AvPlug( *m_1394Service,
269                                     m_nodeId,
270                                     m_plugManager,
271                                     AVCCommand::eST_Unit,
272                                     0xff,
273                                     0xff,
274                                     0xff,
275                                     AvPlug::eAPA_ExternalPlug,
276                                     plugDirection,
277                                     plugId,
278                                     m_verboseLevel );
279         if ( !plug || !plug->discover() ) {
280             debugError( "plug discovering failed\n" );
281             return false;
282         }
283
284         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
285                      plug->getName() );
286         m_externalPlugs.push_back( plug );
287     }
288
289     return true;
290 }
291
292 bool
293 AvDevice::discoverPlugConnections()
294 {
295     for ( AvPlugVector::iterator it = m_pcrPlugs.begin();
296           it != m_pcrPlugs.end();
297           ++it )
298     {
299         AvPlug* plug = *it;
300         if ( !plug->discoverConnections() ) {
301             debugError( "Could not discover plug connections\n" );
302             return false;
303         }
304     }
305     for ( AvPlugVector::iterator it = m_externalPlugs.begin();
306           it != m_externalPlugs.end();
307           ++it )
308     {
309         AvPlug* plug = *it;
310         if ( !plug->discoverConnections() ) {
311             debugError( "Could not discover plug connections\n" );
312             return false;
313         }
314     }
315
316     return true;
317 }
318
319 bool
320 AvDevice::discoverSubUnitsPlugConnections()
321 {
322     for ( AvDeviceSubunitVector::iterator it = m_subunits.begin();
323           it != m_subunits.end();
324           ++it )
325     {
326         AvDeviceSubunit* subunit = *it;
327         if ( !subunit->discoverConnections() ) {
328             debugError( "Subunit '%s'  plug connections failed\n",
329                         subunit->getName() );
330             return false;
331         }
332     }
333     return true;
334 }
335
336 bool
337 AvDevice::discoverSyncModes()
338 {
339     // Following possible sync plugs exists:
340     // - Music subunit sync output plug = internal sync (CSP)
341     // - Unit input plug 0 = SYT match
342     // - Unit input plut 1 = Sync stream
343     //
344     // If last sync mode is reported it is mostelikely not
345     // implemented *sic*
346     //
347     // Following sync sources are device specific:
348     // - All unit external input plugs which have a
349     //   sync information (WS, SPDIF, ...)
350
351     // First we have to find the sync input and output plug
352     // in the music subunit.
353
354     // Note PCR input means 1394bus-to-device where as
355     // MSU input means subunit-to-device
356
357     AvPlugVector syncPCRInputPlugs = getPlugsByType( m_pcrPlugs,
358                                                      AvPlug::eAPD_Input,
359                                                      AvPlug::eAPT_Sync );
360     if ( !syncPCRInputPlugs.size() ) {
361         debugWarning( "No PCR sync input plug found\n" );
362     }
363
364     AvPlugVector syncPCROutputPlugs = getPlugsByType( m_pcrPlugs,
365                                                       AvPlug::eAPD_Output,
366                                                       AvPlug::eAPT_Sync );
367     if ( !syncPCROutputPlugs.size() ) {
368         debugWarning( "No PCR sync output plug found\n" );
369     }
370
371     AvPlugVector isoPCRInputPlugs = getPlugsByType( m_pcrPlugs,
372                                                     AvPlug::eAPD_Input,
373                                                     AvPlug::eAPT_IsoStream );
374     if ( !isoPCRInputPlugs.size() ) {
375         debugWarning( "No PCR iso input plug found\n" );
376
377     }
378
379     AvPlugVector isoPCROutputPlugs = getPlugsByType( m_pcrPlugs,
380                                                     AvPlug::eAPD_Output,
381                                                     AvPlug::eAPT_IsoStream );
382     if ( !isoPCROutputPlugs.size() ) {
383         debugWarning( "No PCR iso output plug found\n" );
384
385     }
386
387     AvPlugVector digitalPCRInputPlugs = getPlugsByType( m_externalPlugs,
388                                                     AvPlug::eAPD_Input,
389                                                     AvPlug::eAPT_Digital );
390
391     AvPlugVector syncMSUInputPlugs = m_plugManager.getPlugsByType(
392         AVCCommand::eST_Music,
393         0,
394         0xff,
395         0xff,
396         AvPlug::eAPA_SubunitPlug,
397         AvPlug::eAPD_Input,
398         AvPlug::eAPT_Sync );
399     if ( !syncMSUInputPlugs.size() ) {
400         debugWarning( "No sync input plug for MSU subunit found\n" );
401     }
402
403     AvPlugVector syncMSUOutputPlugs = m_plugManager.getPlugsByType(
404         AVCCommand::eST_Music,
405         0,
406         0xff,
407         0xff,
408         AvPlug::eAPA_SubunitPlug,
409         AvPlug::eAPD_Output,
410         AvPlug::eAPT_Sync );
411     if ( !syncMSUOutputPlugs.size() ) {
412         debugWarning( "No sync output plug for MSU subunit found\n" );
413     }
414
415     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Input Plugs:\n" );
416     showAvPlugs( syncPCRInputPlugs );
417     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Output Plugs:\n" );
418     showAvPlugs( syncPCROutputPlugs );
419     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Input Plugs:\n" );
420     showAvPlugs( isoPCRInputPlugs );
421     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Output Plugs:\n" );
422     showAvPlugs( isoPCROutputPlugs );
423     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR digital Input Plugs:\n" );
424     showAvPlugs( digitalPCRInputPlugs );
425     debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Input Plugs:\n" );
426     showAvPlugs( syncMSUInputPlugs );
427     debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Output Plugs:\n" );
428     showAvPlugs( syncMSUOutputPlugs );
429
430     // Check all possible PCR input to MSU input connections
431     // -> sync stream input
432     checkSyncConnectionsAndAddToList( syncPCRInputPlugs,
433                                       syncMSUInputPlugs,
434                                       "Sync Stream Input" );
435
436     // Check all possible MSU output to PCR output connections
437     // -> sync stream output
438     checkSyncConnectionsAndAddToList( syncMSUOutputPlugs,
439                                       syncPCROutputPlugs,
440                                       "Sync Stream Output" );
441
442     // Check all PCR iso input to MSU input connections
443     // -> SYT match
444     checkSyncConnectionsAndAddToList( isoPCRInputPlugs,
445                                       syncMSUInputPlugs,
446                                       "Syt Match" );
447
448     // Check all MSU sync output to MSU input connections
449     // -> CSP
450     checkSyncConnectionsAndAddToList( syncMSUOutputPlugs,
451                                       syncMSUInputPlugs,
452                                       "Internal (CSP)" );
453
454     // Check all external PCR digital input to MSU input connections
455     // -> SPDIF/ADAT sync
456     checkSyncConnectionsAndAddToList( digitalPCRInputPlugs,
457                                       syncMSUInputPlugs,
458                                       "Digital Input Sync" );
459
460     // Currently active connection signal source cmd, command type
461     // status, source unknown, destination MSU sync input plug
462
463     for ( AvPlugVector::const_iterator it = syncMSUInputPlugs.begin();
464           it != syncMSUInputPlugs.end();
465           ++it )
466     {
467         AvPlug* msuPlug = *it;
468         for ( AvPlugVector::const_iterator jt =
469                   msuPlug->getInputConnections().begin();
470               jt != msuPlug->getInputConnections().end();
471               ++jt )
472         {
473             AvPlug* plug = *jt;
474
475             for ( SyncInfoVector::iterator it = m_syncInfos.begin();
476                   it != m_syncInfos.end();
477                   ++it )
478             {
479                 SyncInfo* pSyncInfo = &*it;
480                 if ( ( pSyncInfo->m_source == plug )
481                      && ( pSyncInfo->m_destination == msuPlug ) )
482                 {
483                     m_activeSyncInfo = pSyncInfo;
484                     break;
485                 }
486             }
487             debugOutput( DEBUG_LEVEL_NORMAL,
488                          "Active Sync Connection: '%s' -> '%s'\n",
489                          plug->getName(),
490                          msuPlug->getName() );
491         }
492     }
493
494     return true;
495 }
496
497 bool
498 AvDevice::enumerateSubUnits()
499 {
500     SubUnitInfoCmd subUnitInfoCmd( m_1394Service );
501     //subUnitInfoCmd.setVerbose( 1 );
502     subUnitInfoCmd.setCommandType( AVCCommand::eCT_Status );
503
504     // BeBoB has always exactly one audio and one music subunit. This
505     // means is fits into the first page of the SubUnitInfo command.
506     // So there is no need to do more than needed
507
508     subUnitInfoCmd.m_page = 0;
509     subUnitInfoCmd.setNodeId( m_nodeId );
510     subUnitInfoCmd.setVerbose( m_verboseLevel );
511     if ( !subUnitInfoCmd.fire() ) {
512         debugError( "Subunit info command failed\n" );
513     }
514
515     for ( int i = 0; i < subUnitInfoCmd.getNrOfValidEntries(); ++i ) {
516         subunit_type_t subunit_type
517             = subUnitInfoCmd.m_table[i].m_subunit_type;
518
519         unsigned int subunitId = getNrOfSubunits( subunit_type );
520
521         debugOutput( DEBUG_LEVEL_VERBOSE,
522                      "subunit_id = %2d, subunit_type = %2d (%s)\n",
523                      subunitId,
524                      subunit_type,
525                      subunitTypeToString( subunit_type ) );
526
527         AvDeviceSubunit* subunit = 0;
528         switch( subunit_type ) {
529         case AVCCommand::eST_Audio:
530             subunit = new AvDeviceSubunitAudio( *this, subunitId,
531                                                 m_verboseLevel );
532             if ( !subunit ) {
533                 debugFatal( "Could not allocate AvDeviceSubunitAudio\n" );
534                 return false;
535             }
536             break;
537         case AVCCommand::eST_Music:
538             subunit = new AvDeviceSubunitMusic( *this, subunitId,
539                                                 m_verboseLevel );
540             if ( !subunit ) {
541                 debugFatal( "Could not allocate AvDeviceSubunitMusic\n" );
542                 return false;
543             }
544             break;
545         default:
546             debugOutput( DEBUG_LEVEL_NORMAL,
547                          "Unsupported subunit found, subunit_type = %d (%s)\n",
548                          subunit_type,
549                          subunitTypeToString( subunit_type ) );
550             continue;
551
552         }
553
554         if ( !subunit->discover() ) {
555             debugError( "enumerateSubUnits: Could not discover "
556                         "subunit_id = %2d, subunit_type = %2d (%s)\n",
557                         subunitId,
558                         subunit_type,
559                         subunitTypeToString( subunit_type ) );
560             delete subunit;
561             return false;
562         }
563         m_subunits.push_back( subunit );
564     }
565
566     return true;
567 }
568
569
570 AvDeviceSubunit*
571 AvDevice::getSubunit( subunit_type_t subunitType,
572                       subunit_id_t subunitId ) const
573 {
574     for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin();
575           it != m_subunits.end();
576           ++it )
577     {
578         AvDeviceSubunit* subunit = *it;
579         if ( ( subunitType == subunit->getSubunitType() )
580              && ( subunitId == subunit->getSubunitId() ) )
581         {
582             return subunit;
583         }
584     }
585
586     return 0;
587 }
588
589
590 unsigned int
591 AvDevice::getNrOfSubunits( subunit_type_t subunitType ) const
592 {
593     unsigned int nrOfSubunits = 0;
594
595     for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin();
596           it != m_subunits.end();
597           ++it )
598     {
599         AvDeviceSubunit* subunit = *it;
600         if ( subunitType == subunit->getSubunitType() ) {
601             nrOfSubunits++;
602         }
603     }
604
605     return nrOfSubunits;
606 }
607
608 AvPlugConnection*
609 AvDevice::getPlugConnection( AvPlug& srcPlug ) const
610 {
611     for ( AvPlugConnectionVector::const_iterator it
612               = m_plugConnections.begin();
613           it != m_plugConnections.end();
614           ++it )
615     {
616         AvPlugConnection* plugConnection = *it;
617         if ( &( plugConnection->getSrcPlug() ) == &srcPlug ) {
618             return plugConnection;
619         }
620     }
621
622     return 0;
623 }
624
625 AvPlug*
626 AvDevice::getPlugById( AvPlugVector& plugs,
627                        AvPlug::EAvPlugDirection plugDirection,
628                        int id )
629 {
630     for ( AvPlugVector::iterator it = plugs.begin();
631           it != plugs.end();
632           ++it )
633     {
634         AvPlug* plug = *it;
635         if ( ( id == plug->getPlugId() )
636              && ( plugDirection == plug->getPlugDirection() ) )
637         {
638             return plug;
639         }
640     }
641
642     return 0;
643 }
644
645 AvPlugVector
646 AvDevice::getPlugsByType( AvPlugVector& plugs,
647                           AvPlug::EAvPlugDirection plugDirection,
648                           AvPlug::EAvPlugType type)
649 {
650     AvPlugVector plugVector;
651     for ( AvPlugVector::iterator it = plugs.begin();
652           it != plugs.end();
653           ++it )
654     {
655         AvPlug* plug = *it;
656         if ( ( type == plug->getPlugType() )
657              && ( plugDirection == plug->getPlugDirection() ) )
658         {
659             plugVector.push_back( plug );
660         }
661     }
662
663     return plugVector;
664 }
665
666 AvPlug*
667 AvDevice::getSyncPlug( int maxPlugId, AvPlug::EAvPlugDirection )
668 {
669     return 0;
670 }
671
672 bool
673 AvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency )
674 {
675
676     AvPlug* plug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
677     if ( !plug ) {
678         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
679         return false;
680     }
681
682     if ( !setSamplingFrequencyPlug( *plug,
683                                     AvPlug::eAPD_Input,
684                                     samplingFrequency ) )
685     {
686         debugError( "setSampleRate: Setting sample rate failed\n" );
687         return false;
688     }
689
690     plug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output,  0 );
691     if ( !plug ) {
692         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
693         return false;
694     }
695
696     if ( !setSamplingFrequencyPlug( *plug,
697                                     AvPlug::eAPD_Output,
698                                     samplingFrequency ) )
699     {
700         debugError( "setSampleRate: Setting sample rate failed\n" );
701         return false;
702     }
703
704
705     debugOutput( DEBUG_LEVEL_VERBOSE,
706                  "setSampleRate: Set sample rate to %d\n",
707                  convertESamplingFrequency( samplingFrequency ) );
708     return true;
709 }
710
711 bool
712 AvDevice::setSamplingFrequencyPlug( AvPlug& plug,
713                                     AvPlug::EAvPlugDirection direction,
714                                     ESamplingFrequency samplingFrequency )
715 {
716
717     ExtendedStreamFormatCmd extStreamFormatCmd(
718         m_1394Service,
719         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList );
720     UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
721                                      plug.getPlugId() );
722
723     extStreamFormatCmd.setPlugAddress(
724         PlugAddress(
725             AvPlug::convertPlugDirection(direction ),
726             PlugAddress::ePAM_Unit,
727             unitPlugAddress ) );
728
729     extStreamFormatCmd.setNodeId( m_nodeId );
730     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
731
732     int i = 0;
733     bool cmdSuccess = false;
734     bool correctFormatFound = false;
735
736     do {
737         extStreamFormatCmd.setIndexInStreamFormat( i );
738         extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
739         extStreamFormatCmd.setVerbose( m_verboseLevel );
740
741         cmdSuccess = extStreamFormatCmd.fire();
742
743         if ( cmdSuccess
744              && ( extStreamFormatCmd.getResponse() ==
745                   AVCCommand::eR_Implemented ) )
746         {
747             ESamplingFrequency foundFreq = eSF_DontCare;
748
749             FormatInformation* formatInfo =
750                 extStreamFormatCmd.getFormatInformation();
751             FormatInformationStreamsCompound* compoundStream
752                 = dynamic_cast< FormatInformationStreamsCompound* > (
753                     formatInfo->m_streams );
754             if ( compoundStream ) {
755                 foundFreq =
756                     static_cast<ESamplingFrequency>(
757                         compoundStream->m_samplingFrequency );
758             }
759
760             FormatInformationStreamsSync* syncStream
761                 = dynamic_cast< FormatInformationStreamsSync* > (
762                     formatInfo->m_streams );
763             if ( syncStream ) {
764                 foundFreq =
765                     static_cast<ESamplingFrequency>(
766                         syncStream->m_samplingFrequency );
767             }
768
769             if ( foundFreq == samplingFrequency )
770             {
771                 correctFormatFound = true;
772                 break;
773             }
774         }
775
776         ++i;
777     } while ( cmdSuccess
778               && ( extStreamFormatCmd.getResponse() ==
779                    ExtendedStreamFormatCmd::eR_Implemented )
780               && ( extStreamFormatCmd.getStatus() !=
781                    ExtendedStreamFormatCmd::eS_NotUsed ) );
782
783     if ( !cmdSuccess ) {
784         debugError( "setSampleRatePlug: Failed to retrieve format info\n" );
785         return false;
786     }
787
788     if ( !correctFormatFound ) {
789         debugError( "setSampleRatePlug: %s plug %d does not support "
790                     "sample rate %d\n",
791                     plug.getName(),
792                     plug.getPlugId(),
793                     convertESamplingFrequency( samplingFrequency ) );
794         return false;
795     }
796
797     extStreamFormatCmd.setSubFunction(
798         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand );
799     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Control );
800     extStreamFormatCmd.setVerbose( m_verboseLevel );
801
802     if ( !extStreamFormatCmd.fire() ) {
803         debugError( "setSampleRate: Could not set sample rate %d "
804                     "to %s plug %d\n",
805                     convertESamplingFrequency( samplingFrequency ),
806                     plug.getName(),
807                     plug.getPlugId() );
808         return false;
809     }
810
811     return true;
812 }
813
814 void
815 AvDevice::showDevice() const
816 {
817     m_plugManager.showPlugs();
818 }
819
820 void
821 AvDevice::showAvPlugs( AvPlugVector& plugs ) const
822 {
823     int i = 0;
824     for ( AvPlugVector::const_iterator it = plugs.begin();
825           it != plugs.end();
826           ++it, ++i )
827     {
828         AvPlug* plug = *it;
829         debugOutput( DEBUG_LEVEL_VERBOSE, "Plug %d\n", i );
830         plug->showPlug();
831     }
832 }
833
834 bool
835 AvDevice::checkSyncConnectionsAndAddToList( AvPlugVector& plhs,
836                                             AvPlugVector& prhs,
837                                             std::string syncDescription )
838 {
839     for ( AvPlugVector::iterator plIt = plhs.begin();
840           plIt != plhs.end();
841           ++plIt )
842     {
843         AvPlug* pl = *plIt;
844         for ( AvPlugVector::iterator prIt = prhs.begin();
845               prIt != prhs.end();
846               ++prIt )
847         {
848             AvPlug* pr = *prIt;
849             if ( pl->inquireConnnection( *pr ) ) {
850                 m_syncInfos.push_back( SyncInfo( *pl, *pr, syncDescription ) );
851                 debugOutput( DEBUG_LEVEL_NORMAL,
852                              "Sync connection '%s' -> '%s'\n",
853                              pl->getName(),
854                              pr->getName() );
855             }
856         }
857     }
858     return true;
859 }
860
861 bool AvDevice::setActiveSync(const SyncInfo& syncInfo)
862 {
863     return syncInfo.m_source->setConnection( *syncInfo.m_destination );
864 }
865
866 bool AvDevice::setId( unsigned int id)
867 {
868         return true;
869 }
870
871 }
Note: See TracBrowser for help on using the browser.