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

Revision 363, 37.8 kB (checked in by wagi, 17 years ago)

AvDevice::setSamplingFrequencyPlug: do not test format info status when iterating over supported sample rates. same fix was applied onto 1.0 branch earlier.

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 #include <sstream>
37
38 namespace BeBoB {
39
40 IMPL_DEBUG_MODULE( AvDevice, AvDevice, DEBUG_LEVEL_NORMAL );
41
42 AvDevice::AvDevice( std::auto_ptr< ConfigRom >( configRom ),
43                     Ieee1394Service& ieee1394service,
44                     int nodeId,
45                     int verboseLevel )
46     : m_configRom( configRom )
47     , m_1394Service( &ieee1394service )
48     , m_nodeId( nodeId )
49     , m_verboseLevel( verboseLevel )
50     , m_plugManager( verboseLevel )
51     , m_activeSyncInfo( 0 )
52     , m_id(0)
53     , m_receiveProcessor ( 0 )
54     , m_receiveProcessorBandwidth ( -1 )
55     , m_transmitProcessor ( 0 )
56     , m_transmitProcessorBandwidth ( -1 )
57 {
58     setDebugLevel( verboseLevel );
59     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::AvDevice (NodeID %d)\n",
60                  nodeId );
61 }
62
63 AvDevice::~AvDevice()
64 {
65     for ( AvDeviceSubunitVector::iterator it = m_subunits.begin();
66           it != m_subunits.end();
67           ++it )
68     {
69         delete *it;
70     }
71     for ( AvPlugConnectionVector::iterator it = m_plugConnections.begin();
72           it != m_plugConnections.end();
73           ++it )
74     {
75         delete *it;
76     }
77     for ( AvPlugVector::iterator it = m_pcrPlugs.begin();
78           it != m_pcrPlugs.end();
79           ++it )
80     {
81         delete *it;
82     }
83     for ( AvPlugVector::iterator it = m_externalPlugs.begin();
84           it != m_externalPlugs.end();
85           ++it )
86     {
87         delete *it;
88     }
89 }
90
91 ConfigRom&
92 AvDevice::getConfigRom() const
93 {
94     return *m_configRom;
95 }
96
97 struct VendorModelEntry {
98     unsigned int vendor_id;
99     unsigned int model_id;
100 };
101
102 static VendorModelEntry supportedDeviceList[] =
103 {
104     {0x00000f, 0x00010065},  // Mackie, Onyx Firewire
105
106     {0x0003db, 0x00010048},  // Apogee Electronics, Rosetta 200
107
108     {0x0007f5, 0x00010048},  // BridgeCo, RD Audio1
109
110     {0x000a92, 0x00010066},  // Presonous FirePOD
111
112     {0x000aac, 0x00000003},  // TerraTec Electronic GmbH, Phase 88 FW
113     {0x000aac, 0x00000004},  // TerraTec Electronic GmbH, Phase X24 FW (model version 4)
114     {0x000aac, 0x00000007},  // TerraTec Electronic GmbH, Phase X24 FW (model version 7)
115
116     {0x000f1b, 0x00010064},  // ESI, Quatafire 610
117
118     {0x0040ab, 0x00010048},  // EDIROL, FA-101
119     {0x0040ab, 0x00010049},  // EDIROL, FA-66
120
121     {0x00130e, 0x00000003},  // Focusrite, Pro26IO (Saffire 26)
122 };
123
124 bool
125 AvDevice::probe( ConfigRom& configRom )
126 {
127     unsigned int vendorId = configRom.getNodeVendorId();
128     unsigned int modelId = configRom.getModelId();
129
130     for ( unsigned int i = 0;
131           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
132           ++i )
133     {
134         if ( ( supportedDeviceList[i].vendor_id == vendorId )
135              && ( supportedDeviceList[i].model_id == modelId ) )
136         {
137             return true;
138         }
139     }
140
141     return false;
142 }
143
144 bool
145 AvDevice::discover()
146 {
147     if ( !enumerateSubUnits() ) {
148         debugError( "Could not enumarate sub units\n" );
149         return false;
150     }
151
152     if ( !discoverPlugs() ) {
153         debugError( "Detecting plugs failed\n" );
154         return false;
155     }
156
157     if ( !discoverPlugConnections() ) {
158         debugError( "Detecting plug connections failed\n" );
159         return false;
160     }
161
162     if ( !discoverSubUnitsPlugConnections() ) {
163         debugError( "Detecting plug connnection failed\n" );
164         return false;
165     }
166
167     if ( !discoverSyncModes() ) {
168         debugError( "Detecting sync modes failed\n" );
169         return false;
170     }
171
172     return true;
173 }
174
175 bool
176 AvDevice::discoverPlugs()
177 {
178     //////////////////////////////////////////////
179     // Get number of available isochronous input
180     // and output plugs of unit
181
182     PlugInfoCmd plugInfoCmd( m_1394Service );
183     plugInfoCmd.setNodeId( m_nodeId );
184     plugInfoCmd.setCommandType( AVCCommand::eCT_Status );
185     plugInfoCmd.setVerbose( m_verboseLevel );
186
187     if ( !plugInfoCmd.fire() ) {
188         debugError( "plug info command failed\n" );
189         return false;
190     }
191
192     debugOutput( DEBUG_LEVEL_NORMAL, "number of iso input plugs = %d\n",
193                  plugInfoCmd.m_serialBusIsochronousInputPlugs );
194     debugOutput( DEBUG_LEVEL_NORMAL, "number of iso output plugs = %d\n",
195                  plugInfoCmd.m_serialBusIsochronousOutputPlugs );
196     debugOutput( DEBUG_LEVEL_NORMAL, "number of external input plugs = %d\n",
197                  plugInfoCmd.m_externalInputPlugs );
198     debugOutput( DEBUG_LEVEL_NORMAL, "number of external output plugs = %d\n",
199                  plugInfoCmd.m_externalOutputPlugs );
200
201     if ( !discoverPlugsPCR( AvPlug::eAPD_Input,
202                             plugInfoCmd.m_serialBusIsochronousInputPlugs ) )
203     {
204         debugError( "pcr input plug discovering failed\n" );
205         return false;
206     }
207
208     if ( !discoverPlugsPCR( AvPlug::eAPD_Output,
209                             plugInfoCmd.m_serialBusIsochronousOutputPlugs ) )
210     {
211         debugError( "pcr output plug discovering failed\n" );
212         return false;
213     }
214
215     if ( !discoverPlugsExternal( AvPlug::eAPD_Input,
216                                  plugInfoCmd.m_externalInputPlugs ) )
217     {
218         debugError( "external input plug discovering failed\n" );
219         return false;
220     }
221
222     if ( !discoverPlugsExternal( AvPlug::eAPD_Output,
223                                  plugInfoCmd.m_externalOutputPlugs ) )
224     {
225         debugError( "external output plug discovering failed\n" );
226         return false;
227     }
228
229     return true;
230 }
231
232 bool
233 AvDevice::discoverPlugsPCR( AvPlug::EAvPlugDirection plugDirection,
234                             plug_id_t plugMaxId )
235 {
236     for ( int plugId = 0;
237           plugId < plugMaxId;
238           ++plugId )
239     {
240         AvPlug* plug  = new AvPlug( *m_1394Service,
241                                     m_nodeId,
242                                     m_plugManager,
243                                     AVCCommand::eST_Unit,
244                                     0xff,
245                                     0xff,
246                                     0xff,
247                                     AvPlug::eAPA_PCR,
248                                     plugDirection,
249                                     plugId,
250                                     m_verboseLevel );
251         if ( !plug || !plug->discover() ) {
252             debugError( "plug discovering failed\n" );
253             delete plug;
254             return false;
255         }
256
257         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
258                      plug->getName() );
259         m_pcrPlugs.push_back( plug );
260     }
261
262     return true;
263 }
264
265 bool
266 AvDevice::discoverPlugsExternal( AvPlug::EAvPlugDirection plugDirection,
267                                  plug_id_t plugMaxId )
268 {
269     for ( int plugId = 0;
270           plugId < plugMaxId;
271           ++plugId )
272     {
273         AvPlug* plug  = new AvPlug( *m_1394Service,
274                                     m_nodeId,
275                                     m_plugManager,
276                                     AVCCommand::eST_Unit,
277                                     0xff,
278                                     0xff,
279                                     0xff,
280                                     AvPlug::eAPA_ExternalPlug,
281                                     plugDirection,
282                                     plugId,
283                                     m_verboseLevel );
284         if ( !plug || !plug->discover() ) {
285             debugError( "plug discovering failed\n" );
286             return false;
287         }
288
289         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
290                      plug->getName() );
291         m_externalPlugs.push_back( plug );
292     }
293
294     return true;
295 }
296
297 bool
298 AvDevice::discoverPlugConnections()
299 {
300     for ( AvPlugVector::iterator it = m_pcrPlugs.begin();
301           it != m_pcrPlugs.end();
302           ++it )
303     {
304         AvPlug* plug = *it;
305         if ( !plug->discoverConnections() ) {
306             debugError( "Could not discover plug connections\n" );
307             return false;
308         }
309     }
310     for ( AvPlugVector::iterator it = m_externalPlugs.begin();
311           it != m_externalPlugs.end();
312           ++it )
313     {
314         AvPlug* plug = *it;
315         if ( !plug->discoverConnections() ) {
316             debugError( "Could not discover plug connections\n" );
317             return false;
318         }
319     }
320
321     return true;
322 }
323
324 bool
325 AvDevice::discoverSubUnitsPlugConnections()
326 {
327     for ( AvDeviceSubunitVector::iterator it = m_subunits.begin();
328           it != m_subunits.end();
329           ++it )
330     {
331         AvDeviceSubunit* subunit = *it;
332         if ( !subunit->discoverConnections() ) {
333             debugError( "Subunit '%s'  plug connections failed\n",
334                         subunit->getName() );
335             return false;
336         }
337     }
338     return true;
339 }
340
341 bool
342 AvDevice::discoverSyncModes()
343 {
344     // Following possible sync plugs exists:
345     // - Music subunit sync output plug = internal sync (CSP)
346     // - Unit input plug 0 = SYT match
347     // - Unit input plut 1 = Sync stream
348     //
349     // If last sync mode is reported it is mostelikely not
350     // implemented *sic*
351     //
352     // Following sync sources are device specific:
353     // - All unit external input plugs which have a
354     //   sync information (WS, SPDIF, ...)
355
356     // First we have to find the sync input and output plug
357     // in the music subunit.
358
359     // Note PCR input means 1394bus-to-device where as
360     // MSU input means subunit-to-device
361
362     AvPlugVector syncPCRInputPlugs = getPlugsByType( m_pcrPlugs,
363                                                      AvPlug::eAPD_Input,
364                                                      AvPlug::eAPT_Sync );
365     if ( !syncPCRInputPlugs.size() ) {
366         debugWarning( "No PCR sync input plug found\n" );
367     }
368
369     AvPlugVector syncPCROutputPlugs = getPlugsByType( m_pcrPlugs,
370                                                       AvPlug::eAPD_Output,
371                                                       AvPlug::eAPT_Sync );
372     if ( !syncPCROutputPlugs.size() ) {
373         debugWarning( "No PCR sync output plug found\n" );
374     }
375
376     AvPlugVector isoPCRInputPlugs = getPlugsByType( m_pcrPlugs,
377                                                     AvPlug::eAPD_Input,
378                                                     AvPlug::eAPT_IsoStream );
379     if ( !isoPCRInputPlugs.size() ) {
380         debugWarning( "No PCR iso input plug found\n" );
381
382     }
383
384     AvPlugVector isoPCROutputPlugs = getPlugsByType( m_pcrPlugs,
385                                                     AvPlug::eAPD_Output,
386                                                     AvPlug::eAPT_IsoStream );
387     if ( !isoPCROutputPlugs.size() ) {
388         debugWarning( "No PCR iso output plug found\n" );
389
390     }
391
392     AvPlugVector digitalPCRInputPlugs = getPlugsByType( m_externalPlugs,
393                                                     AvPlug::eAPD_Input,
394                                                     AvPlug::eAPT_Digital );
395
396     AvPlugVector syncMSUInputPlugs = m_plugManager.getPlugsByType(
397         AVCCommand::eST_Music,
398         0,
399         0xff,
400         0xff,
401         AvPlug::eAPA_SubunitPlug,
402         AvPlug::eAPD_Input,
403         AvPlug::eAPT_Sync );
404     if ( !syncMSUInputPlugs.size() ) {
405         debugWarning( "No sync input plug for MSU subunit found\n" );
406     }
407
408     AvPlugVector syncMSUOutputPlugs = m_plugManager.getPlugsByType(
409         AVCCommand::eST_Music,
410         0,
411         0xff,
412         0xff,
413         AvPlug::eAPA_SubunitPlug,
414         AvPlug::eAPD_Output,
415         AvPlug::eAPT_Sync );
416     if ( !syncMSUOutputPlugs.size() ) {
417         debugWarning( "No sync output plug for MSU subunit found\n" );
418     }
419
420     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Input Plugs:\n" );
421     showAvPlugs( syncPCRInputPlugs );
422     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Output Plugs:\n" );
423     showAvPlugs( syncPCROutputPlugs );
424     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Input Plugs:\n" );
425     showAvPlugs( isoPCRInputPlugs );
426     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Output Plugs:\n" );
427     showAvPlugs( isoPCROutputPlugs );
428     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR digital Input Plugs:\n" );
429     showAvPlugs( digitalPCRInputPlugs );
430     debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Input Plugs:\n" );
431     showAvPlugs( syncMSUInputPlugs );
432     debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Output Plugs:\n" );
433     showAvPlugs( syncMSUOutputPlugs );
434
435     // Check all possible PCR input to MSU input connections
436     // -> sync stream input
437     checkSyncConnectionsAndAddToList( syncPCRInputPlugs,
438                                       syncMSUInputPlugs,
439                                       "Sync Stream Input" );
440
441     // Check all possible MSU output to PCR output connections
442     // -> sync stream output
443     checkSyncConnectionsAndAddToList( syncMSUOutputPlugs,
444                                       syncPCROutputPlugs,
445                                       "Sync Stream Output" );
446
447     // Check all PCR iso input to MSU input connections
448     // -> SYT match
449     checkSyncConnectionsAndAddToList( isoPCRInputPlugs,
450                                       syncMSUInputPlugs,
451                                       "Syt Match" );
452
453     // Check all MSU sync output to MSU input connections
454     // -> CSP
455     checkSyncConnectionsAndAddToList( syncMSUOutputPlugs,
456                                       syncMSUInputPlugs,
457                                       "Internal (CSP)" );
458
459     // Check all external PCR digital input to MSU input connections
460     // -> SPDIF/ADAT sync
461     checkSyncConnectionsAndAddToList( digitalPCRInputPlugs,
462                                       syncMSUInputPlugs,
463                                       "Digital Input Sync" );
464
465     // Currently active connection signal source cmd, command type
466     // status, source unknown, destination MSU sync input plug
467
468     for ( AvPlugVector::const_iterator it = syncMSUInputPlugs.begin();
469           it != syncMSUInputPlugs.end();
470           ++it )
471     {
472         AvPlug* msuPlug = *it;
473         for ( AvPlugVector::const_iterator jt =
474                   msuPlug->getInputConnections().begin();
475               jt != msuPlug->getInputConnections().end();
476               ++jt )
477         {
478             AvPlug* plug = *jt;
479
480             for ( SyncInfoVector::iterator it = m_syncInfos.begin();
481                   it != m_syncInfos.end();
482                   ++it )
483             {
484                 SyncInfo* pSyncInfo = &*it;
485                 if ( ( pSyncInfo->m_source == plug )
486                      && ( pSyncInfo->m_destination == msuPlug ) )
487                 {
488                     m_activeSyncInfo = pSyncInfo;
489                     break;
490                 }
491             }
492             debugOutput( DEBUG_LEVEL_NORMAL,
493                          "Active Sync Connection: '%s' -> '%s'\n",
494                          plug->getName(),
495                          msuPlug->getName() );
496         }
497     }
498
499     return true;
500 }
501
502 bool
503 AvDevice::enumerateSubUnits()
504 {
505     bool musicSubunitFound=false;
506     bool audioSubunitFound=false;
507
508     SubUnitInfoCmd subUnitInfoCmd( m_1394Service );
509     //subUnitInfoCmd.setVerbose( 1 );
510     subUnitInfoCmd.setCommandType( AVCCommand::eCT_Status );
511
512     // BeBoB has always exactly one audio and one music subunit. This
513     // means is fits into the first page of the SubUnitInfo command.
514     // So there is no need to do more than needed
515
516     subUnitInfoCmd.m_page = 0;
517     subUnitInfoCmd.setNodeId( m_nodeId );
518     subUnitInfoCmd.setVerbose( m_verboseLevel );
519     if ( !subUnitInfoCmd.fire() ) {
520         debugError( "Subunit info command failed\n" );
521         // shouldn't this be an error situation?
522         return false;
523     }
524
525     for ( int i = 0; i < subUnitInfoCmd.getNrOfValidEntries(); ++i ) {
526         subunit_type_t subunit_type
527             = subUnitInfoCmd.m_table[i].m_subunit_type;
528
529         unsigned int subunitId = getNrOfSubunits( subunit_type );
530
531         debugOutput( DEBUG_LEVEL_VERBOSE,
532                      "subunit_id = %2d, subunit_type = %2d (%s)\n",
533                      subunitId,
534                      subunit_type,
535                      subunitTypeToString( subunit_type ) );
536
537         AvDeviceSubunit* subunit = 0;
538         switch( subunit_type ) {
539         case AVCCommand::eST_Audio:
540             subunit = new AvDeviceSubunitAudio( *this, subunitId,
541                                                 m_verboseLevel );
542             if ( !subunit ) {
543                 debugFatal( "Could not allocate AvDeviceSubunitAudio\n" );
544                 return false;
545             }
546            
547             m_subunits.push_back( subunit );
548             audioSubunitFound=true;
549            
550             break;
551         case AVCCommand::eST_Music:
552             subunit = new AvDeviceSubunitMusic( *this, subunitId,
553                                                 m_verboseLevel );
554             if ( !subunit ) {
555                 debugFatal( "Could not allocate AvDeviceSubunitMusic\n" );
556                 return false;
557             }
558            
559             m_subunits.push_back( subunit );
560             musicSubunitFound=true;
561            
562             break;
563         default:
564             debugOutput( DEBUG_LEVEL_NORMAL,
565                          "Unsupported subunit found, subunit_type = %d (%s)\n",
566                          subunit_type,
567                          subunitTypeToString( subunit_type ) );
568             continue;
569
570         }
571
572         if ( !subunit->discover() ) {
573             debugError( "enumerateSubUnits: Could not discover "
574                         "subunit_id = %2d, subunit_type = %2d (%s)\n",
575                         subunitId,
576                         subunit_type,
577                         subunitTypeToString( subunit_type ) );
578             delete subunit;
579             return false;
580         }
581
582     }
583
584     // a BeBoB always has an audio and a music subunit
585     return (musicSubunitFound && audioSubunitFound);
586 }
587
588
589 AvDeviceSubunit*
590 AvDevice::getSubunit( subunit_type_t subunitType,
591                       subunit_id_t subunitId ) const
592 {
593     for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin();
594           it != m_subunits.end();
595           ++it )
596     {
597         AvDeviceSubunit* subunit = *it;
598         if ( ( subunitType == subunit->getSubunitType() )
599              && ( subunitId == subunit->getSubunitId() ) )
600         {
601             return subunit;
602         }
603     }
604
605     return 0;
606 }
607
608
609 unsigned int
610 AvDevice::getNrOfSubunits( subunit_type_t subunitType ) const
611 {
612     unsigned int nrOfSubunits = 0;
613
614     for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin();
615           it != m_subunits.end();
616           ++it )
617     {
618         AvDeviceSubunit* subunit = *it;
619         if ( subunitType == subunit->getSubunitType() ) {
620             nrOfSubunits++;
621         }
622     }
623
624     return nrOfSubunits;
625 }
626
627 AvPlugConnection*
628 AvDevice::getPlugConnection( AvPlug& srcPlug ) const
629 {
630     for ( AvPlugConnectionVector::const_iterator it
631               = m_plugConnections.begin();
632           it != m_plugConnections.end();
633           ++it )
634     {
635         AvPlugConnection* plugConnection = *it;
636         if ( &( plugConnection->getSrcPlug() ) == &srcPlug ) {
637             return plugConnection;
638         }
639     }
640
641     return 0;
642 }
643
644 AvPlug*
645 AvDevice::getPlugById( AvPlugVector& plugs,
646                        AvPlug::EAvPlugDirection plugDirection,
647                        int id )
648 {
649     for ( AvPlugVector::iterator it = plugs.begin();
650           it != plugs.end();
651           ++it )
652     {
653         AvPlug* plug = *it;
654         if ( ( id == plug->getPlugId() )
655              && ( plugDirection == plug->getPlugDirection() ) )
656         {
657             return plug;
658         }
659     }
660
661     return 0;
662 }
663
664 AvPlugVector
665 AvDevice::getPlugsByType( AvPlugVector& plugs,
666                           AvPlug::EAvPlugDirection plugDirection,
667                           AvPlug::EAvPlugType type)
668 {
669     AvPlugVector plugVector;
670     for ( AvPlugVector::iterator it = plugs.begin();
671           it != plugs.end();
672           ++it )
673     {
674         AvPlug* plug = *it;
675         if ( ( type == plug->getPlugType() )
676              && ( plugDirection == plug->getPlugDirection() ) )
677         {
678             plugVector.push_back( plug );
679         }
680     }
681
682     return plugVector;
683 }
684
685 AvPlug*
686 AvDevice::getSyncPlug( int maxPlugId, AvPlug::EAvPlugDirection )
687 {
688     return 0;
689 }
690
691 bool
692 AvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency )
693 {
694
695     AvPlug* plug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
696     if ( !plug ) {
697         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
698         return false;
699     }
700
701     if ( !setSamplingFrequencyPlug( *plug,
702                                     AvPlug::eAPD_Input,
703                                     samplingFrequency ) )
704     {
705         debugError( "setSampleRate: Setting sample rate failed\n" );
706         return false;
707     }
708
709     plug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output,  0 );
710     if ( !plug ) {
711         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
712         return false;
713     }
714
715     if ( !setSamplingFrequencyPlug( *plug,
716                                     AvPlug::eAPD_Output,
717                                     samplingFrequency ) )
718     {
719         debugError( "setSampleRate: Setting sample rate failed\n" );
720         return false;
721     }
722
723
724     debugOutput( DEBUG_LEVEL_VERBOSE,
725                  "setSampleRate: Set sample rate to %d\n",
726                  convertESamplingFrequency( samplingFrequency ) );
727     return true;
728 }
729
730 int
731 AvDevice::getSamplingFrequency( ) {
732     AvPlug* inputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
733     if ( !inputPlug ) {
734         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
735         return false;
736     }
737     AvPlug* outputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output, 0 );
738     if ( !outputPlug ) {
739         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
740         return false;
741     }
742
743     int samplerate_playback=inputPlug->getSampleRate();
744     int samplerate_capture=outputPlug->getSampleRate();
745
746     if (samplerate_playback != samplerate_capture) {
747         debugWarning("Samplerates for capture and playback differ!\n");
748     }
749     return samplerate_capture;
750 }
751
752
753 bool
754 AvDevice::setSamplingFrequencyPlug( AvPlug& plug,
755                                     AvPlug::EAvPlugDirection direction,
756                                     ESamplingFrequency samplingFrequency )
757 {
758
759     ExtendedStreamFormatCmd extStreamFormatCmd(
760         m_1394Service,
761         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList );
762     UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
763                                      plug.getPlugId() );
764
765     extStreamFormatCmd.setPlugAddress(
766         PlugAddress(
767             AvPlug::convertPlugDirection(direction ),
768             PlugAddress::ePAM_Unit,
769             unitPlugAddress ) );
770
771     extStreamFormatCmd.setNodeId( m_nodeId );
772     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
773
774     int i = 0;
775     bool cmdSuccess = false;
776     bool correctFormatFound = false;
777
778     do {
779         extStreamFormatCmd.setIndexInStreamFormat( i );
780         extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
781         extStreamFormatCmd.setVerbose( m_verboseLevel );
782
783         cmdSuccess = extStreamFormatCmd.fire();
784
785         if ( cmdSuccess
786              && ( extStreamFormatCmd.getResponse() ==
787                   AVCCommand::eR_Implemented ) )
788         {
789             ESamplingFrequency foundFreq = eSF_DontCare;
790
791             FormatInformation* formatInfo =
792                 extStreamFormatCmd.getFormatInformation();
793             FormatInformationStreamsCompound* compoundStream
794                 = dynamic_cast< FormatInformationStreamsCompound* > (
795                     formatInfo->m_streams );
796             if ( compoundStream ) {
797                 foundFreq =
798                     static_cast< ESamplingFrequency >(
799                         compoundStream->m_samplingFrequency );
800             }
801
802             FormatInformationStreamsSync* syncStream
803                 = dynamic_cast< FormatInformationStreamsSync* > (
804                     formatInfo->m_streams );
805             if ( syncStream ) {
806                 foundFreq =
807                     static_cast< ESamplingFrequency >(
808                         syncStream->m_samplingFrequency );
809             }
810
811             if ( foundFreq == samplingFrequency )
812             {
813                 correctFormatFound = true;
814                 break;
815             }
816         }
817
818         ++i;
819     } while ( cmdSuccess
820               && ( extStreamFormatCmd.getResponse() ==
821                    ExtendedStreamFormatCmd::eR_Implemented ) );
822
823     if ( !cmdSuccess ) {
824         debugError( "setSampleRatePlug: Failed to retrieve format info\n" );
825         return false;
826     }
827
828     if ( !correctFormatFound ) {
829         debugError( "setSampleRatePlug: %s plug %d does not support "
830                     "sample rate %d\n",
831                     plug.getName(),
832                     plug.getPlugId(),
833                     convertESamplingFrequency( samplingFrequency ) );
834         return false;
835     }
836
837     extStreamFormatCmd.setSubFunction(
838         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand );
839     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Control );
840     extStreamFormatCmd.setVerbose( m_verboseLevel );
841
842     if ( !extStreamFormatCmd.fire() ) {
843         debugError( "setSampleRate: Could not set sample rate %d "
844                     "to %s plug %d\n",
845                     convertESamplingFrequency( samplingFrequency ),
846                     plug.getName(),
847                     plug.getPlugId() );
848         return false;
849     }
850
851     return true;
852 }
853
854 void
855 AvDevice::showDevice() const
856 {
857     m_plugManager.showPlugs();
858 }
859
860 void
861 AvDevice::showAvPlugs( AvPlugVector& plugs ) const
862 {
863     int i = 0;
864     for ( AvPlugVector::const_iterator it = plugs.begin();
865           it != plugs.end();
866           ++it, ++i )
867     {
868         AvPlug* plug = *it;
869         debugOutput( DEBUG_LEVEL_VERBOSE, "Plug %d\n", i );
870         plug->showPlug();
871     }
872 }
873
874 bool
875 AvDevice::checkSyncConnectionsAndAddToList( AvPlugVector& plhs,
876                                             AvPlugVector& prhs,
877                                             std::string syncDescription )
878 {
879     for ( AvPlugVector::iterator plIt = plhs.begin();
880           plIt != plhs.end();
881           ++plIt )
882     {
883         AvPlug* pl = *plIt;
884         for ( AvPlugVector::iterator prIt = prhs.begin();
885               prIt != prhs.end();
886               ++prIt )
887         {
888             AvPlug* pr = *prIt;
889             if ( pl->inquireConnnection( *pr ) ) {
890                 m_syncInfos.push_back( SyncInfo( *pl, *pr, syncDescription ) );
891                 debugOutput( DEBUG_LEVEL_NORMAL,
892                              "Sync connection '%s' -> '%s'\n",
893                              pl->getName(),
894                              pr->getName() );
895             }
896         }
897     }
898     return true;
899 }
900
901 bool AvDevice::setActiveSync(const SyncInfo& syncInfo)
902 {
903     return syncInfo.m_source->setConnection( *syncInfo.m_destination );
904 }
905
906 bool AvDevice::setId( unsigned int id)
907 {
908     // FIXME: decent ID system nescessary
909     m_id=id;
910         return true;
911 }
912
913 bool
914 AvDevice::prepare() {
915     ///////////
916     // get plugs
917
918     AvPlug* inputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
919     if ( !inputPlug ) {
920         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
921         return false;
922     }
923     AvPlug* outputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output, 0 );
924     if ( !outputPlug ) {
925         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
926         return false;
927     }
928
929     int samplerate=outputPlug->getSampleRate();
930     m_receiveProcessor=new FreebobStreaming::AmdtpReceiveStreamProcessor(
931                              m_1394Service->getPort(),
932                              samplerate,
933                              outputPlug->getNrOfChannels());
934
935     if(!m_receiveProcessor->init()) {
936         debugFatal("Could not initialize receive processor!\n");
937         return false;
938     }
939
940     if (!addPlugToProcessor(*outputPlug,m_receiveProcessor,
941         FreebobStreaming::AmdtpAudioPort::E_Capture)) {
942         debugFatal("Could not add plug to processor!\n");
943         return false;
944     }
945
946     // do the transmit processor
947 //     if (m_snoopMode) {
948 //         // we are snooping, so these are receive too.
949 //         samplerate=inputPlug->getSampleRate();
950 //         m_receiveProcessor2=new FreebobStreaming::AmdtpReceiveStreamProcessor(
951 //                                   channel,
952 //                                   m_1394Service->getPort(),
953 //                                   samplerate,
954 //                                   inputPlug->getNrOfChannels());
955 //         
956 //         if(!m_receiveProcessor2->init()) {
957 //             debugFatal("Could not initialize snooping receive processor!\n");
958 //             return false;
959 //         }
960 //         if (!addPlugToProcessor(*inputPlug,m_receiveProcessor2,
961 //             FreebobStreaming::AmdtpAudioPort::E_Capture)) {
962 //             debugFatal("Could not add plug to processor!\n");
963 //             return false;
964 //         }
965 //     } else {
966         // do the transmit processor
967         samplerate=inputPlug->getSampleRate();
968         m_transmitProcessor=new FreebobStreaming::AmdtpTransmitStreamProcessor(
969                                 m_1394Service->getPort(),
970                                 samplerate,
971                                 inputPlug->getNrOfChannels());
972                                
973         if(!m_transmitProcessor->init()) {
974             debugFatal("Could not initialize transmit processor!\n");
975             return false;
976        
977         }
978        
979         // FIXME: do this the proper way!
980         m_transmitProcessor->syncmaster=m_receiveProcessor;
981    
982         if (!addPlugToProcessor(*inputPlug,m_transmitProcessor,
983             FreebobStreaming::AmdtpAudioPort::E_Playback)) {
984             debugFatal("Could not add plug to processor!\n");
985             return false;
986         }
987 //     }
988
989     return true;
990 }
991
992 bool
993 AvDevice::addPlugToProcessor(
994     AvPlug& plug,
995     FreebobStreaming::StreamProcessor *processor,
996     FreebobStreaming::AmdtpAudioPort::E_Direction direction) {
997
998     AvPlug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
999     for ( AvPlug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
1000           it != clusterInfos.end();
1001           ++it )
1002     {
1003         const AvPlug::ClusterInfo* clusterInfo = &( *it );
1004
1005         AvPlug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
1006         for ( AvPlug::ChannelInfoVector::const_iterator it = channelInfos.begin();
1007               it != channelInfos.end();
1008               ++it )
1009         {
1010             const AvPlug::ChannelInfo* channelInfo = &( *it );
1011             std::ostringstream portname;
1012            
1013             portname << "dev" << m_id << "_" << channelInfo->m_name;
1014            
1015             FreebobStreaming::Port *p=NULL;
1016             switch(clusterInfo->m_portType) {
1017             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
1018             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
1019             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
1020             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
1021             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
1022                 p=new FreebobStreaming::AmdtpAudioPort(
1023                         portname.str(),
1024                         direction,
1025                         // \todo: streaming backend expects indexing starting from 0
1026                         // but bebob reports it starting from 1. Decide where
1027                         // and how to handle this (pp: here)
1028                         channelInfo->m_streamPosition - 1,
1029                         channelInfo->m_location,
1030                         FreebobStreaming::AmdtpPortInfo::E_MBLA,
1031                         clusterInfo->m_portType
1032                 );
1033                 break;
1034
1035             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
1036                 p=new FreebobStreaming::AmdtpMidiPort(
1037                         portname.str(),
1038                         direction,
1039                         // \todo: streaming backend expects indexing starting from 0
1040                         // but bebob reports it starting from 1. Decide where
1041                         // and how to handle this (pp: here)
1042                         channelInfo->m_streamPosition - 1,
1043                         channelInfo->m_location,
1044                         FreebobStreaming::AmdtpPortInfo::E_Midi,
1045                         clusterInfo->m_portType
1046                 );
1047
1048                 break;
1049             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
1050             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
1051             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
1052             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
1053             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
1054             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
1055             default:
1056             // unsupported
1057                 break;
1058             }
1059
1060             if (!p) {
1061                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
1062             } else {
1063        
1064                 if (!processor->addPort(p)) {
1065                     debugWarning("Could not register port with stream processor\n");
1066                     return false;
1067                 }
1068             }
1069          }
1070     }
1071     return true;
1072 }
1073
1074 int
1075 AvDevice::getStreamCount() {
1076     return 2; // one receive, one transmit
1077 }
1078
1079 FreebobStreaming::StreamProcessor *
1080 AvDevice::getStreamProcessorByIndex(int i) {
1081     switch (i) {
1082     case 0:
1083         return m_receiveProcessor;
1084     case 1:
1085 //         if (m_snoopMode) {
1086 //             return m_receiveProcessor2;
1087 //         } else {
1088             return m_transmitProcessor;
1089 //         }
1090     default:
1091         return NULL;
1092     }
1093     return 0;
1094 }
1095
1096 int
1097 AvDevice::startStreamByIndex(int i) {
1098     int iso_channel=0;
1099     int plug=0;
1100     int hostplug=-1;
1101    
1102 //     if (m_snoopMode) {
1103 //     
1104 //         switch (i) {
1105 //         case 0:
1106 //             // snooping doesn't use CMP, but obtains the info of the channel
1107 //             // from the target plug
1108 //             
1109 //             // TODO: get isochannel from plug
1110 //             
1111 //             // set the channel obtained by the connection management
1112 //             m_receiveProcessor->setChannel(iso_channel);
1113 //             break;
1114 //         case 1:
1115 //             // snooping doesn't use CMP, but obtains the info of the channel
1116 //             // from the target plug
1117 //             
1118 //             // TODO: get isochannel from plug
1119 //             
1120 //             // set the channel obtained by the connection management
1121 //             m_receiveProcessor2->setChannel(iso_channel);
1122 //
1123 //             break;
1124 //         default:
1125 //             return 0;
1126 //         }
1127 //     } else {
1128    
1129         switch (i) {
1130         case 0:
1131             // do connection management: make connection
1132             iso_channel = iec61883_cmp_connect(
1133                 m_1394Service->getHandle(),
1134                 m_nodeId | 0xffc0,
1135                 &plug,
1136                 raw1394_get_local_id (m_1394Service->getHandle()),
1137                 &hostplug,
1138                 &m_receiveProcessorBandwidth);
1139            
1140             // set the channel obtained by the connection management
1141             m_receiveProcessor->setChannel(iso_channel);
1142             break;
1143         case 1:
1144             // do connection management: make connection
1145             iso_channel = iec61883_cmp_connect(
1146                 m_1394Service->getHandle(),
1147                 raw1394_get_local_id (m_1394Service->getHandle()),
1148                 &hostplug,
1149                 m_nodeId | 0xffc0,
1150                 &plug,
1151                 &m_transmitProcessorBandwidth);
1152            
1153             // set the channel obtained by the connection management
1154             m_transmitProcessor->setChannel(iso_channel);
1155             break;
1156         default:
1157             return 0;
1158         }
1159 //     }
1160    
1161     return 0;
1162
1163 }
1164
1165 int
1166 AvDevice::stopStreamByIndex(int i) {
1167     // do connection management: break connection
1168
1169     int plug=0;
1170     int hostplug=-1;
1171 //     if (m_snoopMode) {
1172 //         switch (i) {
1173 //         case 0:
1174 //             // do connection management: break connection
1175 //     
1176 //             break;
1177 //         case 1:
1178 //             // do connection management: break connection
1179 //
1180 //             break;
1181 //         default:
1182 //             return 0;
1183 //         }
1184 //     } else {
1185         switch (i) {
1186         case 0:
1187             // do connection management: break connection
1188             iec61883_cmp_disconnect(
1189                 m_1394Service->getHandle(),
1190                 m_nodeId | 0xffc0,
1191                 plug,
1192                 raw1394_get_local_id (m_1394Service->getHandle()),
1193                 hostplug,
1194                 m_receiveProcessor->getChannel(),
1195                 m_receiveProcessorBandwidth);
1196    
1197             break;
1198         case 1:
1199             // do connection management: break connection
1200             iec61883_cmp_disconnect(
1201                 m_1394Service->getHandle(),
1202                 raw1394_get_local_id (m_1394Service->getHandle()),
1203                 hostplug,
1204                 m_nodeId | 0xffc0,
1205                 plug,
1206                 m_transmitProcessor->getChannel(),
1207                 m_transmitProcessorBandwidth);
1208
1209             break;
1210         default:
1211             return 0;
1212         }
1213 //     }
1214    
1215     return 0;
1216 }
1217
1218
1219 } // end of namespace
Note: See TracBrowser for help on using the browser.