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

Revision 630, 18.6 kB (checked in by wagi, 15 years ago)

Some more fixing of the cashing code. The loading is still disabled because it seems not to work right. But at least it doesn't crash anymore. Some further debugging is
needed.

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 bool
594 AvDevice::serialize( Glib::ustring basePath, Util::IOSerialize& ser ) const
595 {
596     bool result;
597     result  = AVC::Unit::serialize( basePath, ser );
598     result &= serializeOptions( basePath + "Options", ser );
599     return result;
600 }
601
602 bool
603 AvDevice::deserialize( Glib::ustring basePath, Util::IODeserialize& deser )
604 {
605     bool result;
606     result = AVC::Unit::deserialize( basePath, deser );
607     return result;
608 }
609
610 }
Note: See TracBrowser for help on using the browser.