root/branches/echoaudio/src/bebob/bebob_avdevice.cpp

Revision 543, 27.6 kB (checked in by ppalmers, 17 years ago)

- some cosmetic changes
- struggle with the indexing of bebob channels
- reimplement propagateClusterInfos to make sure it doesn't do anything

Line 
1 /*
2  * Copyright (C) 2005-2007 by Daniel Wagner
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #include "bebob/bebob_avdevice.h"
25 #include "bebob/bebob_avdevice_subunit.h"
26 #include "bebob/GenericMixer.h"
27
28 #include "libieee1394/configrom.h"
29 #include "libieee1394/ieee1394service.h"
30
31 #include "libavc/general/avc_plug_info.h"
32 #include "libavc/general/avc_extended_plug_info.h"
33 #include "libavc/general/avc_subunit_info.h"
34 #include "libavc/streamformat/avc_extended_stream_format.h"
35 #include "libavc/util/avc_serialize.h"
36 #include "libavc/avc_definitions.h"
37
38 #include "debugmodule/debugmodule.h"
39
40 #include <iostream>
41 #include <sstream>
42
43 using namespace AVC;
44
45 namespace BeBoB {
46
47 IMPL_DEBUG_MODULE( AvDevice, AvDevice, DEBUG_LEVEL_VERBOSE );
48
49 static VendorModelEntry supportedDeviceList[] =
50 {
51     {0x00000f, 0x00010065, "Mackie", "Onyx Firewire"},
52
53     {0x0003db, 0x00010048, "Apogee Electronics", "Rosetta 200"},
54
55     {0x0007f5, 0x00010048, "BridgeCo", "RD Audio1"},
56
57     {0x000a92, 0x00010000, "PreSonus", "FIREBOX"},
58     {0x000a92, 0x00010066, "PreSonus", "FirePOD"},
59
60     {0x000aac, 0x00000003, "TerraTec Electronic GmbH", "Phase 88 FW"},
61     {0x000aac, 0x00000004, "TerraTec Electronic GmbH", "Phase X24 FW (model version 4)"},
62     {0x000aac, 0x00000007, "TerraTec Electronic GmbH", "Phase X24 FW (model version 7)"},
63
64     {0x000f1b, 0x00010064, "ESI", "Quatafire 610"},
65
66     {0x00130e, 0x00000003, "Focusrite", "Saffire Pro26IO"},
67     {0x00130e, 0x00000006, "Focusrite", "Saffire Pro10IO"},
68
69     {0x0040ab, 0x00010048, "EDIROL", "FA-101"},
70     {0x0040ab, 0x00010049, "EDIROL", "FA-66"},
71 };
72
73 AvDevice::AvDevice( std::auto_ptr< ConfigRom >( configRom ),
74                     Ieee1394Service& ieee1394service,
75                     int nodeId )
76     : FFADODevice( configRom, ieee1394service, nodeId )
77     , AVC::Unit( )
78     , m_model ( NULL )
79     , m_Mixer ( NULL )
80 {
81     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::AvDevice (NodeID %d)\n",
82                  nodeId );
83     addOption(Util::OptionContainer::Option("snoopMode",false));
84 }
85
86 AvDevice::~AvDevice()
87 {
88     if(m_Mixer != NULL) {
89         if (!removeChildOscNode(m_Mixer)) {
90             debugWarning("failed to unregister mixer from OSC namespace\n");
91         }
92         delete m_Mixer;
93     }
94 }
95
96 AVC::Subunit*
97 BeBoB::AvDevice::createSubunit(AVC::Unit& unit,
98                                AVC::ESubunitType type,
99                                AVC::subunit_t id )
100 {
101     switch (type) {
102         case AVC::eST_Audio:
103             return new BeBoB::SubunitAudio(unit, id );
104         case AVC::eST_Music:
105             return new BeBoB::SubunitMusic(unit, id );
106         default:
107             return NULL;
108     }
109 }
110
111 AVC::Plug *
112 BeBoB::AvDevice::createPlug( AVC::Unit* unit,
113                      AVC::Subunit* subunit,
114                      AVC::function_block_type_t functionBlockType,
115                      AVC::function_block_type_t functionBlockId,
116                      AVC::Plug::EPlugAddressType plugAddressType,
117                      AVC::Plug::EPlugDirection plugDirection,
118                      AVC::plug_id_t plugId )
119 {
120
121     return new BeBoB::Plug( unit,
122                      subunit,
123                      functionBlockType,
124                      functionBlockId,
125                      plugAddressType,
126                      plugDirection,
127                      plugId );
128 }
129
130 void
131 AvDevice::setVerboseLevel(int l)
132 {
133     m_pPlugManager->setVerboseLevel(l);
134
135     FFADODevice::setVerboseLevel(l);
136     AVC::Unit::setVerboseLevel(l);
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     return false;
156 }
157
158 bool
159 AvDevice::discover()
160 {
161     unsigned int vendorId = m_pConfigRom->getNodeVendorId();
162     unsigned int modelId = m_pConfigRom->getModelId();
163
164     for ( unsigned int i = 0;
165           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
166           ++i )
167     {
168         if ( ( supportedDeviceList[i].vendor_id == vendorId )
169              && ( supportedDeviceList[i].model_id == modelId )
170            )
171         {
172             m_model = &(supportedDeviceList[i]);
173             break;
174         }
175     }
176
177     if (m_model != NULL) {
178         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
179                 m_model->vendor_name, m_model->model_name);
180     } else return false;
181
182     if ( !Unit::discover() ) {
183         debugError( "Could not discover unit\n" );
184         return false;
185     }
186
187     if((getAudioSubunit( 0 ) == NULL)) {
188         debugError( "Unit doesn't have an Audio subunit.\n");
189         return false;
190     }
191     if((getMusicSubunit( 0 ) == NULL)) {
192         debugError( "Unit doesn't have a Music subunit.\n");
193         return false;
194     }
195
196 // replaced by the previous Unit discovery
197 //     if ( !enumerateSubUnits() ) {
198 //         debugError( "Could not enumarate sub units\n" );
199 //         return false;
200 //     }
201
202     // create a GenericMixer and add it as an OSC child node
203     //  remove if already there
204     if(m_Mixer != NULL) {
205         if (!removeChildOscNode(m_Mixer)) {
206             debugWarning("failed to unregister mixer from OSC namespace\n");
207         }
208         delete m_Mixer;
209     }
210    
211     //  create the mixer & register it
212     if(getAudioSubunit(0) == NULL) {
213         debugWarning("Could not find audio subunit, mixer not available.\n");
214         m_Mixer = NULL;
215     } else {
216         m_Mixer = new GenericMixer(*m_p1394Service , *this);
217         if (!addChildOscNode(m_Mixer)) {
218             debugWarning("failed to register mixer in OSC namespace\n");
219         }
220     }
221     return true;
222 }
223
224 bool
225 AvDevice::setSamplingFrequency( int s )
226 {
227     ESamplingFrequency samplingFrequency=parseSampleRate( s );
228     bool snoopMode=false;
229     if(!getOption("snoopMode", snoopMode)) {
230         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
231     }
232
233     if(snoopMode) {
234         int current_sr=getSamplingFrequency();
235         if (current_sr != convertESamplingFrequency( samplingFrequency ) ) {
236             debugError("In snoop mode it is impossible to set the sample rate.\n");
237             debugError("Please start the client with the correct setting.\n");
238             return false;
239         }
240         return true;
241     } else {
242         AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
243         if ( !plug ) {
244             debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
245             return false;
246         }
247
248         if ( !setSamplingFrequencyPlug( *plug,
249                                         Plug::eAPD_Input,
250                                         samplingFrequency ) )
251         {
252             debugError( "setSampleRate: Setting sample rate failed\n" );
253             return false;
254         }
255
256         plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output,  0 );
257         if ( !plug ) {
258             debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
259             return false;
260         }
261
262         if ( !setSamplingFrequencyPlug( *plug,
263                                         Plug::eAPD_Output,
264                                         samplingFrequency ) )
265         {
266             debugError( "setSampleRate: Setting sample rate failed\n" );
267             return false;
268         }
269
270         debugOutput( DEBUG_LEVEL_VERBOSE,
271                      "setSampleRate: Set sample rate to %d\n",
272                      convertESamplingFrequency( samplingFrequency ) );
273         return true;
274     }
275     // not executable
276     return false;
277 }
278
279 int
280 AvDevice::getSamplingFrequency( ) {
281     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
282     if ( !inputPlug ) {
283         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
284         return false;
285     }
286     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
287     if ( !outputPlug ) {
288         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
289         return false;
290     }
291
292     int samplerate_playback=inputPlug->getSampleRate();
293     int samplerate_capture=outputPlug->getSampleRate();
294
295     if (samplerate_playback != samplerate_capture) {
296         debugWarning("Samplerates for capture and playback differ!\n");
297     }
298     return samplerate_capture;
299 }
300
301
302 bool
303 AvDevice::setSamplingFrequencyPlug( AVC::Plug& plug,
304                                     Plug::EPlugDirection direction,
305                                     ESamplingFrequency samplingFrequency )
306 {
307
308     ExtendedStreamFormatCmd extStreamFormatCmd(
309         *m_p1394Service,
310         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList );
311     UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
312                                      plug.getPlugId() );
313
314     extStreamFormatCmd.setPlugAddress(
315         PlugAddress(
316             Plug::convertPlugDirection(direction ),
317             PlugAddress::ePAM_Unit,
318             unitPlugAddress ) );
319
320     extStreamFormatCmd.setNodeId( m_pConfigRom->getNodeId() );
321     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
322
323     int i = 0;
324     bool cmdSuccess = false;
325     bool correctFormatFound = false;
326
327     do {
328         extStreamFormatCmd.setIndexInStreamFormat( i );
329         extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
330         extStreamFormatCmd.setVerbose( m_verboseLevel );
331
332         cmdSuccess = extStreamFormatCmd.fire();
333
334         if ( cmdSuccess
335              && ( extStreamFormatCmd.getResponse() ==
336                   AVCCommand::eR_Implemented ) )
337         {
338             ESamplingFrequency foundFreq = eSF_DontCare;
339
340             FormatInformation* formatInfo =
341                 extStreamFormatCmd.getFormatInformation();
342             FormatInformationStreamsCompound* compoundStream
343                 = dynamic_cast< FormatInformationStreamsCompound* > (
344                     formatInfo->m_streams );
345             if ( compoundStream ) {
346                 foundFreq =
347                     static_cast< ESamplingFrequency >(
348                         compoundStream->m_samplingFrequency );
349             }
350
351             FormatInformationStreamsSync* syncStream
352                 = dynamic_cast< FormatInformationStreamsSync* > (
353                     formatInfo->m_streams );
354             if ( syncStream ) {
355                 foundFreq =
356                     static_cast< ESamplingFrequency >(
357                         syncStream->m_samplingFrequency );
358             }
359
360             if ( foundFreq == samplingFrequency )
361             {
362                 correctFormatFound = true;
363                 break;
364             }
365         }
366
367         ++i;
368     } while ( cmdSuccess
369               && ( extStreamFormatCmd.getResponse() ==
370                    ExtendedStreamFormatCmd::eR_Implemented ) );
371
372     if ( !cmdSuccess ) {
373         debugError( "setSampleRatePlug: Failed to retrieve format info\n" );
374         return false;
375     }
376
377     if ( !correctFormatFound ) {
378         debugError( "setSampleRatePlug: %s plug %d does not support "
379                     "sample rate %d\n",
380                     plug.getName(),
381                     plug.getPlugId(),
382                     convertESamplingFrequency( samplingFrequency ) );
383         return false;
384     }
385
386     extStreamFormatCmd.setSubFunction(
387         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand );
388     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Control );
389     extStreamFormatCmd.setVerbose( m_verboseLevel );
390
391     if ( !extStreamFormatCmd.fire() ) {
392         debugError( "setSampleRate: Could not set sample rate %d "
393                     "to %s plug %d\n",
394                     convertESamplingFrequency( samplingFrequency ),
395                     plug.getName(),
396                     plug.getPlugId() );
397         return false;
398     }
399
400     return true;
401 }
402
403 void
404 AvDevice::showDevice()
405 {
406     debugOutput(DEBUG_LEVEL_VERBOSE,
407         "%s %s at node %d\n", m_model->vendor_name, m_model->model_name,
408         m_nodeId);
409
410     m_pPlugManager->showPlugs();
411     flushDebugOutput();
412 }
413
414
415 bool
416 AvDevice::lock() {
417     bool snoopMode=false;
418     if(!getOption("snoopMode", snoopMode)) {
419         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
420     }
421
422     if (snoopMode) {
423         // don't lock
424     } else {
425 //         return Unit::reserve(4);
426     }
427
428     return true;
429 }
430
431 bool
432 AvDevice::unlock() {
433     bool snoopMode=false;
434     if(!getOption("snoopMode", snoopMode)) {
435         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
436     }
437
438     if (snoopMode) {
439         // don't unlock
440     } else {
441 //         return Unit::reserve(0);
442     }
443     return true;
444 }
445
446 bool
447 AvDevice::prepare() {
448     bool snoopMode=false;
449     if(!getOption("snoopMode", snoopMode)) {
450         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
451     }
452
453     ///////////
454     // get plugs
455
456     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
457     if ( !inputPlug ) {
458         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
459         return false;
460     }
461     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
462     if ( !outputPlug ) {
463         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
464         return false;
465     }
466
467     int samplerate=outputPlug->getSampleRate();
468
469     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
470     // create & add streamprocessors
471     Streaming::StreamProcessor *p;
472
473     p=new Streaming::AmdtpReceiveStreamProcessor(
474                              m_p1394Service->getPort(),
475                              samplerate,
476                              outputPlug->getNrOfChannels());
477
478     if(!p->init()) {
479         debugFatal("Could not initialize receive processor!\n");
480         delete p;
481         return false;
482     }
483
484     if (!addPlugToProcessor(*outputPlug,p,
485         Streaming::Port::E_Capture)) {
486         debugFatal("Could not add plug to processor!\n");
487         delete p;
488         return false;
489     }
490
491     m_receiveProcessors.push_back(p);
492
493     // do the transmit processor
494     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n",
495             (snoopMode?" in snoop mode":""));
496     if (snoopMode) {
497         // we are snooping, so this is receive too.
498         p=new Streaming::AmdtpReceiveStreamProcessor(
499                                   m_p1394Service->getPort(),
500                                   samplerate,
501                                   inputPlug->getNrOfChannels());
502     } else {
503         p=new Streaming::AmdtpTransmitStreamProcessor(
504                                 m_p1394Service->getPort(),
505                                 samplerate,
506                                 inputPlug->getNrOfChannels());
507     }
508
509     if(!p->init()) {
510         debugFatal("Could not initialize transmit processor %s!\n",
511             (snoopMode?" in snoop mode":""));
512         delete p;
513         return false;
514     }
515
516     if (snoopMode) {
517         if (!addPlugToProcessor(*inputPlug,p,
518             Streaming::Port::E_Capture)) {
519             debugFatal("Could not add plug to processor!\n");
520             return false;
521         }
522     } else {
523         if (!addPlugToProcessor(*inputPlug,p,
524             Streaming::Port::E_Playback)) {
525             debugFatal("Could not add plug to processor!\n");
526             return false;
527         }
528     }
529
530     // we put this SP into the transmit SP vector,
531     // no matter if we are in snoop mode or not
532     // this allows us to find out what direction
533     // a certain stream should have.
534     m_transmitProcessors.push_back(p);
535
536     return true;
537 }
538
539 bool
540 AvDevice::addPlugToProcessor(
541     AVC::Plug& plug,
542     Streaming::StreamProcessor *processor,
543     Streaming::AmdtpAudioPort::E_Direction direction) {
544
545     std::string id=std::string("dev?");
546     if(!getOption("id", id)) {
547         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
548     }
549
550     Plug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
551     for ( Plug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
552           it != clusterInfos.end();
553           ++it )
554     {
555         const Plug::ClusterInfo* clusterInfo = &( *it );
556
557         Plug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
558         for ( Plug::ChannelInfoVector::const_iterator it = channelInfos.begin();
559               it != channelInfos.end();
560               ++it )
561         {
562             const Plug::ChannelInfo* channelInfo = &( *it );
563             std::ostringstream portname;
564
565             portname << id << "_" << channelInfo->m_name;
566
567             Streaming::Port *p=NULL;
568             switch(clusterInfo->m_portType) {
569             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
570             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
571             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
572             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
573             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
574                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding audio channel %s (pos=0x%02X, loc=0x%02X)\n",
575                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition-1, channelInfo->m_location-1);
576                 p=new Streaming::AmdtpAudioPort(
577                         portname.str(),
578                         direction,
579                         // \todo: streaming backend expects indexing starting from 0
580                         // but bebob reports it starting from 1. Decide where
581                         // and how to handle this (pp: here)
582                         // note that the descriptor mechanism specifies indexing from 0
583                         channelInfo->m_streamPosition-1,
584                         channelInfo->m_location - 1,
585                         Streaming::AmdtpPortInfo::E_MBLA
586                 );
587                 break;
588
589             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
590                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding MIDI channel %s (pos=0x%02X, loc=0x%02X)\n",
591                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition-1, processor->getPortCount(Streaming::Port::E_Midi));
592                 p=new Streaming::AmdtpMidiPort(
593                         portname.str(),
594                         direction,
595                         channelInfo->m_streamPosition-1,
596                         // Workaround for out-of-spec hardware
597                         // should be:
598                         // channelInfo->m_location-1,
599                         // but now we renumber the midi channels' location as they
600                         // are discovered
601                         processor->getPortCount(Streaming::Port::E_Midi),
602                         Streaming::AmdtpPortInfo::E_Midi
603                 );
604
605                 break;
606             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
607             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
608             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
609             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
610             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
611             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
612             default:
613             // unsupported
614                 break;
615             }
616
617             if (!p) {
618                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
619             } else {
620
621                 if (!processor->addPort(p)) {
622                     debugWarning("Could not register port with stream processor\n");
623                     return false;
624                 }
625             }
626          }
627     }
628     return true;
629 }
630
631 int
632 AvDevice::getStreamCount() {
633     return m_receiveProcessors.size() + m_transmitProcessors.size();
634 }
635
636 Streaming::StreamProcessor *
637 AvDevice::getStreamProcessorByIndex(int i) {
638
639     if (i<(int)m_receiveProcessors.size()) {
640         return m_receiveProcessors.at(i);
641     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
642         return m_transmitProcessors.at(i-m_receiveProcessors.size());
643     }
644
645     return NULL;
646 }
647
648 bool
649 AvDevice::startStreamByIndex(int i) {
650     int iso_channel=-1;
651     bool snoopMode=false;
652     if(!getOption("snoopMode", snoopMode)) {
653         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
654     }
655
656     if (i<(int)m_receiveProcessors.size()) {
657         int n=i;
658         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
659
660         if(snoopMode) { // a stream from the device to another host
661             // FIXME: put this into a decent framework!
662             // we should check the oPCR[n] on the device
663             struct iec61883_oPCR opcr;
664             if (iec61883_get_oPCRX(
665                     m_p1394Service->getHandle(),
666                     m_pConfigRom->getNodeId() | 0xffc0,
667                     (quadlet_t *)&opcr,
668                     n)) {
669
670                 debugWarning("Error getting the channel for SP %d\n",i);
671                 return false;
672             }
673
674             iso_channel=opcr.channel;
675         } else {
676             iso_channel=m_p1394Service->allocateIsoChannelCMP(
677                 m_pConfigRom->getNodeId() | 0xffc0, n,
678                 m_p1394Service->getLocalNodeId()| 0xffc0, -1);
679         }
680         if (iso_channel<0) {
681             debugError("Could not allocate ISO channel for SP %d\n",i);
682             return false;
683         }
684
685         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
686
687         p->setChannel(iso_channel);
688         return true;
689
690     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
691         int n=i-m_receiveProcessors.size();
692         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
693
694         if(snoopMode) { // a stream from another host to the device
695             // FIXME: put this into a decent framework!
696             // we should check the iPCR[n] on the device
697             struct iec61883_iPCR ipcr;
698             if (iec61883_get_iPCRX(
699                     m_p1394Service->getHandle(),
700                     m_pConfigRom->getNodeId() | 0xffc0,
701                     (quadlet_t *)&ipcr,
702                     n)) {
703
704                 debugWarning("Error getting the channel for SP %d\n",i);
705                 return false;
706             }
707
708             iso_channel=ipcr.channel;
709
710         } else {
711             iso_channel=m_p1394Service->allocateIsoChannelCMP(
712                 m_p1394Service->getLocalNodeId()| 0xffc0, -1,
713                 m_pConfigRom->getNodeId() | 0xffc0, n);
714         }
715
716         if (iso_channel<0) {
717             debugError("Could not allocate ISO channel for SP %d\n",i);
718             return false;
719         }
720
721         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
722
723         p->setChannel(iso_channel);
724         return true;
725     }
726
727     debugError("SP index %d out of range!\n",i);
728     return false;
729 }
730
731 bool
732 AvDevice::stopStreamByIndex(int i) {
733     bool snoopMode=false;
734     if(!getOption("snoopMode", snoopMode)) {
735         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
736     }
737
738     if (i<(int)m_receiveProcessors.size()) {
739         int n=i;
740         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
741
742         if(snoopMode) {
743
744         } else {
745             // deallocate ISO channel
746             if(!m_p1394Service->freeIsoChannel(p->getChannel())) {
747                 debugError("Could not deallocate iso channel for SP %d\n",i);
748                 return false;
749             }
750         }
751         p->setChannel(-1);
752
753         return true;
754
755     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
756         int n=i-m_receiveProcessors.size();
757         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
758
759         if(snoopMode) {
760
761         } else {
762             // deallocate ISO channel
763             if(!m_p1394Service->freeIsoChannel(p->getChannel())) {
764                 debugError("Could not deallocate iso channel for SP %d\n",i);
765                 return false;
766             }
767         }
768         p->setChannel(-1);
769
770         return true;
771     }
772
773     debugError("SP index %d out of range!\n",i);
774     return false;
775 }
776
777 template <typename T> bool serializeVector( Glib::ustring path,
778                                             Util::IOSerialize& ser,
779                                             const T& vec )
780 {
781     bool result = true; // if vec.size() == 0
782     int i = 0;
783     for ( typename T::const_iterator it = vec.begin(); it != vec.end(); ++it ) {
784         std::ostringstream strstrm;
785         strstrm << path << i;
786         result &= ( *it )->serialize( strstrm.str() + "/", ser );
787         i++;
788     }
789     return result;
790 }
791
792 template <typename T, typename VT> bool deserializeVector( Glib::ustring path,
793                                                            Util::IODeserialize& deser,
794                                                            Unit& avDevice,
795                                                            VT& vec )
796 {
797     int i = 0;
798     bool bFinished = false;
799     do {
800         std::ostringstream strstrm;
801         strstrm << path << i << "/";
802         T* ptr = T::deserialize( strstrm.str(),
803                                  deser,
804                                  avDevice );
805         if ( ptr ) {
806             vec.push_back( ptr );
807             i++;
808         } else {
809             bFinished = true;
810         }
811     } while ( !bFinished );
812
813     return true;
814 }
815
816 bool
817 AvDevice::serialize( Glib::ustring basePath,
818                      Util::IOSerialize& ser ) const
819 {
820
821     bool result;
822     result  = m_pConfigRom->serialize( basePath + "m_pConfigRom/", ser );
823     result &= ser.write( basePath + "m_verboseLevel", getDebugLevel() );
824     result &= m_pPlugManager->serialize( basePath + "Plug", ser ); // serialize all av plugs
825     result &= serializeVector( basePath + "PlugConnection", ser, m_plugConnections );
826     result &= serializeVector( basePath + "Subunit", ser, m_subunits );
827     result &= serializeSyncInfoVector( basePath + "SyncInfo", ser, m_syncInfos );
828
829     int i = 0;
830     for ( SyncInfoVector::const_iterator it = m_syncInfos.begin();
831           it != m_syncInfos.end();
832           ++it )
833     {
834         const SyncInfo& info = *it;
835         if ( m_activeSyncInfo == &info ) {
836             result &= ser.write( basePath + "m_activeSyncInfo",  i );
837             break;
838         }
839         i++;
840     }
841
842     result &= serializeOptions( basePath + "Options", ser );
843
844 //     result &= ser.write( basePath + "m_id", id );
845
846     return result;
847 }
848
849 AvDevice*
850 AvDevice::deserialize( Glib::ustring basePath,
851                        Util::IODeserialize& deser,
852                        Ieee1394Service& ieee1394Service )
853 {
854
855     ConfigRom *configRom =
856         ConfigRom::deserialize( basePath + "m_pConfigRom/", deser, ieee1394Service );
857
858     if ( !configRom ) {
859         return NULL;
860     }
861
862     AvDevice* pDev = new AvDevice(
863         std::auto_ptr<ConfigRom>(configRom),
864         ieee1394Service, configRom->getNodeId());
865
866     if ( pDev ) {
867         bool result;
868         int verboseLevel;
869         result  = deser.read( basePath + "m_verboseLevel", verboseLevel );
870         setDebugLevel( verboseLevel );
871        
872         result &= AVC::Unit::deserialize(basePath, pDev, deser, ieee1394Service);
873
874         result &= deserializeOptions( basePath + "Options", deser, *pDev );
875     }
876
877     return pDev;
878 }
879
880 } // end of namespace
Note: See TracBrowser for help on using the browser.