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

Revision 1550, 30.4 kB (checked in by ppalmers, 15 years ago)

- Implement basic HSS1394 support for the Stanton SCS devices
- Start of the implementation of a generic TCAT DICE EAP control
- Reworked part of the busreset / ARM handler code

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 #include "stanton/scs.h"
48
49 namespace GenericAVC {
50
51 IMPL_DEBUG_MODULE( Device, Device, DEBUG_LEVEL_NORMAL );
52
53 Device::Device( DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
54     : FFADODevice( d, configRom )
55 {
56     debugOutput( DEBUG_LEVEL_VERBOSE, "Created GenericAVC::Device (NodeID %d)\n",
57                  getConfigRom().getNodeId() );
58     addOption(Util::OptionContainer::Option("snoopMode",false));
59 }
60
61 Device::~Device()
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 Device::probe( Util::Configuration& c, ConfigRom& configRom, bool generic )
79 {
80     if(generic) {
81         // check if we have a music subunit
82         AVC::SubUnitInfoCmd subUnitInfoCmd( configRom.get1394Service() );
83         subUnitInfoCmd.setCommandType( AVC::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             AVC::subunit_type_t subunit_type
93                 = subUnitInfoCmd.m_table[i].m_subunit_type;
94             if (subunit_type == AVC::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 Device::createDevice(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
111 {
112     unsigned int vendorId = configRom->getNodeVendorId();
113     unsigned int modelId = configRom->getModelId();
114
115     switch (vendorId) {
116         case FW_VENDORID_STANTON:
117             if (modelId == 0x00001000 ) {
118                 return new Stanton::ScsDevice(d, configRom);
119             }
120         default:
121             return new GenericAVC::Device(d, configRom);
122     }
123     return NULL;
124 }
125
126 bool
127 Device::discover()
128 {
129     Util::MutexLockHelper lock(m_DeviceMutex);
130
131     unsigned int vendorId = getConfigRom().getNodeVendorId();
132     unsigned int modelId = getConfigRom().getModelId();
133
134     Util::Configuration &c = getDeviceManager().getConfiguration();
135     Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
136
137     if (c.isValid(vme) && vme.driver == Util::Configuration::eD_GenericAVC) {
138         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
139                      vme.vendor_name.c_str(),
140                      vme.model_name.c_str());
141     } else {
142         debugWarning("Using generic AV/C support for unsupported device '%s %s'\n",
143                      getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
144     }
145     return discoverGeneric();
146 }
147
148 bool
149 Device::discoverGeneric()
150 {
151     if ( !Unit::discover() ) {
152         debugError( "Could not discover unit\n" );
153         return false;
154     }
155
156     if((getAudioSubunit( 0 ) == NULL)) {
157         debugError( "Unit doesn't have an Audio subunit.\n");
158         return false;
159     }
160     if((getMusicSubunit( 0 ) == NULL)) {
161         debugError( "Unit doesn't have a Music subunit.\n");
162         return false;
163     }
164     return true;
165 }
166
167 void
168 Device::setVerboseLevel(int l)
169 {
170     Util::MutexLockHelper lock(m_DeviceMutex);
171     setDebugLevel(l);
172     m_pPlugManager->setVerboseLevel(l);
173     FFADODevice::setVerboseLevel(l);
174     AVC::Unit::setVerboseLevel(l);
175     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
176 }
177
178 #include <libieee1394/IEC61883.h>
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                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi));
716                 p=new Streaming::AmdtpMidiPort(
717                         *processor,
718                         portname.str(),
719                         direction,
720                         channelInfo->m_streamPosition,
721                         // Workaround for out-of-spec hardware
722                         // should be:
723                         // channelInfo->m_location,
724                         // but now we renumber the midi channels' location as they
725                         // are discovered
726                         processor->getPortCount(Streaming::Port::E_Midi),
727                         Streaming::AmdtpPortInfo::E_Midi
728                 );
729
730                 break;
731             case AVC::ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
732             case AVC::ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
733             case AVC::ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
734             case AVC::ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
735             case AVC::ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
736                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding digital audio channel %s (pos=0x%02X, loc=0x%02X)\n",
737                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
738                 p=new Streaming::AmdtpAudioPort(
739                         *processor,
740                         portname.str(),
741                         direction,
742                         channelInfo->m_streamPosition,
743                         channelInfo->m_location,
744                         Streaming::AmdtpPortInfo::E_MBLA
745                 );
746                 break;
747
748             case AVC::ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
749             default:
750             // unsupported
751                 break;
752             }
753
754             if (!p) {
755                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n", channelInfo->m_name.c_str());
756             }
757          }
758     }
759     return true;
760 }
761
762 int
763 Device::getStreamCount() {
764     int retval;
765     Util::MutexLockHelper lock(m_DeviceMutex);
766     retval = m_receiveProcessors.size() + m_transmitProcessors.size();
767     return retval;
768 }
769
770 Streaming::StreamProcessor *
771 Device::getStreamProcessorByIndex(int i) {
772
773     if (i<(int)m_receiveProcessors.size()) {
774         return m_receiveProcessors.at(i);
775     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
776         return m_transmitProcessors.at(i-m_receiveProcessors.size());
777     }
778
779     return NULL;
780 }
781
782 bool
783 Device::startStreamByIndex(int i) {
784     int iso_channel=-1;
785     bool snoopMode=false;
786     if(!getOption("snoopMode", snoopMode)) {
787         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
788     }
789
790     if (i<(int)m_receiveProcessors.size()) {
791         int n=i;
792         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
793
794         if(snoopMode) { // a stream from the device to another host
795             // FIXME: put this into a decent framework!
796             // we should check the oPCR[n] on the device
797             struct iec61883_oPCR opcr;
798             if (iec61883_get_oPCRX(
799                     get1394Service().getHandle(),
800                     getConfigRom().getNodeId() | 0xffc0,
801                     (quadlet_t *)&opcr,
802                     n)) {
803
804                 debugWarning("Error getting the channel for SP %d\n",i);
805                 return false;
806             }
807
808             iso_channel=opcr.channel;
809         } else {
810             iso_channel=get1394Service().allocateIsoChannelCMP(
811                 getConfigRom().getNodeId() | 0xffc0, n,
812                 get1394Service().getLocalNodeId()| 0xffc0, -1);
813         }
814         if (iso_channel<0) {
815             debugError("Could not allocate ISO channel for SP %d\n",i);
816             return false;
817         }
818
819         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
820
821         p->setChannel(iso_channel);
822         return true;
823
824     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
825         int n=i-m_receiveProcessors.size();
826         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
827
828         if(snoopMode) { // a stream from another host to the device
829             // FIXME: put this into a decent framework!
830             // we should check the iPCR[n] on the device
831             struct iec61883_iPCR ipcr;
832             if (iec61883_get_iPCRX(
833                     get1394Service().getHandle(),
834                     getConfigRom().getNodeId() | 0xffc0,
835                     (quadlet_t *)&ipcr,
836                     n)) {
837
838                 debugWarning("Error getting the channel for SP %d\n",i);
839                 return false;
840             }
841
842             iso_channel=ipcr.channel;
843
844         } else {
845             iso_channel=get1394Service().allocateIsoChannelCMP(
846                 get1394Service().getLocalNodeId()| 0xffc0, -1,
847                 getConfigRom().getNodeId() | 0xffc0, n);
848         }
849
850         if (iso_channel<0) {
851             debugError("Could not allocate ISO channel for SP %d\n",i);
852             return false;
853         }
854
855         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
856
857         p->setChannel(iso_channel);
858         return true;
859     }
860
861     debugError("SP index %d out of range!\n",i);
862     return false;
863 }
864
865 bool
866 Device::stopStreamByIndex(int i) {
867     bool snoopMode=false;
868     if(!getOption("snoopMode", snoopMode)) {
869         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
870     }
871
872     if (i<(int)m_receiveProcessors.size()) {
873         int n=i;
874         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
875
876         // can't stop it if it's not running
877         if(p->getChannel() == -1) {
878             debugOutput(DEBUG_LEVEL_VERBOSE, "SP %d not running\n",i);
879             return true;
880         }
881
882         if(snoopMode) {
883
884         } else {
885             // deallocate ISO channel
886             if(!get1394Service().freeIsoChannel(p->getChannel())) {
887                 debugError("Could not deallocate iso channel for SP %d\n",i);
888                 return false;
889             }
890         }
891         p->setChannel(-1);
892
893         return true;
894
895     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
896         int n=i-m_receiveProcessors.size();
897         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
898
899         // can't stop it if it's not running
900         if(p->getChannel() == -1) {
901             debugOutput(DEBUG_LEVEL_VERBOSE, "SP %d not running\n",i);
902             return true;
903         }
904
905         if(snoopMode) {
906
907         } else {
908             // deallocate ISO channel
909             if(!get1394Service().freeIsoChannel(p->getChannel())) {
910                 debugError("Could not deallocate iso channel for SP %d\n",i);
911                 return false;
912             }
913         }
914         p->setChannel(-1);
915
916         return true;
917     }
918
919     debugError("SP index %d out of range!\n",i);
920     return false;
921 }
922
923 bool
924 Device::serialize( std::string basePath, Util::IOSerialize& ser ) const
925 {
926     bool result;
927     result  = AVC::Unit::serialize( basePath, ser );
928     result &= serializeOptions( basePath + "Options", ser );
929     return result;
930 }
931
932 bool
933 Device::deserialize( std::string basePath, Util::IODeserialize& deser )
934 {
935     bool result;
936     result = AVC::Unit::deserialize( basePath, deser );
937     return result;
938 }
939
940 }
Note: See TracBrowser for help on using the browser.