root/trunk/libffado/src/genericavc/avc_avdevice.cpp

Revision 739, 22.8 kB (checked in by ppalmers, 13 years ago)

- Adapt the ffado external API (upgrade to v3)

NEEDS NEW JACK BACKEND

- simplify FFADODevice constructor even more
- implement first framework support for supporting multiple adapters.

currently all firewire adapters are scanned for supported devices unless specified otherwise
however attaching devices to separate adapters is not supported. using multiple adapters at
that are connected together might work.

Line 
1 /*
2  * Copyright (C) 2005-2007 by Pieter Palmers
3  * Copyright (C) 2005-2007 by Daniel Wagner
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License version 2.1, as published by the Free Software Foundation;
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22  * MA 02110-1301 USA
23  */
24
25 #include "genericavc/avc_avdevice.h"
26
27 #include "libieee1394/configrom.h"
28 #include "libieee1394/ieee1394service.h"
29
30 #include "libavc/avc_definitions.h"
31 #include "libavc/general/avc_plug_info.h"
32 #include "libavc/general/avc_extended_plug_info.h"
33
34 #include "debugmodule/debugmodule.h"
35
36 #include "config.h"
37
38 #include <string>
39 #include <stdint.h>
40 #include <assert.h>
41 #include <netinet/in.h>
42 #include <iostream>
43 #include <sstream>
44
45 #include <libraw1394/csr.h>
46
47 using namespace AVC;
48
49 namespace GenericAVC {
50
51 IMPL_DEBUG_MODULE( AvDevice, AvDevice, DEBUG_LEVEL_NORMAL );
52
53 AvDevice::AvDevice(std::auto_ptr<ConfigRom>( configRom ))
54     : FFADODevice( configRom )
55 {
56     debugOutput( DEBUG_LEVEL_VERBOSE, "Created GenericAVC::AvDevice (NodeID %d)\n",
57                  getConfigRom().getNodeId() );
58     addOption(Util::OptionContainer::Option("snoopMode",false));
59 }
60
61 bool
62 AvDevice::probe( ConfigRom& configRom )
63 {
64     unsigned int vendorId = configRom.getNodeVendorId();
65     unsigned int modelId = configRom.getModelId();
66
67     GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" );
68     if ( vendorModel.parse() ) {
69         return vendorModel.isPresent( vendorId, modelId );
70     }
71
72     return false;
73 }
74
75 FFADODevice *
76 AvDevice::createDevice(std::auto_ptr<ConfigRom>( configRom ))
77 {
78     return new AvDevice(configRom );
79 }
80
81 bool
82 AvDevice::discover()
83 {
84     // check if we already have a valid VendorModel entry
85     // e.g. because a subclass called this function
86     if (!GenericAVC::VendorModel::isValid(m_model)) {
87         unsigned int vendorId = getConfigRom().getNodeVendorId();
88         unsigned int modelId = getConfigRom().getModelId();
89
90         GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_genericavc.txt" );
91         if ( vendorModel.parse() ) {
92             m_model = vendorModel.find( vendorId, modelId );
93         }
94
95         if (!GenericAVC::VendorModel::isValid(m_model)) {
96             return false;
97         }
98         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
99                 m_model.vendor_name.c_str(), m_model.model_name.c_str());
100     }
101
102     if ( !Unit::discover() ) {
103         debugError( "Could not discover unit\n" );
104         return false;
105     }
106
107     if((getAudioSubunit( 0 ) == NULL)) {
108         debugError( "Unit doesn't have an Audio subunit.\n");
109         return false;
110     }
111     if((getMusicSubunit( 0 ) == NULL)) {
112         debugError( "Unit doesn't have a Music subunit.\n");
113         return false;
114     }
115
116     return true;
117 }
118
119 void
120 AvDevice::setVerboseLevel(int l)
121 {
122     setDebugLevel(l);
123     m_pPlugManager->setVerboseLevel(l);
124     FFADODevice::setVerboseLevel(l);
125     AVC::Unit::setVerboseLevel(l);
126     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
127 }
128
129 int
130 AvDevice::getSamplingFrequency( ) {
131     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
132     if ( !inputPlug ) {
133         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
134         return false;
135     }
136     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
137     if ( !outputPlug ) {
138         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
139         return false;
140     }
141
142     int samplerate_playback=inputPlug->getSampleRate();
143     int samplerate_capture=outputPlug->getSampleRate();
144
145     if (samplerate_playback != samplerate_capture) {
146         debugWarning("Samplerates for capture and playback differ!\n");
147     }
148     return samplerate_capture;
149 }
150
151 bool
152 AvDevice::setSamplingFrequency( int s )
153 {
154     bool snoopMode=false;
155     if(!getOption("snoopMode", snoopMode)) {
156         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
157     }
158
159     if(snoopMode) {
160         int current_sr=getSamplingFrequency();
161         if (current_sr != s ) {
162             debugError("In snoop mode it is impossible to set the sample rate.\n");
163             debugError("Please start the client with the correct setting.\n");
164             return false;
165         }
166         return true;
167     } else {
168         AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
169         if ( !plug ) {
170             debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
171             return false;
172         }
173
174         if ( !plug->setSampleRate( s ) )
175         {
176             debugError( "setSampleRate: Setting sample rate failed\n" );
177             return false;
178         }
179
180         plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output,  0 );
181         if ( !plug ) {
182             debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
183             return false;
184         }
185
186         if ( !plug->setSampleRate( s ) )
187         {
188             debugError( "setSampleRate: Setting sample rate failed\n" );
189             return false;
190         }
191
192         debugOutput( DEBUG_LEVEL_VERBOSE,
193                      "setSampleRate: Set sample rate to %d\n",
194                      s );
195         return true;
196     }
197     // not executable
198     return false;
199
200 }
201
202 FFADODevice::ClockSourceVector
203 AvDevice::getSupportedClockSources() {
204     FFADODevice::ClockSourceVector r;
205
206     PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType(
207         eST_Music,
208         0,
209         0xff,
210         0xff,
211         Plug::eAPA_SubunitPlug,
212         Plug::eAPD_Input,
213         Plug::eAPT_Sync );
214     if ( !syncMSUInputPlugs.size() ) {
215         debugWarning( "No sync input plug for MSU subunit found\n" );
216         return r;
217     }
218
219     for ( SyncInfoVector::const_iterator it
220               = getSyncInfos().begin();
221           it != getSyncInfos().end();
222           ++it )
223     {
224         const SyncInfo si=*it;
225
226         // check if the destination is a MSU input plug
227         bool found=false;
228         for ( PlugVector::const_iterator it2 = syncMSUInputPlugs.begin();
229               it2 != syncMSUInputPlugs.end();
230               ++it2 )
231         {
232             AVC::Plug* msuPlug = *it2;
233             found |= (msuPlug == si.m_destination);
234         }
235
236         if (found) {
237             ClockSource s=syncInfoToClockSource(*it);
238             r.push_back(s);
239         }
240     }
241
242     return r;
243 }
244
245 bool
246 AvDevice::setActiveClockSource(ClockSource s) {
247     Plug *src=m_pPlugManager->getPlug( s.id );
248     if (!src) {
249         debugError("Could not find plug with id %d\n", s.id);
250         return false;
251     }
252
253     for ( SyncInfoVector::const_iterator it
254               = getSyncInfos().begin();
255           it != getSyncInfos().end();
256           ++it )
257     {
258         const SyncInfo si=*it;
259
260         if (si.m_source==src) {
261             return setActiveSync(si);
262         }
263     }
264
265     return false;
266 }
267
268 FFADODevice::ClockSource
269 AvDevice::getActiveClockSource() {
270     const SyncInfo* si=getActiveSyncInfo();
271     if ( !si ) {
272         debugError( "Could not retrieve active sync information\n" );
273         ClockSource s;
274         s.type=eCT_Invalid;
275         return s;
276     }
277     debugOutput(DEBUG_LEVEL_VERBOSE, "Active Sync mode:  %s\n", si->m_description.c_str() );
278
279     return syncInfoToClockSource(*si);
280 }
281
282 FFADODevice::ClockSource
283 AvDevice::syncInfoToClockSource(const SyncInfo& si) {
284     ClockSource s;
285
286     // the description is easy
287     // it can be that we overwrite it later
288     s.description=si.m_description;
289
290     // FIXME: always valid at the moment
291     s.valid=true;
292
293     assert(si.m_source);
294     s.id=si.m_source->getGlobalId();
295
296     // now figure out what type this is
297     switch(si.m_source->getPlugType()) {
298         case Plug::eAPT_IsoStream:
299             s.type=eCT_SytMatch;
300             break;
301         case Plug::eAPT_Sync:
302             if(si.m_source->getPlugAddressType() == Plug::eAPA_PCR) {
303                 s.type=eCT_SytStream; // this is logical
304             } else if(si.m_source->getPlugAddressType() == Plug::eAPA_SubunitPlug) {
305                 s.type=eCT_Internal; // this assumes some stuff
306             } else if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) {
307                 std::string plugname=si.m_source->getName();
308                 s.description=plugname;
309                 // this is basically due to Focusrites interpretation
310                 if(plugname.find( "SPDIF", 0 ) != string::npos) {
311                     s.type=eCT_SPDIF; // this assumes the name will tell us
312                 } else {
313                     s.type=eCT_WordClock; // this assumes a whole lot more
314                 }
315             } else {
316                 s.type=eCT_Invalid;
317             }
318             break;
319         case Plug::eAPT_Digital:
320             if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) {
321                 std::string plugname=si.m_source->getName();
322                 s.description=plugname;
323                 // this is basically due to Focusrites interpretation
324                 if(plugname.find( "ADAT", 0 ) != string::npos) {
325                     s.type=eCT_ADAT; // this assumes the name will tell us
326                 } else if(plugname.find( "SPDIF", 0 ) != string::npos) {
327                     s.type=eCT_SPDIF; // this assumes the name will tell us
328                 } else {
329                     s.type=eCT_WordClock; // this assumes a whole lot more
330                 }
331             } else {
332                 s.type=eCT_Invalid;
333             }
334             break;
335         default:
336             s.type=eCT_Invalid; break;
337     }
338
339     // is it active?
340     const SyncInfo* active=getActiveSyncInfo();
341     if (active) {
342         if ((active->m_source == si.m_source)
343            && (active->m_destination == si.m_destination))
344            s.active=true;
345         else s.active=false;
346     } else s.active=false;
347
348     return s;
349 }
350
351 bool
352 AvDevice::lock() {
353     bool snoopMode=false;
354     if(!getOption("snoopMode", snoopMode)) {
355         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
356     }
357
358     if (snoopMode) {
359         // don't lock
360     } else {
361 //         return Unit::reserve(4);
362     }
363
364     return true;
365 }
366
367 bool
368 AvDevice::unlock() {
369     bool snoopMode=false;
370     if(!getOption("snoopMode", snoopMode)) {
371         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
372     }
373
374     if (snoopMode) {
375         // don't unlock
376     } else {
377 //         return Unit::reserve(0);
378     }
379     return true;
380 }
381
382 void
383 AvDevice::showDevice()
384 {
385     FFADODevice::showDevice();
386
387     debugOutput(DEBUG_LEVEL_NORMAL,
388         "%s %s\n", m_model.vendor_name.c_str(), m_model.model_name.c_str());
389
390     AVC::Unit::show();
391     flushDebugOutput();
392 }
393
394 bool
395 AvDevice::prepare() {
396     bool snoopMode=false;
397     if(!getOption("snoopMode", snoopMode)) {
398         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
399     }
400
401     ///////////
402     // get plugs
403
404     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
405     if ( !inputPlug ) {
406         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
407         return false;
408     }
409     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
410     if ( !outputPlug ) {
411         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
412         return false;
413     }
414
415     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
416     // create & add streamprocessors
417     Streaming::StreamProcessor *p;
418
419     if ( outputPlug->getNrOfChannels() == 0 ) {
420         debugError("Receive plug has no channels\n");
421         return false;
422     }
423     p=new Streaming::AmdtpReceiveStreamProcessor(
424                              get1394Service().getPort(),
425                              outputPlug->getNrOfChannels());
426
427     if(!p->init()) {
428         debugFatal("Could not initialize receive processor!\n");
429         delete p;
430         return false;
431     }
432
433     if (!addPlugToProcessor(*outputPlug,p,
434         Streaming::Port::E_Capture)) {
435         debugFatal("Could not add plug to processor!\n");
436         delete p;
437         return false;
438     }
439
440     m_receiveProcessors.push_back(p);
441
442     // do the transmit processor
443     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n",
444             (snoopMode?" in snoop mode":""));
445     if (snoopMode) {
446         // we are snooping, so this is receive too.
447         p=new Streaming::AmdtpReceiveStreamProcessor(
448                                   get1394Service().getPort(),
449                                   inputPlug->getNrOfChannels());
450     } else {
451         p=new Streaming::AmdtpTransmitStreamProcessor(
452                                 get1394Service().getPort(),
453                                 inputPlug->getNrOfChannels());
454     }
455
456     if(!p->init()) {
457         debugFatal("Could not initialize transmit processor %s!\n",
458             (snoopMode?" in snoop mode":""));
459         delete p;
460         return false;
461     }
462
463     if (snoopMode) {
464         if (!addPlugToProcessor(*inputPlug,p,
465             Streaming::Port::E_Capture)) {
466             debugFatal("Could not add plug to processor!\n");
467             return false;
468         }
469     } else {
470         if (!addPlugToProcessor(*inputPlug,p,
471             Streaming::Port::E_Playback)) {
472             debugFatal("Could not add plug to processor!\n");
473             return false;
474         }
475     }
476
477     // we put this SP into the transmit SP vector,
478     // no matter if we are in snoop mode or not
479     // this allows us to find out what direction
480     // a certain stream should have.
481     m_transmitProcessors.push_back(p);
482
483     return true;
484 }
485
486 bool
487 AvDevice::addPlugToProcessor(
488     AVC::Plug& plug,
489     Streaming::StreamProcessor *processor,
490     Streaming::AmdtpAudioPort::E_Direction direction) {
491
492     std::string id=std::string("dev?");
493     if(!getOption("id", id)) {
494         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
495     }
496
497     Plug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
498     for ( Plug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
499           it != clusterInfos.end();
500           ++it )
501     {
502         const Plug::ClusterInfo* clusterInfo = &( *it );
503
504         Plug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
505         for ( Plug::ChannelInfoVector::const_iterator it = channelInfos.begin();
506               it != channelInfos.end();
507               ++it )
508         {
509             const Plug::ChannelInfo* channelInfo = &( *it );
510             std::ostringstream portname;
511
512             portname << id << "_" << channelInfo->m_name;
513
514             Streaming::Port *p=NULL;
515             switch(clusterInfo->m_portType) {
516             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
517             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
518             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
519             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
520             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
521                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding audio channel %s (pos=0x%02X, loc=0x%02X)\n",
522                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
523                 p=new Streaming::AmdtpAudioPort(
524                         portname.str(),
525                         direction,
526                         channelInfo->m_streamPosition,
527                         channelInfo->m_location,
528                         Streaming::AmdtpPortInfo::E_MBLA
529                 );
530                 break;
531
532             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
533                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding MIDI channel %s (pos=0x%02X, loc=0x%02X)\n",
534                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi));
535                 p=new Streaming::AmdtpMidiPort(
536                         portname.str(),
537                         direction,
538                         channelInfo->m_streamPosition,
539                         // Workaround for out-of-spec hardware
540                         // should be:
541                         // channelInfo->m_location,
542                         // but now we renumber the midi channels' location as they
543                         // are discovered
544                         processor->getPortCount(Streaming::Port::E_Midi),
545                         Streaming::AmdtpPortInfo::E_Midi
546                 );
547
548                 break;
549             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
550             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
551             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
552             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
553             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
554                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding digital audio channel %s (pos=0x%02X, loc=0x%02X)\n",
555                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
556                 p=new Streaming::AmdtpAudioPort(
557                         portname.str(),
558                         direction,
559                         channelInfo->m_streamPosition,
560                         channelInfo->m_location,
561                         Streaming::AmdtpPortInfo::E_MBLA
562                 );
563                 break;
564
565             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
566             default:
567             // unsupported
568                 break;
569             }
570
571             if (!p) {
572                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
573             } else {
574
575                 if (!processor->addPort(p)) {
576                     debugWarning("Could not register port with stream processor\n");
577                     return false;
578                 }
579             }
580          }
581     }
582     return true;
583 }
584
585 int
586 AvDevice::getStreamCount() {
587     return m_receiveProcessors.size() + m_transmitProcessors.size();
588     //return 1;
589 }
590
591 Streaming::StreamProcessor *
592 AvDevice::getStreamProcessorByIndex(int i) {
593
594     if (i<(int)m_receiveProcessors.size()) {
595         return m_receiveProcessors.at(i);
596     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
597         return m_transmitProcessors.at(i-m_receiveProcessors.size());
598     }
599
600     return NULL;
601 }
602
603 bool
604 AvDevice::startStreamByIndex(int i) {
605     int iso_channel=-1;
606     bool snoopMode=false;
607     if(!getOption("snoopMode", snoopMode)) {
608         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
609     }
610
611     if (i<(int)m_receiveProcessors.size()) {
612         int n=i;
613         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
614
615         if(snoopMode) { // a stream from the device to another host
616             // FIXME: put this into a decent framework!
617             // we should check the oPCR[n] on the device
618             struct iec61883_oPCR opcr;
619             if (iec61883_get_oPCRX(
620                     get1394Service().getHandle(),
621                     getConfigRom().getNodeId() | 0xffc0,
622                     (quadlet_t *)&opcr,
623                     n)) {
624
625                 debugWarning("Error getting the channel for SP %d\n",i);
626                 return false;
627             }
628
629             iso_channel=opcr.channel;
630         } else {
631             iso_channel=get1394Service().allocateIsoChannelCMP(
632                 getConfigRom().getNodeId() | 0xffc0, n,
633                 get1394Service().getLocalNodeId()| 0xffc0, -1);
634         }
635         if (iso_channel<0) {
636             debugError("Could not allocate ISO channel for SP %d\n",i);
637             return false;
638         }
639
640         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
641
642         p->setChannel(iso_channel);
643         return true;
644
645     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
646         int n=i-m_receiveProcessors.size();
647         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
648
649         if(snoopMode) { // a stream from another host to the device
650             // FIXME: put this into a decent framework!
651             // we should check the iPCR[n] on the device
652             struct iec61883_iPCR ipcr;
653             if (iec61883_get_iPCRX(
654                     get1394Service().getHandle(),
655                     getConfigRom().getNodeId() | 0xffc0,
656                     (quadlet_t *)&ipcr,
657                     n)) {
658
659                 debugWarning("Error getting the channel for SP %d\n",i);
660                 return false;
661             }
662
663             iso_channel=ipcr.channel;
664
665         } else {
666             iso_channel=get1394Service().allocateIsoChannelCMP(
667                 get1394Service().getLocalNodeId()| 0xffc0, -1,
668                 getConfigRom().getNodeId() | 0xffc0, n);
669         }
670
671         if (iso_channel<0) {
672             debugError("Could not allocate ISO channel for SP %d\n",i);
673             return false;
674         }
675
676         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
677
678         p->setChannel(iso_channel);
679         return true;
680     }
681
682     debugError("SP index %d out of range!\n",i);
683     return false;
684 }
685
686 bool
687 AvDevice::stopStreamByIndex(int i) {
688     bool snoopMode=false;
689     if(!getOption("snoopMode", snoopMode)) {
690         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
691     }
692
693     if (i<(int)m_receiveProcessors.size()) {
694         int n=i;
695         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
696
697         if(snoopMode) {
698
699         } else {
700             // deallocate ISO channel
701             if(!get1394Service().freeIsoChannel(p->getChannel())) {
702                 debugError("Could not deallocate iso channel for SP %d\n",i);
703                 return false;
704             }
705         }
706         p->setChannel(-1);
707
708         return true;
709
710     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
711         int n=i-m_receiveProcessors.size();
712         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
713
714         if(snoopMode) {
715
716         } else {
717             // deallocate ISO channel
718             if(!get1394Service().freeIsoChannel(p->getChannel())) {
719                 debugError("Could not deallocate iso channel for SP %d\n",i);
720                 return false;
721             }
722         }
723         p->setChannel(-1);
724
725         return true;
726     }
727
728     debugError("SP index %d out of range!\n",i);
729     return false;
730 }
731
732 bool
733 AvDevice::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const
734 {
735     bool result;
736     result  = AVC::Unit::serialize( basePath, ser );
737     result &= serializeOptions( basePath + "Options", ser );
738     return result;
739 }
740
741 bool
742 AvDevice::deserialize( Glib::ustring basePath, Util::IODeserialize& deser )
743 {
744     bool result;
745     result = AVC::Unit::deserialize( basePath, deser );
746     return result;
747 }
748
749 }
Note: See TracBrowser for help on using the browser.