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

Revision 548, 18.1 kB (checked in by ppalmers, 13 years ago)

- make the BeBoB AvDevice? a child class of the GenericAVC AvDevice?. This
avoids a lot of code duplication.
- fix inconsistency in position/location numbering between ext pluginfo
cmd and descriptor.

Line 
1 /*
2  * Copyright (C) 2005-2007 by Pieter Palmers
3  * Copyright (C) 2005-2007 by Daniel Wagner
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License version 2.1, as published by the Free Software Foundation;
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22  * MA 02110-1301 USA
23  */
24
25 #warning Generic AV/C support is currently useless
26
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
35 #include "debugmodule/debugmodule.h"
36
37 #include <string>
38 #include <stdint.h>
39 #include <assert.h>
40 #include <netinet/in.h>
41 #include <iostream>
42 #include <sstream>
43
44 #include <libraw1394/csr.h>
45
46 using namespace AVC;
47
48 namespace GenericAVC {
49
50 IMPL_DEBUG_MODULE( AvDevice, AvDevice, DEBUG_LEVEL_VERBOSE );
51
52 // to define the supported devices
53 static VendorModelEntry supportedDeviceList[] =
54 {
55     {0x001486, 0x00000af2, "Echo", "AudioFire2"},
56 };
57
58 AvDevice::AvDevice( std::auto_ptr< ConfigRom >( configRom ),
59                     Ieee1394Service& ieee1394service,
60                     int nodeId )
61     :  FFADODevice( configRom, ieee1394service, nodeId )
62     , m_model( NULL )
63
64 {
65     debugOutput( DEBUG_LEVEL_VERBOSE, "Created GenericAVC::AvDevice (NodeID %d)\n",
66                  nodeId );
67     addOption(Util::OptionContainer::Option("snoopMode",false));
68 }
69
70 AvDevice::~AvDevice()
71 {
72
73 }
74
75 bool
76 AvDevice::probe( ConfigRom& configRom )
77 {
78     unsigned int vendorId = configRom.getNodeVendorId();
79     unsigned int modelId = configRom.getModelId();
80
81     for ( unsigned int i = 0;
82           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
83           ++i )
84     {
85         if ( ( supportedDeviceList[i].vendor_id == vendorId )
86              && ( supportedDeviceList[i].model_id == modelId )
87            )
88         {
89             return true;
90         }
91     }
92
93     return false;
94 }
95
96 bool
97 AvDevice::discover()
98 {
99     unsigned int vendorId = m_pConfigRom->getNodeVendorId();
100     unsigned int modelId = m_pConfigRom->getModelId();
101
102     for ( unsigned int i = 0;
103           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
104           ++i )
105     {
106         if ( ( supportedDeviceList[i].vendor_id == vendorId )
107              && ( supportedDeviceList[i].model_id == modelId )
108            )
109         {
110             m_model = &(supportedDeviceList[i]);
111         }
112     }
113
114     if (m_model == NULL) {
115         return false;
116     }
117     debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
118             m_model->vendor_name, m_model->model_name);
119
120     if ( !Unit::discover() ) {
121         debugError( "Could not discover unit\n" );
122         return false;
123     }
124
125     if((getAudioSubunit( 0 ) == NULL)) {
126         debugError( "Unit doesn't have an Audio subunit.\n");
127         return false;
128     }
129     if((getMusicSubunit( 0 ) == NULL)) {
130         debugError( "Unit doesn't have a Music subunit.\n");
131         return false;
132     }
133
134     return true;
135 }
136
137 void
138 AvDevice::setVerboseLevel(int l)
139 {
140     m_pPlugManager->setVerboseLevel(l);
141
142     FFADODevice::setVerboseLevel(l);
143     AVC::Unit::setVerboseLevel(l);
144 }
145
146 int
147 AvDevice::getSamplingFrequency( ) {
148     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
149     if ( !inputPlug ) {
150         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
151         return false;
152     }
153     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
154     if ( !outputPlug ) {
155         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
156         return false;
157     }
158
159     int samplerate_playback=inputPlug->getSampleRate();
160     int samplerate_capture=outputPlug->getSampleRate();
161
162     if (samplerate_playback != samplerate_capture) {
163         debugWarning("Samplerates for capture and playback differ!\n");
164     }
165     return samplerate_capture;
166 }
167
168 bool
169 AvDevice::setSamplingFrequency( int s )
170 {
171     bool snoopMode=false;
172     if(!getOption("snoopMode", snoopMode)) {
173         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
174     }
175
176     if(snoopMode) {
177         int current_sr=getSamplingFrequency();
178         if (current_sr != s ) {
179             debugError("In snoop mode it is impossible to set the sample rate.\n");
180             debugError("Please start the client with the correct setting.\n");
181             return false;
182         }
183         return true;
184     } else {
185         AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
186         if ( !plug ) {
187             debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
188             return false;
189         }
190
191         if ( !plug->setSampleRate( s ) )
192         {
193             debugError( "setSampleRate: Setting sample rate failed\n" );
194             return false;
195         }
196
197         plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output,  0 );
198         if ( !plug ) {
199             debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
200             return false;
201         }
202
203         if ( !plug->setSampleRate( s ) )
204         {
205             debugError( "setSampleRate: Setting sample rate failed\n" );
206             return false;
207         }
208
209         debugOutput( DEBUG_LEVEL_VERBOSE,
210                      "setSampleRate: Set sample rate to %d\n",
211                      s );
212         return true;
213     }
214     // not executable
215     return false;
216
217 }
218
219 bool
220 AvDevice::lock() {
221     bool snoopMode=false;
222     if(!getOption("snoopMode", snoopMode)) {
223         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
224     }
225
226     if (snoopMode) {
227         // don't lock
228     } else {
229 //         return Unit::reserve(4);
230     }
231
232     return true;
233 }
234
235 bool
236 AvDevice::unlock() {
237     bool snoopMode=false;
238     if(!getOption("snoopMode", snoopMode)) {
239         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
240     }
241
242     if (snoopMode) {
243         // don't unlock
244     } else {
245 //         return Unit::reserve(0);
246     }
247     return true;
248 }
249
250 void
251 AvDevice::showDevice()
252 {
253     debugOutput(DEBUG_LEVEL_VERBOSE,
254         "%s %s at node %d\n", m_model->vendor_name, m_model->model_name,
255         m_nodeId);
256
257     m_pPlugManager->showPlugs();
258     flushDebugOutput();
259 }
260
261 bool
262 AvDevice::prepare() {
263     bool snoopMode=false;
264     if(!getOption("snoopMode", snoopMode)) {
265         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
266     }
267
268     ///////////
269     // get plugs
270
271     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
272     if ( !inputPlug ) {
273         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
274         return false;
275     }
276     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
277     if ( !outputPlug ) {
278         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
279         return false;
280     }
281
282     int samplerate=outputPlug->getSampleRate();
283
284     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
285     // create & add streamprocessors
286     Streaming::StreamProcessor *p;
287
288     p=new Streaming::AmdtpReceiveStreamProcessor(
289                              get1394Service().getPort(),
290                              samplerate,
291                              outputPlug->getNrOfChannels());
292
293     if(!p->init()) {
294         debugFatal("Could not initialize receive processor!\n");
295         delete p;
296         return false;
297     }
298
299     if (!addPlugToProcessor(*outputPlug,p,
300         Streaming::Port::E_Capture)) {
301         debugFatal("Could not add plug to processor!\n");
302         delete p;
303         return false;
304     }
305
306     m_receiveProcessors.push_back(p);
307
308     // do the transmit processor
309     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n",
310             (snoopMode?" in snoop mode":""));
311     if (snoopMode) {
312         // we are snooping, so this is receive too.
313         p=new Streaming::AmdtpReceiveStreamProcessor(
314                                   get1394Service().getPort(),
315                                   samplerate,
316                                   inputPlug->getNrOfChannels());
317     } else {
318         p=new Streaming::AmdtpTransmitStreamProcessor(
319                                 get1394Service().getPort(),
320                                 samplerate,
321                                 inputPlug->getNrOfChannels());
322     }
323
324     if(!p->init()) {
325         debugFatal("Could not initialize transmit processor %s!\n",
326             (snoopMode?" in snoop mode":""));
327         delete p;
328         return false;
329     }
330
331     if (snoopMode) {
332         if (!addPlugToProcessor(*inputPlug,p,
333             Streaming::Port::E_Capture)) {
334             debugFatal("Could not add plug to processor!\n");
335             return false;
336         }
337     } else {
338         if (!addPlugToProcessor(*inputPlug,p,
339             Streaming::Port::E_Playback)) {
340             debugFatal("Could not add plug to processor!\n");
341             return false;
342         }
343     }
344
345     // we put this SP into the transmit SP vector,
346     // no matter if we are in snoop mode or not
347     // this allows us to find out what direction
348     // a certain stream should have.
349     m_transmitProcessors.push_back(p);
350
351     return true;
352 }
353
354 bool
355 AvDevice::addPlugToProcessor(
356     AVC::Plug& plug,
357     Streaming::StreamProcessor *processor,
358     Streaming::AmdtpAudioPort::E_Direction direction) {
359
360     std::string id=std::string("dev?");
361     if(!getOption("id", id)) {
362         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
363     }
364
365     Plug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
366     for ( Plug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
367           it != clusterInfos.end();
368           ++it )
369     {
370         const Plug::ClusterInfo* clusterInfo = &( *it );
371
372         Plug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
373         for ( Plug::ChannelInfoVector::const_iterator it = channelInfos.begin();
374               it != channelInfos.end();
375               ++it )
376         {
377             const Plug::ChannelInfo* channelInfo = &( *it );
378             std::ostringstream portname;
379
380             portname << id << "_" << channelInfo->m_name;
381
382             Streaming::Port *p=NULL;
383             switch(clusterInfo->m_portType) {
384             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
385             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
386             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
387             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
388             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
389                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding audio channel %s (pos=0x%02X, loc=0x%02X)\n",
390                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
391                 p=new Streaming::AmdtpAudioPort(
392                         portname.str(),
393                         direction,
394                         channelInfo->m_streamPosition,
395                         channelInfo->m_location,
396                         Streaming::AmdtpPortInfo::E_MBLA
397                 );
398                 break;
399
400             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
401                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding MIDI channel %s (pos=0x%02X, loc=0x%02X)\n",
402                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, processor->getPortCount(Streaming::Port::E_Midi));
403                 p=new Streaming::AmdtpMidiPort(
404                         portname.str(),
405                         direction,
406                         channelInfo->m_streamPosition,
407                         // Workaround for out-of-spec hardware
408                         // should be:
409                         // channelInfo->m_location,
410                         // but now we renumber the midi channels' location as they
411                         // are discovered
412                         processor->getPortCount(Streaming::Port::E_Midi),
413                         Streaming::AmdtpPortInfo::E_Midi
414                 );
415
416                 break;
417             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
418             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
419             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
420             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
421             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
422                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding digital audio channel %s (pos=0x%02X, loc=0x%02X)\n",
423                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
424                 p=new Streaming::AmdtpAudioPort(
425                         portname.str(),
426                         direction,
427                         channelInfo->m_streamPosition,
428                         channelInfo->m_location,
429                         Streaming::AmdtpPortInfo::E_MBLA
430                 );
431                 break;
432                
433             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
434             default:
435             // unsupported
436                 break;
437             }
438
439             if (!p) {
440                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
441             } else {
442
443                 if (!processor->addPort(p)) {
444                     debugWarning("Could not register port with stream processor\n");
445                     return false;
446                 }
447             }
448          }
449     }
450     return true;
451 }
452
453 int
454 AvDevice::getStreamCount() {
455     return m_receiveProcessors.size() + m_transmitProcessors.size();
456 }
457
458 Streaming::StreamProcessor *
459 AvDevice::getStreamProcessorByIndex(int i) {
460
461     if (i<(int)m_receiveProcessors.size()) {
462         return m_receiveProcessors.at(i);
463     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
464         return m_transmitProcessors.at(i-m_receiveProcessors.size());
465     }
466
467     return NULL;
468 }
469
470 bool
471 AvDevice::startStreamByIndex(int i) {
472     int iso_channel=-1;
473     bool snoopMode=false;
474     if(!getOption("snoopMode", snoopMode)) {
475         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
476     }
477
478     if (i<(int)m_receiveProcessors.size()) {
479         int n=i;
480         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
481
482         if(snoopMode) { // a stream from the device to another host
483             // FIXME: put this into a decent framework!
484             // we should check the oPCR[n] on the device
485             struct iec61883_oPCR opcr;
486             if (iec61883_get_oPCRX(
487                     get1394Service().getHandle(),
488                     m_pConfigRom->getNodeId() | 0xffc0,
489                     (quadlet_t *)&opcr,
490                     n)) {
491
492                 debugWarning("Error getting the channel for SP %d\n",i);
493                 return false;
494             }
495
496             iso_channel=opcr.channel;
497         } else {
498             iso_channel=get1394Service().allocateIsoChannelCMP(
499                 m_pConfigRom->getNodeId() | 0xffc0, n,
500                 get1394Service().getLocalNodeId()| 0xffc0, -1);
501         }
502         if (iso_channel<0) {
503             debugError("Could not allocate ISO channel for SP %d\n",i);
504             return false;
505         }
506
507         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
508
509         p->setChannel(iso_channel);
510         return true;
511
512     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
513         int n=i-m_receiveProcessors.size();
514         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
515
516         if(snoopMode) { // a stream from another host to the device
517             // FIXME: put this into a decent framework!
518             // we should check the iPCR[n] on the device
519             struct iec61883_iPCR ipcr;
520             if (iec61883_get_iPCRX(
521                     get1394Service().getHandle(),
522                     m_pConfigRom->getNodeId() | 0xffc0,
523                     (quadlet_t *)&ipcr,
524                     n)) {
525
526                 debugWarning("Error getting the channel for SP %d\n",i);
527                 return false;
528             }
529
530             iso_channel=ipcr.channel;
531
532         } else {
533             iso_channel=get1394Service().allocateIsoChannelCMP(
534                 get1394Service().getLocalNodeId()| 0xffc0, -1,
535                 m_pConfigRom->getNodeId() | 0xffc0, n);
536         }
537
538         if (iso_channel<0) {
539             debugError("Could not allocate ISO channel for SP %d\n",i);
540             return false;
541         }
542
543         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
544
545         p->setChannel(iso_channel);
546         return true;
547     }
548
549     debugError("SP index %d out of range!\n",i);
550     return false;
551 }
552
553 bool
554 AvDevice::stopStreamByIndex(int i) {
555     bool snoopMode=false;
556     if(!getOption("snoopMode", snoopMode)) {
557         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
558     }
559
560     if (i<(int)m_receiveProcessors.size()) {
561         int n=i;
562         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
563
564         if(snoopMode) {
565
566         } else {
567             // deallocate ISO channel
568             if(!get1394Service().freeIsoChannel(p->getChannel())) {
569                 debugError("Could not deallocate iso channel for SP %d\n",i);
570                 return false;
571             }
572         }
573         p->setChannel(-1);
574
575         return true;
576
577     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
578         int n=i-m_receiveProcessors.size();
579         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
580
581         if(snoopMode) {
582
583         } else {
584             // deallocate ISO channel
585             if(!get1394Service().freeIsoChannel(p->getChannel())) {
586                 debugError("Could not deallocate iso channel for SP %d\n",i);
587                 return false;
588             }
589         }
590         p->setChannel(-1);
591
592         return true;
593     }
594
595     debugError("SP index %d out of range!\n",i);
596     return false;
597 }
598
599 }
Note: See TracBrowser for help on using the browser.