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

Revision 2803, 30.4 kB (checked in by jwoithe, 3 years ago)

Cosmetic: capitalise "L" in "Linux".

"Linux" is a proper noun so it should start with a capital letter. These
changes are almost all within comments.

This patch was originally proposed by pander on the ffado-devel mailing
list. It has been expanded to cover all similar cases to maintain
consistency throughout the source tree.

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