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

Revision 639, 23.1 kB (checked in by ppalmers, 17 years ago)

- Introduce a generic infrastructure for FFADODevices to present the clock sources they support and their state
- Implement this infrastructure for BeBoB devices
- Implement this infrastructure for ECHO Fireworks devices

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