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

Revision 612, 18.2 kB (checked in by ppalmers, 15 years ago)

- Remove dependencies between BeBoB and generic AVC code (functionblocks)
- Clean up the code at some places

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