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

Revision 368, 38.6 kB (checked in by wagi, 17 years ago)

ConfigRom::serialize: no prefix needed for member
ConfigRom::deserialize: ieee1394service argument

no prefix needed for member
return 0 if deserializing fails

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