root/branches/echoaudio/src/genericavc/avc_avdevice.cpp

Revision 541, 18.0 kB (checked in by ppalmers, 15 years ago)

cosmetic change

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 }
68
69 AvDevice::~AvDevice()
70 {
71
72 }
73
74 bool
75 AvDevice::probe( ConfigRom& configRom )
76 {
77     unsigned int vendorId = configRom.getNodeVendorId();
78     unsigned int modelId = configRom.getModelId();
79
80     for ( unsigned int i = 0;
81           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
82           ++i )
83     {
84         if ( ( supportedDeviceList[i].vendor_id == vendorId )
85              && ( supportedDeviceList[i].model_id == modelId )
86            )
87         {
88             return true;
89         }
90     }
91
92     return false;
93 }
94
95 bool
96 AvDevice::discover()
97 {
98     unsigned int vendorId = m_pConfigRom->getNodeVendorId();
99     unsigned int modelId = m_pConfigRom->getModelId();
100
101     for ( unsigned int i = 0;
102           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
103           ++i )
104     {
105         if ( ( supportedDeviceList[i].vendor_id == vendorId )
106              && ( supportedDeviceList[i].model_id == modelId )
107            )
108         {
109             m_model = &(supportedDeviceList[i]);
110         }
111     }
112
113     if (m_model == NULL) {
114         return false;
115     }
116     debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
117             m_model->vendor_name, m_model->model_name);
118
119     if ( !Unit::discover() ) {
120         debugError( "Could not discover unit\n" );
121         return false;
122     }
123
124     if((getAudioSubunit( 0 ) == NULL)) {
125         debugError( "Unit doesn't have an Audio subunit.\n");
126         return false;
127     }
128     if((getMusicSubunit( 0 ) == NULL)) {
129         debugError( "Unit doesn't have a Music subunit.\n");
130         return false;
131     }
132
133     return true;
134 }
135
136 int
137 AvDevice::getSamplingFrequency( ) {
138     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
139     if ( !inputPlug ) {
140         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
141         return false;
142     }
143     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
144     if ( !outputPlug ) {
145         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
146         return false;
147     }
148
149     int samplerate_playback=inputPlug->getSampleRate();
150     int samplerate_capture=outputPlug->getSampleRate();
151
152     if (samplerate_playback != samplerate_capture) {
153         debugWarning("Samplerates for capture and playback differ!\n");
154     }
155     return samplerate_capture;
156 }
157
158 bool
159 AvDevice::setSamplingFrequency( int s )
160 {
161     ESamplingFrequency samplingFrequency=parseSampleRate( s );
162     bool snoopMode=false;
163     if(!getOption("snoopMode", snoopMode)) {
164         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
165     }
166
167     if(snoopMode) {
168         int current_sr=getSamplingFrequency();
169         if (current_sr != convertESamplingFrequency( samplingFrequency ) ) {
170             debugError("In snoop mode it is impossible to set the sample rate.\n");
171             debugError("Please start the client with the correct setting.\n");
172             return false;
173         }
174         return true;
175     } else {
176         AVC::Plug* plug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
177         if ( !plug ) {
178             debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
179             return false;
180         }
181
182         if ( !plug->setSampleRate( convertESamplingFrequency( samplingFrequency ) ) )
183         {
184             debugError( "setSampleRate: Setting sample rate failed\n" );
185             return false;
186         }
187
188         plug = getPlugById( m_pcrPlugs, Plug::eAPD_Output,  0 );
189         if ( !plug ) {
190             debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
191             return false;
192         }
193
194         if ( !plug->setSampleRate( convertESamplingFrequency( samplingFrequency ) ) )
195         {
196             debugError( "setSampleRate: Setting sample rate failed\n" );
197             return false;
198         }
199
200         debugOutput( DEBUG_LEVEL_VERBOSE,
201                      "setSampleRate: Set sample rate to %d\n",
202                      convertESamplingFrequency( samplingFrequency ) );
203         return true;
204     }
205     // not executable
206     return false;
207
208 }
209
210 bool
211 AvDevice::lock() {
212     bool snoopMode=false;
213     if(!getOption("snoopMode", snoopMode)) {
214         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
215     }
216
217     if (snoopMode) {
218         // don't lock
219     } else {
220 //         return Unit::reserve(4);
221     }
222
223     return true;
224 }
225
226 bool
227 AvDevice::unlock() {
228     bool snoopMode=false;
229     if(!getOption("snoopMode", snoopMode)) {
230         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
231     }
232
233     if (snoopMode) {
234         // don't unlock
235     } else {
236 //         return Unit::reserve(0);
237     }
238     return true;
239 }
240
241 void
242 AvDevice::showDevice()
243 {
244     debugOutput(DEBUG_LEVEL_VERBOSE,
245         "%s %s at node %d\n", m_model->vendor_name, m_model->model_name,
246         m_nodeId);
247
248     m_pPlugManager->showPlugs();
249     flushDebugOutput();
250 }
251
252 bool
253 AvDevice::prepare() {
254     bool snoopMode=false;
255     if(!getOption("snoopMode", snoopMode)) {
256         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
257     }
258
259     ///////////
260     // get plugs
261
262     AVC::Plug* inputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Input, 0 );
263     if ( !inputPlug ) {
264         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
265         return false;
266     }
267     AVC::Plug* outputPlug = getPlugById( m_pcrPlugs, Plug::eAPD_Output, 0 );
268     if ( !outputPlug ) {
269         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
270         return false;
271     }
272
273     int samplerate=outputPlug->getSampleRate();
274
275     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
276     // create & add streamprocessors
277     Streaming::StreamProcessor *p;
278
279     p=new Streaming::AmdtpReceiveStreamProcessor(
280                              get1394Service().getPort(),
281                              samplerate,
282                              outputPlug->getNrOfChannels());
283
284     if(!p->init()) {
285         debugFatal("Could not initialize receive processor!\n");
286         delete p;
287         return false;
288     }
289
290     if (!addPlugToProcessor(*outputPlug,p,
291         Streaming::Port::E_Capture)) {
292         debugFatal("Could not add plug to processor!\n");
293         delete p;
294         return false;
295     }
296
297     m_receiveProcessors.push_back(p);
298
299     // do the transmit processor
300     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n",
301             (snoopMode?" in snoop mode":""));
302     if (snoopMode) {
303         // we are snooping, so this is receive too.
304         p=new Streaming::AmdtpReceiveStreamProcessor(
305                                   get1394Service().getPort(),
306                                   samplerate,
307                                   inputPlug->getNrOfChannels());
308     } else {
309         p=new Streaming::AmdtpTransmitStreamProcessor(
310                                 get1394Service().getPort(),
311                                 samplerate,
312                                 inputPlug->getNrOfChannels());
313     }
314
315     if(!p->init()) {
316         debugFatal("Could not initialize transmit processor %s!\n",
317             (snoopMode?" in snoop mode":""));
318         delete p;
319         return false;
320     }
321
322     if (snoopMode) {
323         if (!addPlugToProcessor(*inputPlug,p,
324             Streaming::Port::E_Capture)) {
325             debugFatal("Could not add plug to processor!\n");
326             return false;
327         }
328     } else {
329         if (!addPlugToProcessor(*inputPlug,p,
330             Streaming::Port::E_Playback)) {
331             debugFatal("Could not add plug to processor!\n");
332             return false;
333         }
334     }
335
336     // we put this SP into the transmit SP vector,
337     // no matter if we are in snoop mode or not
338     // this allows us to find out what direction
339     // a certain stream should have.
340     m_transmitProcessors.push_back(p);
341
342     return true;
343 }
344
345 bool
346 AvDevice::addPlugToProcessor(
347     AVC::Plug& plug,
348     Streaming::StreamProcessor *processor,
349     Streaming::AmdtpAudioPort::E_Direction direction) {
350        
351     debugOutput(DEBUG_LEVEL_VERBOSE, " Adding plug %s to processor\n", plug.getName());
352
353     std::string id=std::string("dev?");
354     if(!getOption("id", id)) {
355         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
356     }
357
358     Plug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
359     for ( Plug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
360           it != clusterInfos.end();
361           ++it )
362     {
363         const Plug::ClusterInfo* clusterInfo = &( *it );
364        
365         debugOutput(DEBUG_LEVEL_VERBOSE, " Adding cluster %s\n", clusterInfo->m_name.c_str());
366
367         Plug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
368         for ( Plug::ChannelInfoVector::const_iterator it = channelInfos.begin();
369               it != channelInfos.end();
370               ++it )
371         {
372
373             const Plug::ChannelInfo* channelInfo = &( *it );
374            
375             std::ostringstream portname;
376
377             portname << id << "_" << channelInfo->m_name;
378
379             Streaming::Port *p=NULL;
380             switch(clusterInfo->m_portType) {
381             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
382             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
383             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
384             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
385             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
386                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding audio channel %s (pos=0x%02X, loc=0x%02X)\n",
387                     channelInfo->m_name.c_str(), channelInfo->m_streamPosition, channelInfo->m_location);
388                 p=new Streaming::AmdtpAudioPort(
389                         portname.str(),
390                         direction,
391                         channelInfo->m_streamPosition,
392                         channelInfo->m_location,
393                         Streaming::AmdtpPortInfo::E_MBLA
394                 );
395                 break;
396
397             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
398                 // HACK: for audiofire2 only !!!
399                 debugOutput(DEBUG_LEVEL_VERBOSE, " Adding MIDI channel %s (pos=0x%02X, loc=0x%02X)\n",
400                     channelInfo->m_name.c_str(), (direction==Streaming::Port::E_Capture?4:6),
401                     processor->getPortCount(Streaming::Port::E_Midi));
402                 p=new Streaming::AmdtpMidiPort(
403                         portname.str(),
404                         direction,
405                         (direction==Streaming::Port::E_Capture?4:6),
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             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
423             default:
424             // unsupported
425                 break;
426             }
427
428             if (!p) {
429                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
430             } else {
431
432                 if (!processor->addPort(p)) {
433                     debugWarning("Could not register port with stream processor\n");
434                     return false;
435                 }
436             }
437          }
438     }
439     return true;
440 }
441
442 int
443 AvDevice::getStreamCount() {
444     return m_receiveProcessors.size() + m_transmitProcessors.size();
445 }
446
447 Streaming::StreamProcessor *
448 AvDevice::getStreamProcessorByIndex(int i) {
449
450     if (i<(int)m_receiveProcessors.size()) {
451         return m_receiveProcessors.at(i);
452     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
453         return m_transmitProcessors.at(i-m_receiveProcessors.size());
454     }
455
456     return NULL;
457 }
458
459 bool
460 AvDevice::startStreamByIndex(int i) {
461     int iso_channel=-1;
462     bool snoopMode=false;
463     if(!getOption("snoopMode", snoopMode)) {
464         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
465     }
466
467     if (i<(int)m_receiveProcessors.size()) {
468         int n=i;
469         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
470
471         if(snoopMode) { // a stream from the device to another host
472             // FIXME: put this into a decent framework!
473             // we should check the oPCR[n] on the device
474             struct iec61883_oPCR opcr;
475             if (iec61883_get_oPCRX(
476                     get1394Service().getHandle(),
477                     m_pConfigRom->getNodeId() | 0xffc0,
478                     (quadlet_t *)&opcr,
479                     n)) {
480
481                 debugWarning("Error getting the channel for SP %d\n",i);
482                 return false;
483             }
484
485             iso_channel=opcr.channel;
486         } else {
487             iso_channel=get1394Service().allocateIsoChannelCMP(
488                 m_pConfigRom->getNodeId() | 0xffc0, n,
489                 get1394Service().getLocalNodeId()| 0xffc0, -1);
490         }
491         if (iso_channel<0) {
492             debugError("Could not allocate ISO channel for SP %d\n",i);
493             return false;
494         }
495
496         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
497
498         p->setChannel(iso_channel);
499         return true;
500
501     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
502         int n=i-m_receiveProcessors.size();
503         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
504
505         if(snoopMode) { // a stream from another host to the device
506             // FIXME: put this into a decent framework!
507             // we should check the iPCR[n] on the device
508             struct iec61883_iPCR ipcr;
509             if (iec61883_get_iPCRX(
510                     get1394Service().getHandle(),
511                     m_pConfigRom->getNodeId() | 0xffc0,
512                     (quadlet_t *)&ipcr,
513                     n)) {
514
515                 debugWarning("Error getting the channel for SP %d\n",i);
516                 return false;
517             }
518
519             iso_channel=ipcr.channel;
520
521         } else {
522             iso_channel=get1394Service().allocateIsoChannelCMP(
523                 get1394Service().getLocalNodeId()| 0xffc0, -1,
524                 m_pConfigRom->getNodeId() | 0xffc0, n);
525         }
526
527         if (iso_channel<0) {
528             debugError("Could not allocate ISO channel for SP %d\n",i);
529             return false;
530         }
531
532         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
533
534         p->setChannel(iso_channel);
535         return true;
536     }
537
538     debugError("SP index %d out of range!\n",i);
539     return false;
540 }
541
542 bool
543 AvDevice::stopStreamByIndex(int i) {
544     bool snoopMode=false;
545     if(!getOption("snoopMode", snoopMode)) {
546         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
547     }
548
549     if (i<(int)m_receiveProcessors.size()) {
550         int n=i;
551         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
552
553         if(snoopMode) {
554
555         } else {
556             // deallocate ISO channel
557             if(!get1394Service().freeIsoChannel(p->getChannel())) {
558                 debugError("Could not deallocate iso channel for SP %d\n",i);
559                 return false;
560             }
561         }
562         p->setChannel(-1);
563
564         return true;
565
566     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
567         int n=i-m_receiveProcessors.size();
568         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
569
570         if(snoopMode) {
571
572         } else {
573             // deallocate ISO channel
574             if(!get1394Service().freeIsoChannel(p->getChannel())) {
575                 debugError("Could not deallocate iso channel for SP %d\n",i);
576                 return false;
577             }
578         }
579         p->setChannel(-1);
580
581         return true;
582     }
583
584     debugError("SP index %d out of range!\n",i);
585     return false;
586 }
587
588 }
Note: See TracBrowser for help on using the browser.