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

Revision 1531, 29.9 kB (checked in by ppalmers, 15 years ago)

svn merge -r 1506:HEAD svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0

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