root/branches/echoaudio/src/devicemanager.cpp

Revision 509, 17.2 kB (checked in by ppalmers, 17 years ago)

- Moved all generic stuff but the functionblocks over to libavc
- compiles and works

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Copyright (C) 2005-2007 by Daniel Wagner
3  * Copyright (C) 2005-2007 by Pieter Palmers
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 "fbtypes.h"
26
27 #include "devicemanager.h"
28 #include "ffadodevice.h"
29
30 #include "libieee1394/configrom.h"
31 #include "libieee1394/ieee1394service.h"
32
33 #include "debugmodule/debugmodule.h"
34
35 #include <iostream>
36 #include <sstream>
37
38 #include <unistd.h>
39
40 #include "libstreaming/StreamProcessor.h"
41
42 #ifdef ENABLE_BEBOB
43     #include "bebob/bebob_avdevice.h"
44     #include "maudio/maudio_avdevice.h"
45 #endif
46
47 #ifdef ENABLE_GENERICAVC
48     #include "genericavc/avc_avdevice.h"
49 #endif
50
51 #ifdef ENABLE_BOUNCE
52     #include "bounce/bounce_avdevice.h"
53     #include "bounce/bounce_slave_avdevice.h"
54 #endif
55
56 #ifdef ENABLE_MOTU
57 #include "motu/motu_avdevice.h"
58 #endif
59
60 #ifdef ENABLE_RME
61 #include "rme/rme_avdevice.h"
62 #endif
63
64 #ifdef ENABLE_DICE
65 #include "dice/dice_avdevice.h"
66 #endif
67
68 #ifdef ENABLE_METRIC_HALO
69 #include "metrichalo/mh_avdevice.h"
70 #endif
71
72 using namespace std;
73
74 IMPL_DEBUG_MODULE( DeviceManager, DeviceManager, DEBUG_LEVEL_NORMAL );
75
76 DeviceManager::DeviceManager()
77     : OscNode("devicemanager")
78     , m_1394Service( 0 )
79     , m_oscServer( NULL )
80 {
81     addOption(Util::OptionContainer::Option("slaveMode",false));
82     addOption(Util::OptionContainer::Option("snoopMode",false));
83 }
84
85 DeviceManager::~DeviceManager()
86 {
87     if (m_oscServer) {
88         m_oscServer->stop();
89         delete m_oscServer;
90     }
91
92     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
93           it != m_avDevices.end();
94           ++it )
95     {
96         delete *it;
97     }
98
99     delete m_1394Service;
100 }
101
102 void
103 DeviceManager::setVerboseLevel(int l)
104 {
105     debugOutput( DEBUG_LEVEL_NORMAL, "Setting verbose level to %d...\n", l );
106     setDebugLevel(l);
107
108     if (m_1394Service) m_1394Service->setVerboseLevel(l);
109     if (m_oscServer) m_oscServer->setVerboseLevel(l);
110     OscNode::setVerboseLevel(l);
111
112     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
113           it != m_avDevices.end();
114           ++it )
115     {
116         (*it)->setVerboseLevel(l);
117     }
118 }
119
120 bool
121 DeviceManager::initialize( int port )
122 {
123     m_1394Service = new Ieee1394Service();
124     if ( !m_1394Service ) {
125         debugFatal( "Could not create Ieee1349Service object\n" );
126         return false;
127     }
128
129     if ( !m_1394Service->initialize( port ) ) {
130         debugFatal( "Could not initialize Ieee1349Service object\n" );
131         delete m_1394Service;
132         m_1394Service = 0;
133         return false;
134     }
135
136 //     m_oscServer = new OSC::OscServer("17820");
137 //
138 //     if (!m_oscServer) {
139 //         debugFatal("failed to create osc server\n");
140 //         delete m_1394Service;
141 //         m_1394Service = 0;
142 //         return false;
143 //     }
144 //
145 //     if (!m_oscServer->init()) {
146 //         debugFatal("failed to init osc server\n");
147 //         delete m_oscServer;
148 //         m_oscServer = NULL;
149 //         delete m_1394Service;
150 //         m_1394Service = 0;
151 //         return false;
152 //     }
153 //
154 //     if (!m_oscServer->registerAtRootNode(this)) {
155 //         debugFatal("failed to register devicemanager at server\n");
156 //         delete m_oscServer;
157 //         m_oscServer = NULL;
158 //         delete m_1394Service;
159 //         m_1394Service = 0;
160 //         return false;
161 //     }
162 //
163 //     if (!m_oscServer->start()) {
164 //         debugFatal("failed to start osc server\n");
165 //         delete m_oscServer;
166 //         m_oscServer = NULL;
167 //         delete m_1394Service;
168 //         m_1394Service = 0;
169 //         return false;
170 //     }
171
172     setVerboseLevel(getDebugLevel());
173     return true;
174 }
175
176 bool
177 DeviceManager::discover( )
178 {
179     bool slaveMode=false;
180     if(!getOption("slaveMode", slaveMode)) {
181         debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
182     }
183     bool snoopMode=false;
184     if(!getOption("snoopMode", snoopMode)) {
185         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
186     }
187
188     setVerboseLevel(getDebugLevel());
189
190     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
191           it != m_avDevices.end();
192           ++it )
193     {
194         if (!removeChildOscNode(*it)) {
195             debugWarning("failed to unregister AvDevice from OSC server\n");
196         }
197         delete *it;
198     }
199     m_avDevices.clear();
200
201     if (!slaveMode) {
202         for ( fb_nodeid_t nodeId = 0;
203               nodeId < m_1394Service->getNodeCount();
204               ++nodeId )
205         {
206             debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
207
208             if (nodeId == m_1394Service->getLocalNodeId()) {
209                 debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
210                 continue;
211             }
212
213             std::auto_ptr<ConfigRom> configRom =
214                 std::auto_ptr<ConfigRom>( new ConfigRom( *m_1394Service,
215                                                          nodeId ) );
216             if ( !configRom->initialize() ) {
217                 // \todo If a PHY on the bus is in power safe mode then
218                 // the config rom is missing. So this might be just
219                 // such this case and we can safely skip it. But it might
220                 // be there is a real software problem on our side.
221                 // This should be handled more carefuly.
222                 debugOutput( DEBUG_LEVEL_NORMAL,
223                              "Could not read config rom from device (node id %d). "
224                              "Skip device discovering for this node\n",
225                              nodeId );
226                 continue;
227             }
228
229             FFADODevice* avDevice = getDriverForDevice( configRom,
230                                                         nodeId );
231             if ( avDevice ) {
232                 debugOutput( DEBUG_LEVEL_NORMAL,
233                              "discover: driver found for device %d\n",
234                              nodeId );
235
236                 avDevice->setVerboseLevel( getDebugLevel() );
237
238                 if ( !avDevice->discover() ) {
239                     debugError( "discover: could not discover device\n" );
240                     delete avDevice;
241                     continue;
242                 }
243
244                 if ( !avDevice->setId( m_avDevices.size() ) ) {
245                     debugError( "setting Id failed\n" );
246                 }
247
248                 if (snoopMode) {
249                     debugOutput( DEBUG_LEVEL_VERBOSE,
250                                  "Enabling snoop mode on node %d...\n", nodeId );
251
252                     if(!avDevice->setOption("snoopMode", snoopMode)) {
253                         debugWarning("Could not set snoop mode for device on node %d\n", nodeId);
254                         delete avDevice;
255                         continue;
256                     }
257                 }
258
259                 if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
260                     avDevice->showDevice();
261                 }
262
263                 m_avDevices.push_back( avDevice );
264
265                 if (!addChildOscNode(avDevice)) {
266                     debugWarning("failed to register AvDevice at OSC server\n");
267                 }
268                
269                 debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d done...\n", nodeId );
270
271             }
272         }
273
274         debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
275
276         return true;
277
278     } else { // slave mode
279         fb_nodeid_t nodeId = m_1394Service->getLocalNodeId();
280         debugOutput( DEBUG_LEVEL_VERBOSE, "Starting in slave mode on node %d...\n", nodeId );
281
282         std::auto_ptr<ConfigRom> configRom =
283             std::auto_ptr<ConfigRom>( new ConfigRom( *m_1394Service,
284                                                      nodeId ) );
285         if ( !configRom->initialize() ) {
286             // \todo If a PHY on the bus is in power safe mode then
287             // the config rom is missing. So this might be just
288             // such this case and we can safely skip it. But it might
289             // be there is a real software problem on our side.
290             // This should be handled more carefuly.
291             debugOutput( DEBUG_LEVEL_NORMAL,
292                          "Could not read config rom from device (node id %d). "
293                          "Skip device discovering for this node\n",
294                          nodeId );
295             return false;
296         }
297
298         FFADODevice* avDevice = getSlaveDriver( configRom );
299         if ( avDevice ) {
300             debugOutput( DEBUG_LEVEL_NORMAL,
301                          "discover: driver found for device %d\n",
302                          nodeId );
303
304             avDevice->setVerboseLevel( getDebugLevel() );
305
306             if ( !avDevice->discover() ) {
307                 debugError( "discover: could not discover device\n" );
308                 delete avDevice;
309                 return false;
310             }
311
312             if ( !avDevice->setId( m_avDevices.size() ) ) {
313                 debugError( "setting Id failed\n" );
314             }
315             if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
316                 avDevice->showDevice();
317             }
318
319             m_avDevices.push_back( avDevice );
320
321             debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d done...\n", nodeId );
322         }
323
324         debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
325
326         return true;
327     }
328 }
329
330
331 FFADODevice*
332 DeviceManager::getDriverForDevice( std::auto_ptr<ConfigRom>( configRom ),
333                                    int id )
334 {
335 #ifdef ENABLE_BEBOB
336     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying BeBoB...\n" );
337     if ( BeBoB::AvDevice::probe( *configRom.get() ) ) {
338         return new BeBoB::AvDevice( configRom, *m_1394Service, id );
339     }
340 #endif
341
342 #ifdef ENABLE_GENERICAVC
343     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" );
344     if ( GenericAVC::AvDevice::probe( *configRom.get() ) ) {
345         return new GenericAVC::AvDevice( configRom, *m_1394Service, id );
346     }
347 #endif
348
349 #ifdef ENABLE_BEBOB
350     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying M-Audio...\n" );
351     if ( MAudio::AvDevice::probe( *configRom.get() ) ) {
352         return new MAudio::AvDevice( configRom, *m_1394Service, id );
353     }
354 #endif
355
356 #ifdef ENABLE_MOTU
357     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Motu...\n" );
358     if ( Motu::MotuDevice::probe( *configRom.get() ) ) {
359         return new Motu::MotuDevice( configRom, *m_1394Service, id );
360     }
361 #endif
362
363 #ifdef ENABLE_DICE
364     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Dice...\n" );
365     if ( Dice::DiceAvDevice::probe( *configRom.get() ) ) {
366         return new Dice::DiceAvDevice( configRom, *m_1394Service, id );
367     }
368 #endif
369
370 #ifdef ENABLE_METRIC_HALO
371     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Metric Halo...\n" );
372     if ( MetricHalo::MHAvDevice::probe( *configRom.get() ) ) {
373         return new MetricHalo::MHAvDevice( configRom, *m_1394Service, id );
374     }
375 #endif
376
377 #ifdef ENABLE_RME
378     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying RME...\n" );
379     if ( Rme::RmeDevice::probe( *configRom.get() ) ) {
380         return new Rme::RmeDevice( configRom, *m_1394Service, id );
381     }
382 #endif
383
384 #ifdef ENABLE_BOUNCE
385     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Bounce...\n" );
386     if ( Bounce::BounceDevice::probe( *configRom.get() ) ) {
387         return new Bounce::BounceDevice( configRom, *m_1394Service, id );
388     }
389 #endif
390
391     return 0;
392 }
393
394 FFADODevice*
395 DeviceManager::getSlaveDriver( std::auto_ptr<ConfigRom>( configRom ) )
396 {
397
398 #ifdef ENABLE_BOUNCE
399     if ( Bounce::BounceSlaveDevice::probe( *configRom.get() ) ) {
400         return new Bounce::BounceSlaveDevice( configRom, *m_1394Service );
401     }
402 #endif
403
404     return 0;
405 }
406
407 bool
408 DeviceManager::isValidNode(int node)
409 {
410     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
411           it != m_avDevices.end();
412           ++it )
413     {
414         FFADODevice* avDevice = *it;
415
416         if (avDevice->getConfigRom().getNodeId() == node) {
417             return true;
418     }
419     }
420     return false;
421 }
422
423 int
424 DeviceManager::getNbDevices()
425 {
426     return m_avDevices.size();
427 }
428
429 int
430 DeviceManager::getDeviceNodeId( int deviceNr )
431 {
432     if ( ! ( deviceNr < getNbDevices() ) ) {
433         debugError( "Device number out of range (%d)\n", deviceNr );
434         return -1;
435     }
436
437     FFADODevice* avDevice = m_avDevices.at( deviceNr );
438
439     if ( !avDevice ) {
440         debugError( "Could not get device at position (%d)\n",  deviceNr );
441     }
442
443     return avDevice->getConfigRom().getNodeId();
444 }
445
446 FFADODevice*
447 DeviceManager::getAvDevice( int nodeId )
448 {
449     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
450           it != m_avDevices.end();
451           ++it )
452     {
453         FFADODevice* avDevice = *it;
454         if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
455             return avDevice;
456         }
457     }
458
459     return 0;
460 }
461
462 FFADODevice*
463 DeviceManager::getAvDeviceByIndex( int idx )
464 {
465     return m_avDevices.at(idx);
466 }
467
468 unsigned int
469 DeviceManager::getAvDeviceCount( )
470 {
471     return m_avDevices.size();
472 }
473
474 /**
475  * Return the streamprocessor that is to be used as
476  * the sync source.
477  *
478  * Algorithm still to be determined
479  *
480  * @return StreamProcessor that is sync source
481  */
482 Streaming::StreamProcessor *
483 DeviceManager::getSyncSource() {
484     FFADODevice* device = getAvDeviceByIndex(0);
485
486     bool slaveMode=false;
487     if(!getOption("slaveMode", slaveMode)) {
488         debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
489     }
490
491     #warning TEST CODE FOR BOUNCE DEVICE !!
492     // this makes the bounce slave use the xmit SP as sync source
493     if (slaveMode) {
494         return device->getStreamProcessorByIndex(1);
495     } else {
496         return device->getStreamProcessorByIndex(0);
497     }
498 }
499
500 bool
501 DeviceManager::deinitialize()
502 {
503     return true;
504 }
505
506 bool
507 DeviceManager::saveCache( Glib::ustring fileName )
508 {
509     int i;
510     i=0; // avoids unused warning
511
512     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
513           it != m_avDevices.end();
514           ++it )
515     {
516         FFADODevice* pAvDevice;
517         pAvDevice = *it; // avoids unused warning
518
519         #ifdef ENABLE_BEBOB
520         BeBoB::AvDevice* pBeBoBDevice = reinterpret_cast< BeBoB::AvDevice* >( pAvDevice );
521         if ( pBeBoBDevice ) {
522             // Let's use a very simple path to find the devices later.
523             // Since under hood there will an xml node name this should
524             // adhere the needed naming rules. Of course we could give it
525             // a good node name and add an attribute but that would mean
526             // we have to expose a bigger interface from IOSerialize/IODesialize,
527             // which is just not needed. KISS.
528             ostringstream strstrm;
529             strstrm << "id" << i;
530             Glib::ustring basePath = "BeBoB/" + strstrm.str() + "/";
531
532             Util::XMLSerialize ser( fileName );
533             pBeBoBDevice->serialize( basePath, ser );
534
535             i++;
536             std::cout << "a bebob device serialized" << std::endl;
537         }
538         #endif
539     }
540     return true;
541 }
542
543 bool
544 DeviceManager::loadCache( Glib::ustring fileName )
545 {
546     int i;
547     i=0; // avoids unused warning
548     Util::XMLDeserialize deser( fileName );
549
550     typedef std::vector<ConfigRom*> ConfigRomVector;
551     ConfigRomVector configRoms;
552
553     for ( fb_nodeid_t nodeId = 0;
554           nodeId < m_1394Service->getNodeCount();
555           ++nodeId )
556     {
557         ConfigRom* pConfigRom  =  new ConfigRom( *m_1394Service, nodeId );
558         if ( !pConfigRom->initialize() ) {
559             // \todo If a PHY on the bus is in power safe mode then
560             // the config rom is missing. So this might be just
561             // such this case and we can safely skip it. But it might
562             // be there is a real software problem on our side.
563             // This should be handled more carefuly.
564             debugOutput( DEBUG_LEVEL_NORMAL,
565                          "Could not read config rom from device (node id %d). "
566                          "Skip device discovering for this node\n",
567                          nodeId );
568             delete pConfigRom;
569             continue;
570         }
571         configRoms.push_back( pConfigRom );
572     }
573
574     #ifdef ENABLE_BEBOB
575     BeBoB::AvDevice* pBeBoBDevice = 0;
576     do {
577         ostringstream strstrm;
578         strstrm << "id" << i;
579         pBeBoBDevice = BeBoB::AvDevice::deserialize(
580             "BeBoB/" + strstrm.str() + "/",
581             deser,
582             *m_1394Service );
583
584         ++i;
585         if ( pBeBoBDevice ) {
586             for (ConfigRomVector::iterator it = configRoms.begin();
587                  it != configRoms.end();
588                  ++it )
589             {
590                 ConfigRom* pConfigRom = *it;
591
592                 if ( pBeBoBDevice->getConfigRom() == *pConfigRom ) {
593                     pBeBoBDevice->getConfigRom().setNodeId( pConfigRom->getNodeId() );
594                     // m_avDevices.push_back( pBeBoBDevice );
595
596                 }
597             }
598         }
599     } while ( pBeBoBDevice );
600     #endif
601
602     return true;
603 }
Note: See TracBrowser for help on using the browser.