root/branches/libffado-2.0/src/genericavc/avc_avdevice.cpp

Revision 1385, 27.4 kB (checked in by ppalmers, 12 years ago)

Implement a mechanism to disable the samplerate and clock source controls while the device is streaming in order to avoid changes that could mess up jack. The saffire pro controls that cause a device reset to
happen are also disabled while streaming is active.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  * Copyright (C) 2005-2008 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 program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include "devicemanager.h"
26 #include "genericavc/avc_avdevice.h"
27
28 #include "libieee1394/configrom.h"
29 #include "libieee1394/ieee1394service.h"
30
31 #include "libavc/avc_definitions.h"
32 #include "libavc/general/avc_plug_info.h"
33 #include "libavc/general/avc_extended_plug_info.h"
34 #include "libavc/general/avc_subunit_info.h"
35
36 #include "debugmodule/debugmodule.h"
37
38 #include <string>
39 #include <stdint.h>
40 #include <assert.h>
41 #include "libutil/ByteSwap.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( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
54     : FFADODevice( d, 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 AvDevice::~AvDevice()
62 {
63     for ( StreamProcessorVectorIterator it = m_receiveProcessors.begin();
64           it != m_receiveProcessors.end();
65           ++it )
66     {
67         delete *it;
68     }
69     for ( StreamProcessorVectorIterator it = m_transmitProcessors.begin();
70           it != m_transmitProcessors.end();
71           ++it )
72     {
73         delete *it;
74     }
75 }
76
77 bool
78 AvDevice::probe( Util::Configuration& c, ConfigRom& configRom, bool generic )
79 {
80     if(generic) {
81         // check if we have a music subunit
82         SubUnitInfoCmd subUnitInfoCmd( configRom.get1394Service() );
83         subUnitInfoCmd.setCommandType( AVCCommand::eCT_Status );
84         subUnitInfoCmd.m_page = 0;
85         subUnitInfoCmd.setNodeId( configRom.getNodeId() );
86         subUnitInfoCmd.setVerbose( configRom.getVerboseLevel() );
87         if ( !subUnitInfoCmd.fire() ) {
88             debugError( "Subunit info command failed\n" );
89             return false;
90         }
91         for ( int i = 0; i < subUnitInfoCmd.getNrOfValidEntries(); ++i ) {
92             subunit_type_t subunit_type
93                 = subUnitInfoCmd.m_table[i].m_subunit_type;
94             if (subunit_type == eST_Music) return true;
95         }
96
97         return false;
98     } else {
99         // check if device is in supported devices list
100         unsigned int vendorId = configRom.getNodeVendorId();
101         unsigned int modelId = configRom.getModelId();
102
103         Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
104         return c.isValid(vme) && vme.driver == Util::Configuration::eD_GenericAVC;
105         return false;
106     }
107 }
108
109 FFADODevice *
110 AvDevice::createDevice(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
111 {
112     return new AvDevice(d, configRom );
113 }
114
115 bool
116 AvDevice::discover()
117 {
118     Util::MutexLockHelper lock(m_DeviceMutex);
119
120     unsigned int vendorId = getConfigRom().getNodeVendorId();
121     unsigned int modelId = getConfigRom().getModelId();
122
123     Util::Configuration &c = getDeviceManager().getConfiguration();
124     Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
125
126     if (c.isValid(vme) && vme.driver == Util::Configuration::eD_GenericAVC) {
127         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
128                      vme.vendor_name.c_str(),
129                      vme.model_name.c_str());
130     } else {
131         debugWarning("Using generic AV/C support for unsupported device '%s %s'\n",
132                      getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
133     }
134     return discoverGeneric();
135 }
136
137 bool
138 AvDevice::discoverGeneric()
139 {
140     if ( !Unit::discover() ) {
141         debugError( "Could not discover unit\n" );
142         return false;
143     }
144
145     if((getAudioSubunit( 0 ) == NULL)) {
146         debugError( "Unit doesn't have an Audio subunit.\n");
147         return false;
148     }
149     if((getMusicSubunit( 0 ) == NULL)) {
150         debugError( "Unit doesn't have a Music subunit.\n");
151         return false;
152     }
153     return true;
154 }
155
156 void
157 AvDevice::setVerboseLevel(int l)
158 {
159     Util::MutexLockHelper lock(m_DeviceMutex);
160     setDebugLevel(l);
161     m_pPlugManager->setVerboseLevel(l);
162     FFADODevice::setVerboseLevel(l);
163     AVC::Unit::setVerboseLevel(l);
164     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
165 }
166
167 #include <libieee1394/IEC61883.h>
168 enum FFADODevice::eStreamingState
169 AvDevice::getStreamingState()
170 {
171     // check the IEC plug control registers to see if the device is streaming
172     // a bit of a hack, but will do until we come up with something better
173     struct iec61883_oPCR oPCR0;
174     struct iec61883_iPCR iPCR0;
175    
176     quadlet_t *oPCR0q = (quadlet_t *)&oPCR0;
177     quadlet_t *iPCR0q = (quadlet_t *)&iPCR0;
178    
179     if(!get1394Service().read(getNodeId() | 0xFFC0, CSR_REGISTER_BASE + CSR_O_PCR_0, 1, oPCR0q)) {
180         debugWarning("Could not read oPCR0 register\n");
181     }
182     if(!get1394Service().read(getNodeId() | 0xFFC0, CSR_REGISTER_BASE + CSR_I_PCR_0, 1, iPCR0q)) {
183         debugWarning("Could not read iPCR0 register\n");
184     }
185
186     *oPCR0q = CondSwapFromBus32(*oPCR0q);
187     *iPCR0q = CondSwapFromBus32(*iPCR0q);
188
189     debugOutput(DEBUG_LEVEL_VERBOSE, "iPCR0: %08X, oPCR0: %08X\n", *iPCR0q, *oPCR0q);
190
191     if(iPCR0.n_p2p_connections > 0 && oPCR0.n_p2p_connections > 0) {
192         return eSS_Both;
193     } else if (iPCR0.n_p2p_connections > 0) {
194         return eSS_Receiving;
195     } else if (oPCR0.n_p2p_connections > 0) {
196         return eSS_Sending;
197     } else {
198         return eSS_Idle;
199     }
200 }
201
202 int
203 AvDevice::getSamplingFrequency( ) {
204     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
205     if ( !inputPlug ) {
206         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
207         return false;
208     }
209     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
210     if ( !outputPlug ) {
211         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
212         return false;
213     }
214
215     int samplerate_playback=inputPlug->getSampleRate();
216     int samplerate_capture=outputPlug->getSampleRate();
217
218     if (samplerate_playback != samplerate_capture) {
219         debugWarning("Samplerates for capture and playback differ!\n");
220     }
221     return samplerate_capture;
222 }
223
224 bool
225 AvDevice::setSamplingFrequency( int s )
226 {
227     Util::MutexLockHelper lock(m_DeviceMutex);
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 != s ) {
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 ( !plug->setSampleRate( s ) )
249         {
250             debugError( "setSampleRate: Setting sample rate failed\n" );
251             return false;
252         }
253
254         plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output,  0 );
255         if ( !plug ) {
256             debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
257             return false;
258         }
259
260         if ( !plug->setSampleRate( s ) )
261         {
262             debugError( "setSampleRate: Setting sample rate failed\n" );
263             return false;
264         }
265
266         debugOutput( DEBUG_LEVEL_VERBOSE,
267                      "setSampleRate: Set sample rate to %d\n",
268                      s );
269         return true;
270     }
271     // not executable
272     return false;
273
274 }
275
276 bool
277 AvDevice::supportsSamplingFrequency( int s )
278 {
279     Util::MutexLockHelper lock(m_DeviceMutex);
280
281     AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
282     if ( !plug ) {
283         debugError( "Could not retrieve iso input plug 0\n" );
284         return false;
285     }
286
287     if ( !plug->supportsSampleRate( s ) )
288     {
289         debugError( "sample rate not supported by input plug\n" );
290         return false;
291     }
292
293     plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output,  0 );
294     if ( !plug ) {
295         debugError( "Could not retrieve iso output plug 0\n" );
296         return false;
297     }
298
299     if ( !plug->supportsSampleRate( s ) )
300     {
301         debugError( "sample rate not supported by output plug\n" );
302         return false;
303     }
304     return true;
305 }
306
307 #define GENERICAVC_CHECK_AND_ADD_SR(v, x) \
308     { if(supportsSamplingFrequency(x)) \
309       v.push_back(x); }
310
311 std::vector<int>
312 AvDevice::getSupportedSamplingFrequencies()
313 {
314     if (m_supported_frequencies_cache.size() == 0) {
315         GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 22050);
316         GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 24000);
317         GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 32000);
318         GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 44100);
319         GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 48000);
320         GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 88200);
321         GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 96000);
322         GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 176400);
323         GENERICAVC_CHECK_AND_ADD_SR(m_supported_frequencies_cache, 192000);
324     }
325     return m_supported_frequencies_cache;
326 }
327
328 FFADODevice::ClockSourceVector
329 AvDevice::getSupportedClockSources() {
330     FFADODevice::ClockSourceVector r;
331
332     Util::MutexLockHelper lock(m_DeviceMutex);
333
334     PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType(
335         eST_Music,
336         0,
337         0xff,
338         0xff,
339         Plug::eAPA_SubunitPlug,
340         Plug::eAPD_Input,
341         Plug::eAPT_Sync );
342     if ( !syncMSUInputPlugs.size() ) {
343         // there exist devices which do not have a sync plug
344         // or their av/c model is broken.
345         return r;
346     }
347
348     for ( SyncInfoVector::const_iterator it
349               = getSyncInfos().begin();
350           it != getSyncInfos().end();
351           ++it )
352     {
353         const SyncInfo si=*it;
354
355         ClockSource s=syncInfoToClockSource(*it);
356         r.push_back(s);
357     }
358     return r;
359 }
360
361 bool
362 AvDevice::setActiveClockSource(ClockSource s) {
363     Plug *src=m_pPlugManager->getPlug( s.id );
364     if (!src) {
365         debugError("Could not find plug with id %d\n", s.id);
366         return false;
367     }
368
369     Util::MutexLockHelper lock(m_DeviceMutex);
370     for ( SyncInfoVector::const_iterator it
371               = getSyncInfos().begin();
372           it != getSyncInfos().end();
373           ++it )
374     {
375         const SyncInfo si=*it;
376
377         if (si.m_source==src) {
378             return setActiveSync(si);
379         }
380     }
381     return false;
382 }
383
384 FFADODevice::ClockSource
385 AvDevice::getActiveClockSource() {
386     const SyncInfo* si=getActiveSyncInfo();
387     if ( !si ) {
388         debugError( "Could not retrieve active sync information\n" );
389         ClockSource s;
390         s.type=eCT_Invalid;
391         return s;
392     }
393     debugOutput(DEBUG_LEVEL_VERBOSE, "Active Sync mode:  %s\n", si->m_description.c_str() );
394
395     return syncInfoToClockSource(*si);
396 }
397
398 FFADODevice::ClockSource
399 AvDevice::syncInfoToClockSource(const SyncInfo& si) {
400     ClockSource s;
401
402     // the description is easy
403     // it can be that we overwrite it later
404     s.description=si.m_description;
405
406     // FIXME: always valid at the moment
407     s.valid=true;
408
409     assert(si.m_source);
410     s.id=si.m_source->getGlobalId();
411
412     // now figure out what type this is
413     switch(si.m_source->getPlugType()) {
414         case Plug::eAPT_IsoStream:
415             s.type=eCT_SytMatch;
416             break;
417         case Plug::eAPT_Sync:
418             if(si.m_source->getPlugAddressType() == Plug::eAPA_PCR) {
419                 s.type=eCT_SytStream; // this is logical
420             } else if(si.m_source->getPlugAddressType() == Plug::eAPA_SubunitPlug) {
421                 s.type=eCT_Internal; // this assumes some stuff
422             } else if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) {
423                 std::string plugname=si.m_source->getName();
424                 s.description=plugname;
425                 // this is basically due to Focusrites interpretation
426                 if(plugname.find( "SPDIF", 0 ) != string::npos) {
427                     s.type=eCT_SPDIF; // this assumes the name will tell us
428                 } else {
429                     s.type=eCT_WordClock; // this assumes a whole lot more
430                 }
431             } else {
432                 s.type=eCT_Invalid;
433             }
434             break;
435         case Plug::eAPT_Digital:
436             if(si.m_source->getPlugAddressType() == Plug::eAPA_ExternalPlug) {
437                 std::string plugname=si.m_source->getName();
438                 s.description=plugname;
439                 // this is basically due to Focusrites interpretation
440                 if(plugname.find( "ADAT", 0 ) != string::npos) {
441                     s.type=eCT_ADAT; // this assumes the name will tell us
442                 } else if(plugname.find( "SPDIF", 0 ) != string::npos) {
443                     s.type=eCT_SPDIF; // this assumes the name will tell us
444                 } else {
445                     s.type=eCT_WordClock; // this assumes a whole lot more
446                 }
447             } else {
448                 s.type=eCT_Invalid;
449             }
450             break;
451         default:
452             s.type=eCT_Invalid; break;
453     }
454
455     // is it active?
456     const SyncInfo* active=getActiveSyncInfo();
457     if (active) {
458         if ((active->m_source == si.m_source)
459            && (active->m_destination == si.m_destination))
460            s.active=true;
461         else s.active=false;
462     } else s.active=false;
463
464     return s;
465 }
466
467 bool
468 AvDevice::lock() {
469     bool snoopMode=false;
470     Util::MutexLockHelper lock(m_DeviceMutex);
471     if(!getOption("snoopMode", snoopMode)) {
472         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
473     }
474
475     if (snoopMode) {
476         // don't lock
477     } else {
478 //         return Unit::reserve(4);
479     }
480
481     return true;
482 }
483
484 bool
485 AvDevice::unlock() {
486     bool snoopMode=false;
487     Util::MutexLockHelper lock(m_DeviceMutex);
488     if(!getOption("snoopMode", snoopMode)) {
489         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
490     }
491
492     if (snoopMode) {
493         // don't unlock
494     } else {
495 //         return Unit::reserve(0);
496     }
497     return true;
498 }
499
500 void
501 AvDevice::showDevice()
502 {
503     FFADODevice::showDevice();
504
505     AVC::Unit::show();
506     flushDebugOutput();
507 }
508
509 bool
510 AvDevice::prepare() {
511     bool snoopMode=false;
512     Util::MutexLockHelper lock(m_DeviceMutex);
513     if(!getOption("snoopMode", snoopMode)) {
514         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
515     }
516
517     ///////////
518     // get plugs
519
520     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
521     if ( !inputPlug ) {
522         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
523         return false;
524     }
525     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
526     if ( !outputPlug ) {
527         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
528         return false;
529     }
530
531     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
532     // create & add streamprocessors
533     Streaming::StreamProcessor *p;
534
535     if ( outputPlug->getNrOfChannels() == 0 ) {
536         debugError("Receive plug has no channels\n");
537         return false;
538     }
539     p = new Streaming::AmdtpReceiveStreamProcessor(*this,
540                              outputPlug->getNrOfChannels());
541
542     if(!p->init()) {
543         debugFatal("Could not initialize receive processor!\n");
544         delete p;
545         return false;
546     }
547
548     if (!addPlugToProcessor(*outputPlug, p,
549         Streaming::Port::E_Capture)) {
550         debugFatal("Could not add plug to processor!\n");
551         delete p;
552         return false;
553     }
554
555     m_receiveProcessors.push_back(p);
556
557     // do the transmit processor
558     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n",
559             (snoopMode?" in snoop mode":""));
560     if (snoopMode) {
561         // we are snooping, so this is receive too.
562         p=new Streaming::AmdtpReceiveStreamProcessor(*this,
563                                   inputPlug->getNrOfChannels());
564     } else {
565         Streaming::AmdtpTransmitStreamProcessor * t;
566         t=new Streaming::AmdtpTransmitStreamProcessor(*this,
567                                 inputPlug->getNrOfChannels());
568         #if AMDTP_ALLOW_PAYLOAD_IN_NODATA_XMIT
569             // FIXME: it seems that some BeBoB devices can't handle NO-DATA without payload
570             t->sendPayloadForNoDataPackets(true);
571         #endif
572         p=t;
573     }
574
575     if(!p->init()) {
576         debugFatal("Could not initialize transmit processor %s!\n",
577             (snoopMode?" in snoop mode":""));
578         delete p;
579         return false;
580     }
581
582     if (snoopMode) {
583         if (!addPlugToProcessor(*inputPlug, p,
584             Streaming::Port::E_Capture)) {
585             debugFatal("Could not add plug to processor!\n");
586             return false;
587         }
588     } else {
589         if (!addPlugToProcessor(*inputPlug, p,
590             Streaming::Port::E_Playback)) {
591             debugFatal("Could not add plug to processor!\n");
592             return false;
593         }
594     }
595
596     // we put this SP into the transmit SP vector,
597     // no matter if we are in snoop mode or not
598     // this allows us to find out what direction
599     // a certain stream should have.
600     m_transmitProcessors.push_back(p);
601
602     return true;
603 }
604
605 bool
606 AvDevice::addPlugToProcessor(
607     AVC::Plug& plug,
608     Streaming::StreamProcessor *processor,
609     Streaming::AmdtpAudioPort::E_Direction direction) {
610
611     std::string id=std::string("dev?");
612     if(!getOption("id", id)) {
613         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
614     }
615
616     Plug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
617     for ( Plug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
618           it != clusterInfos.end();
619           ++it )
620     {
621         const Plug::ClusterInfo* clusterInfo = &( *it );
622
623         Plug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
624         for ( Plug::ChannelInfoVector::const_iterator it = channelInfos.begin();
625               it != channelInfos.end();
626               ++it )
627         {
628             const Plug::ChannelInfo* channelInfo = &( *it );
629             std::ostringstream portname;
630
631             portname << id << "_" << channelInfo->m_name;
632
633             Streaming::Port *p=NULL;
634             switch(clusterInfo->m_portType) {
635             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
636             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
637             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
638             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
639             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
640                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding audio channel %s (pos=0x%02X, loc=0x%02X)\n",
641                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
642                 p=new Streaming::AmdtpAudioPort(
643                         *processor,
644                         portname.str(),
645                         direction,
646                         channelInfo->m_streamPosition,
647                         channelInfo->m_location,
648                         Streaming::AmdtpPortInfo::E_MBLA
649                 );
650                 break;
651
652             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
653                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding MIDI channel %s (pos=0x%02X, loc=0x%02X)\n",
654                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi));
655                 p=new Streaming::AmdtpMidiPort(
656                         *processor,
657                         portname.str(),
658                         direction,
659                         channelInfo->m_streamPosition,
660                         // Workaround for out-of-spec hardware
661                         // should be:
662                         // channelInfo->m_location,
663                         // but now we renumber the midi channels' location as they
664                         // are discovered
665                         processor->getPortCount(Streaming::Port::E_Midi),
666                         Streaming::AmdtpPortInfo::E_Midi
667                 );
668
669                 break;
670             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
671             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
672             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
673             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
674             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
675                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding digital audio channel %s (pos=0x%02X, loc=0x%02X)\n",
676                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
677                 p=new Streaming::AmdtpAudioPort(
678                         *processor,
679                         portname.str(),
680                         direction,
681                         channelInfo->m_streamPosition,
682                         channelInfo->m_location,
683                         Streaming::AmdtpPortInfo::E_MBLA
684                 );
685                 break;
686
687             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
688             default:
689             // unsupported
690                 break;
691             }
692
693             if (!p) {
694                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
695             }
696          }
697     }
698     return true;
699 }
700
701 int
702 AvDevice::getStreamCount() {
703     int retval;
704     Util::MutexLockHelper lock(m_DeviceMutex);
705     retval = m_receiveProcessors.size() + m_transmitProcessors.size();
706     return retval;
707 }
708
709 Streaming::StreamProcessor *
710 AvDevice::getStreamProcessorByIndex(int i) {
711
712     if (i<(int)m_receiveProcessors.size()) {
713         return m_receiveProcessors.at(i);
714     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
715         return m_transmitProcessors.at(i-m_receiveProcessors.size());
716     }
717
718     return NULL;
719 }
720
721 bool
722 AvDevice::startStreamByIndex(int i) {
723     int iso_channel=-1;
724     bool snoopMode=false;
725     if(!getOption("snoopMode", snoopMode)) {
726         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
727     }
728
729     if (i<(int)m_receiveProcessors.size()) {
730         int n=i;
731         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
732
733         if(snoopMode) { // a stream from the device to another host
734             // FIXME: put this into a decent framework!
735             // we should check the oPCR[n] on the device
736             struct iec61883_oPCR opcr;
737             if (iec61883_get_oPCRX(
738                     get1394Service().getHandle(),
739                     getConfigRom().getNodeId() | 0xffc0,
740                     (quadlet_t *)&opcr,
741                     n)) {
742
743                 debugWarning("Error getting the channel for SP %d\n",i);
744                 return false;
745             }
746
747             iso_channel=opcr.channel;
748         } else {
749             iso_channel=get1394Service().allocateIsoChannelCMP(
750                 getConfigRom().getNodeId() | 0xffc0, n,
751                 get1394Service().getLocalNodeId()| 0xffc0, -1);
752         }
753         if (iso_channel<0) {
754             debugError("Could not allocate ISO channel for SP %d\n",i);
755             return false;
756         }
757
758         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
759
760         p->setChannel(iso_channel);
761         return true;
762
763     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
764         int n=i-m_receiveProcessors.size();
765         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
766
767         if(snoopMode) { // a stream from another host to the device
768             // FIXME: put this into a decent framework!
769             // we should check the iPCR[n] on the device
770             struct iec61883_iPCR ipcr;
771             if (iec61883_get_iPCRX(
772                     get1394Service().getHandle(),
773                     getConfigRom().getNodeId() | 0xffc0,
774                     (quadlet_t *)&ipcr,
775                     n)) {
776
777                 debugWarning("Error getting the channel for SP %d\n",i);
778                 return false;
779             }
780
781             iso_channel=ipcr.channel;
782
783         } else {
784             iso_channel=get1394Service().allocateIsoChannelCMP(
785                 get1394Service().getLocalNodeId()| 0xffc0, -1,
786                 getConfigRom().getNodeId() | 0xffc0, n);
787         }
788
789         if (iso_channel<0) {
790             debugError("Could not allocate ISO channel for SP %d\n",i);
791             return false;
792         }
793
794         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
795
796         p->setChannel(iso_channel);
797         return true;
798     }
799
800     debugError("SP index %d out of range!\n",i);
801     return false;
802 }
803
804 bool
805 AvDevice::stopStreamByIndex(int i) {
806     bool snoopMode=false;
807     if(!getOption("snoopMode", snoopMode)) {
808         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
809     }
810
811     if (i<(int)m_receiveProcessors.size()) {
812         int n=i;
813         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
814
815         // can't stop it if it's not running
816         if(p->getChannel() == -1) {
817             debugOutput(DEBUG_LEVEL_VERBOSE, "SP %d not running\n",i);
818             return true;
819         }
820
821         if(snoopMode) {
822
823         } else {
824             // deallocate ISO channel
825             if(!get1394Service().freeIsoChannel(p->getChannel())) {
826                 debugError("Could not deallocate iso channel for SP %d\n",i);
827                 return false;
828             }
829         }
830         p->setChannel(-1);
831
832         return true;
833
834     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
835         int n=i-m_receiveProcessors.size();
836         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
837
838         // can't stop it if it's not running
839         if(p->getChannel() == -1) {
840             debugOutput(DEBUG_LEVEL_VERBOSE, "SP %d not running\n",i);
841             return true;
842         }
843
844         if(snoopMode) {
845
846         } else {
847             // deallocate ISO channel
848             if(!get1394Service().freeIsoChannel(p->getChannel())) {
849                 debugError("Could not deallocate iso channel for SP %d\n",i);
850                 return false;
851             }
852         }
853         p->setChannel(-1);
854
855         return true;
856     }
857
858     debugError("SP index %d out of range!\n",i);
859     return false;
860 }
861
862 bool
863 AvDevice::serialize( std::string basePath, Util::IOSerialize& ser ) const
864 {
865     bool result;
866     result  = AVC::Unit::serialize( basePath, ser );
867     result &= serializeOptions( basePath + "Options", ser );
868     return result;
869 }
870
871 bool
872 AvDevice::deserialize( std::string basePath, Util::IODeserialize& deser )
873 {
874     bool result;
875     result = AVC::Unit::deserialize( basePath, deser );
876     return result;
877 }
878
879 }
Note: See TracBrowser for help on using the browser.