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

Revision 376, 41.6 kB (checked in by wagi, 17 years ago)

De/Serialize function added to subunit
Give AvDevice? reference to all deserialize functions (instead of
several arguments like config rom etc)

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