root/trunk/libffado/src/devicemanager.cpp

Revision 967, 31.6 kB (checked in by ppalmers, 16 years ago)

- first attempt at not causing total havoc when devices are removed from the bus.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Copyright (C) 2005-2008 by Daniel Wagner
3  * Copyright (C) 2005-2008 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 program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include "fbtypes.h"
26
27 #include "devicemanager.h"
28 #include "ffadodevice.h"
29 #include "DeviceStringParser.h"
30
31 #include "libieee1394/configrom.h"
32 #include "libieee1394/ieee1394service.h"
33
34 #include "libstreaming/generic/StreamProcessor.h"
35 #include "libstreaming/StreamProcessorManager.h"
36
37 #include "debugmodule/debugmodule.h"
38
39 #ifdef ENABLE_BEBOB
40 #include "bebob/bebob_avdevice.h"
41 #include "maudio/maudio_avdevice.h"
42 #endif
43
44 #ifdef ENABLE_GENERICAVC
45     #include "genericavc/avc_avdevice.h"
46 #endif
47
48 #ifdef ENABLE_FIREWORKS
49     #include "fireworks/fireworks_device.h"
50 #endif
51
52 #ifdef ENABLE_BOUNCE
53 #include "bounce/bounce_avdevice.h"
54 #include "bounce/bounce_slave_avdevice.h"
55 #endif
56
57 #ifdef ENABLE_MOTU
58 #include "motu/motu_avdevice.h"
59 #endif
60
61 #ifdef ENABLE_RME
62 #include "rme/rme_avdevice.h"
63 #endif
64
65 #ifdef ENABLE_DICE
66 #include "dice/dice_avdevice.h"
67 #endif
68
69 #ifdef ENABLE_METRIC_HALO
70 #include "metrichalo/mh_avdevice.h"
71 #endif
72
73 #include <iostream>
74 #include <sstream>
75
76 #include <algorithm>
77
78 using namespace std;
79
80 IMPL_DEBUG_MODULE( DeviceManager, DeviceManager, DEBUG_LEVEL_NORMAL );
81
82 DeviceManager::DeviceManager()
83     : Control::Container("devicemanager")
84     , m_processorManager( new Streaming::StreamProcessorManager() )
85     , m_deviceStringParser( new DeviceStringParser() )
86     , m_used_cache_last_time( false )
87     , m_ignore_busreset( false )
88 {
89     addOption(Util::OptionContainer::Option("slaveMode",false));
90     addOption(Util::OptionContainer::Option("snoopMode",false));
91 }
92
93 DeviceManager::~DeviceManager()
94 {
95     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
96           it != m_avDevices.end();
97           ++it )
98     {
99         if (!deleteElement(*it)) {
100             debugWarning("failed to remove AvDevice from Control::Container\n");
101         }
102         delete *it;
103     }
104
105     // the SP's are automatically unregistered at the SPM
106     delete m_processorManager;
107
108     for ( FunctorVectorIterator it = m_busreset_functors.begin();
109           it != m_busreset_functors.end();
110           ++it )
111     {
112         delete *it;
113     }
114
115     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
116           it != m_1394Services.end();
117           ++it )
118     {
119         delete *it;
120     }
121
122     delete m_deviceStringParser;
123 }
124
125 bool
126 DeviceManager::setThreadParameters(bool rt, int priority) {
127     if (!m_processorManager->setThreadParameters(rt, priority)) {
128         debugError("Could not set processor manager thread parameters\n");
129         return false;
130     }
131     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
132           it != m_1394Services.end();
133           ++it )
134     {
135         if (!(*it)->setThreadParameters(rt, priority)) {
136             debugError("Could not set 1394 service thread parameters\n");
137             return false;
138         }
139     }
140     m_thread_realtime = rt;
141     m_thread_priority = priority;
142     return true;
143 }
144
145 bool
146 DeviceManager::initialize()
147 {
148     assert(m_1394Services.size() == 0);
149     assert(m_busreset_functors.size() == 0);
150
151     int nb_detected_ports = Ieee1394Service::detectNbPorts();
152     if (nb_detected_ports < 0) {
153         debugFatal("Failed to detect the number of 1394 adapters. Is the IEEE1394 stack loaded (raw1394)?\n");
154         return false;
155     }
156     if (nb_detected_ports == 0) {
157         debugFatal("No firewire adapters (ports) found.\n");
158         return false;
159     }
160     debugOutput( DEBUG_LEVEL_VERBOSE, "Found %d firewire adapters (ports)\n", nb_detected_ports);
161     for (unsigned int port = 0; port < (unsigned int)nb_detected_ports; port++) {
162         Ieee1394Service* tmp1394Service = new Ieee1394Service();
163         if ( !tmp1394Service ) {
164             debugFatal( "Could not create Ieee1349Service object for port %d\n", port );
165             return false;
166         }
167         tmp1394Service->setVerboseLevel( getDebugLevel() );
168         m_1394Services.push_back(tmp1394Service);
169
170         tmp1394Service->setThreadParameters(m_thread_realtime, m_thread_priority);
171         if ( !tmp1394Service->initialize( port ) ) {
172             debugFatal( "Could not initialize Ieee1349Service object for port %d\n", port );
173             return false;
174         }
175         // add the bus reset handler
176         Util::Functor* tmp_busreset_functor = new Util::MemberFunctor0< DeviceManager*,
177                     void (DeviceManager::*)() >
178                     ( this, &DeviceManager::busresetHandler, false );
179         if ( !tmp_busreset_functor ) {
180             debugFatal( "Could not create busreset handler for port %d\n", port );
181             return false;
182         }
183         m_busreset_functors.push_back(tmp_busreset_functor);
184
185         tmp1394Service->addBusResetHandler( tmp_busreset_functor );
186     }
187
188     return true;
189 }
190
191 bool
192 DeviceManager::addSpecString(char *s) {
193     std::string spec = s;
194     if(isSpecStringValid(spec)) {
195         debugOutput(DEBUG_LEVEL_VERBOSE, "Adding spec string %s\n", spec.c_str());
196         assert(m_deviceStringParser);
197         m_deviceStringParser->parseString(spec);
198         return true;
199     } else {
200         debugError("Invalid spec string: %s\n", spec.c_str());
201         return false;
202     }
203 }
204
205 bool
206 DeviceManager::isSpecStringValid(std::string s) {
207     assert(m_deviceStringParser);
208     return m_deviceStringParser->isValidString(s);
209 }
210
211 void
212 DeviceManager::busresetHandler()
213 {
214     debugOutput( DEBUG_LEVEL_VERBOSE, "Bus reset...\n" );
215     if(m_ignore_busreset) {
216         debugOutput( DEBUG_LEVEL_VERBOSE, " ignoring...\n" );
217         return;
218     }
219
220     // FIXME: what port was the bus reset on?
221     // propagate the bus reset to all avDevices
222     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
223           it != m_avDevices.end();
224           ++it )
225     {
226         (*it)->handleBusReset();
227     }
228
229     // notify the streamprocessormanager of the busreset
230     if(m_processorManager) {
231         m_processorManager->handleBusReset();
232     } else {
233         debugWarning("No valid SPM\n");
234     }
235
236     // rediscover to find new devices
237     // (only for the control server ATM, streaming can't dynamically add/remove devices)
238     if(!discover(m_used_cache_last_time, true)) {
239         debugError("Could not rediscover devices\n");
240     }
241
242     // notify any clients
243     for ( busreset_notif_vec_t::iterator it = m_busResetNotifiers.begin();
244           it != m_busResetNotifiers.end();
245           ++it )
246     {
247         Util::Functor* func = *it;
248         debugOutput( DEBUG_LEVEL_VERBOSE, " running notifier %p...\n", func );
249         ( *func )();
250     }
251 }
252
253 bool
254 DeviceManager::registerBusresetNotification(Util::Functor *handler)
255 {
256     debugOutput( DEBUG_LEVEL_VERBOSE, "register %p...\n", handler);
257     assert(handler);
258     for ( busreset_notif_vec_t::iterator it = m_busResetNotifiers.begin();
259       it != m_busResetNotifiers.end();
260       ++it )
261     {
262         if ( *it == handler ) {
263             debugOutput(DEBUG_LEVEL_VERBOSE, "already registered\n");
264             return false;
265         }
266     }
267     m_busResetNotifiers.push_back(handler);
268     return true;
269 }
270
271 bool
272 DeviceManager::unregisterBusresetNotification(Util::Functor *handler)
273 {
274     debugOutput( DEBUG_LEVEL_VERBOSE, "unregister %p...\n", handler);
275     assert(handler);
276
277     for ( busreset_notif_vec_t::iterator it = m_busResetNotifiers.begin();
278       it != m_busResetNotifiers.end();
279       ++it )
280     {
281         if ( *it == handler ) {
282             m_busResetNotifiers.erase(it);
283             return true;
284         }
285     }
286     debugError("Could not find handler (%p)\n", handler);
287     return false; //not found
288 }
289
290 bool
291 DeviceManager::discover( bool useCache, bool rediscover )
292 {
293     m_used_cache_last_time = useCache;
294     bool slaveMode=false;
295     if(!getOption("slaveMode", slaveMode)) {
296         debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
297     }
298     bool snoopMode=false;
299     if(!getOption("snoopMode", snoopMode)) {
300         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
301     }
302
303     setVerboseLevel(getDebugLevel());
304
305     ConfigRomVector configRoms;
306     // build a list of configroms on the bus.
307     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
308         it != m_1394Services.end();
309         ++it )
310     {
311         Ieee1394Service *portService = *it;
312         for ( fb_nodeid_t nodeId = 0;
313             nodeId < portService->getNodeCount();
314             ++nodeId )
315         {
316             debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
317
318             if (nodeId == portService->getLocalNodeId()) {
319                 debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
320                 continue;
321             }
322
323             ConfigRom * configRom = new ConfigRom( *portService, nodeId );
324             if ( !configRom->initialize() ) {
325                 // \todo If a PHY on the bus is in power safe mode then
326                 // the config rom is missing. So this might be just
327                 // such this case and we can safely skip it. But it might
328                 // be there is a real software problem on our side.
329                 // This should be handlede more carefuly.
330                 debugOutput( DEBUG_LEVEL_NORMAL,
331                             "Could not read config rom from device (node id %d). "
332                             "Skip device discovering for this node\n",
333                             nodeId );
334                 continue;
335             }
336             configRoms.push_back(configRom);
337         }
338     }
339
340     if(rediscover) {
341         FFADODeviceVector discovered_devices_on_bus;
342         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
343             it != m_avDevices.end();
344             ++it )
345         {
346             bool seen_device = false;
347             for ( ConfigRomVectorIterator it2 = configRoms.begin();
348                 it2 != configRoms.end();
349                 ++it2 )
350             {
351                 seen_device |= ((*it)->getConfigRom().getGuid() == (*it2)->getGuid());
352             }
353
354             if(seen_device) {
355                 debugOutput( DEBUG_LEVEL_VERBOSE,
356                             "Already discovered device with GUID: %s\n",
357                             (*it)->getConfigRom().getGuidString().c_str() );
358                 // we already discovered this device, and it is still here. keep it
359                 discovered_devices_on_bus.push_back(*it);
360             } else {
361                 debugOutput( DEBUG_LEVEL_VERBOSE,
362                             "Device with GUID: %s disappeared from bus, removing...\n",
363                             (*it)->getConfigRom().getGuidString().c_str() );
364
365                 // the device has disappeared, remove it from the control tree
366                 if (!deleteElement(*it)) {
367                     debugWarning("failed to remove AvDevice from Control::Container\n");
368                 }
369                 // delete the device
370                 // FIXME: this will mess up the any code that waits for bus resets to
371                 //        occur
372                 delete *it;
373             }
374         }
375         // prune the devices that disappeared
376         m_avDevices = discovered_devices_on_bus;
377     } else { // remove everything since we are not rediscovering
378         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
379             it != m_avDevices.end();
380             ++it )
381         {
382             if (!deleteElement(*it)) {
383                 debugWarning("failed to remove AvDevice from Control::Container\n");
384             }
385             delete *it;
386         }
387
388         m_avDevices.clear();
389     }
390
391     // delete the config rom list entries
392     // FIXME: we should reuse it
393     for ( ConfigRomVectorIterator it = configRoms.begin();
394         it != configRoms.end();
395         ++it )
396     {
397         delete *it;
398     }
399
400     assert(m_deviceStringParser);
401     // show the spec strings we're going to use
402     if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
403         m_deviceStringParser->show();
404     }
405
406     if (!slaveMode) {
407         for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
408             it != m_1394Services.end();
409             ++it )
410         {
411             Ieee1394Service *portService = *it;
412             for ( fb_nodeid_t nodeId = 0;
413                 nodeId < portService->getNodeCount();
414                 ++nodeId )
415             {
416                 debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
417    
418                 if (nodeId == portService->getLocalNodeId()) {
419                     debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
420                     continue;
421                 }
422    
423                 std::auto_ptr<ConfigRom> configRom =
424                     std::auto_ptr<ConfigRom>( new ConfigRom( *portService, nodeId ) );
425                 if ( !configRom->initialize() ) {
426                     // \todo If a PHY on the bus is in power safe mode then
427                     // the config rom is missing. So this might be just
428                     // such this case and we can safely skip it. But it might
429                     // be there is a real software problem on our side.
430                     // This should be handlede more carefuly.
431                     debugOutput( DEBUG_LEVEL_NORMAL,
432                                 "Could not read config rom from device (node id %d). "
433                                 "Skip device discovering for this node\n",
434                                 nodeId );
435                     continue;
436                 }
437
438                 bool already_in_vector = false;
439                 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
440                     it != m_avDevices.end();
441                     ++it )
442                 {
443                     if ((*it)->getConfigRom().getGuid() == configRom->getGuid()) {
444                         already_in_vector = true;
445                         break;
446                     }
447                 }
448                 if(already_in_vector) {
449                     if(!rediscover) {
450                         debugWarning("Device with GUID %s already discovered on other port, skipping device...\n",
451                                     configRom->getGuidString().c_str());
452                     }
453                     continue;
454                 }
455
456                 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
457                     configRom->printConfigRomDebug();
458                 }
459
460                 // if spec strings are given, only add those devices
461                 // that match the spec string(s).
462                 // if no (valid) spec strings are present, grab all
463                 // supported devices.
464                 if(m_deviceStringParser->countDeviceStrings() &&
465                   !m_deviceStringParser->match(*configRom.get())) {
466                     debugOutput(DEBUG_LEVEL_VERBOSE, "Device doesn't match any of the spec strings. skipping...\n");
467                     continue;
468                 }
469
470                 // find a driver
471                 FFADODevice* avDevice = getDriverForDevice( configRom,
472                                                             nodeId );
473
474                 if ( avDevice ) {
475                     debugOutput( DEBUG_LEVEL_NORMAL,
476                                 "driver found for device %d\n",
477                                 nodeId );
478
479                     avDevice->setVerboseLevel( getDebugLevel() );
480                     bool isFromCache = false;
481                     if ( useCache && avDevice->loadFromCache() ) {
482                         debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" );
483                         isFromCache = true;
484                         // restore the debug level for everything that was loaded
485                         avDevice->setVerboseLevel( getDebugLevel() );
486                     } else if ( avDevice->discover() ) {
487                         debugOutput( DEBUG_LEVEL_VERBOSE, "discovery successful\n" );
488                     } else {
489                         debugError( "could not discover device\n" );
490                         delete avDevice;
491                         continue;
492                     }
493
494                     if (snoopMode) {
495                         debugOutput( DEBUG_LEVEL_VERBOSE,
496                                     "Enabling snoop mode on node %d...\n", nodeId );
497
498                         if(!avDevice->setOption("snoopMode", snoopMode)) {
499                             debugWarning("Could not set snoop mode for device on node %d\n", nodeId);
500                             delete avDevice;
501                             continue;
502                         }
503                     }
504
505                     if ( !isFromCache && !avDevice->saveCache() ) {
506                         debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
507                     }
508                     m_avDevices.push_back( avDevice );
509
510                     if (!addElement(avDevice)) {
511                         debugWarning("failed to add AvDevice to Control::Container\n");
512                     }
513
514                     debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
515                 }
516             }
517         }
518
519         debugOutput( DEBUG_LEVEL_NORMAL, "Discovery finished...\n" );
520         // FIXME: do better sorting
521         // sort the m_avDevices vector on their GUID
522         // then assign reassign the id's to the devices
523         // the side effect of this is that for the same set of attached devices,
524         // a device id always corresponds to the same device
525         sort(m_avDevices.begin(), m_avDevices.end(), FFADODevice::compareGUID);
526         int i=0;
527         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
528             it != m_avDevices.end();
529             ++it )
530         {
531             if ( !(*it)->setId( i++ ) ) {
532                 debugError( "setting Id failed\n" );
533             }
534         }
535         showDeviceInfo();
536         return true;
537     } else { // slave mode
538         Ieee1394Service *portService = m_1394Services.at(0);
539         fb_nodeid_t nodeId = portService->getLocalNodeId();
540         debugOutput( DEBUG_LEVEL_VERBOSE, "Starting in slave mode on node %d...\n", nodeId );
541
542         std::auto_ptr<ConfigRom> configRom =
543             std::auto_ptr<ConfigRom>( new ConfigRom( *portService,
544                                                      nodeId ) );
545         if ( !configRom->initialize() ) {
546             // \todo If a PHY on the bus is in power safe mode then
547             // the config rom is missing. So this might be just
548             // such this case and we can safely skip it. But it might
549             // be there is a real software problem on our side.
550             // This should be handled more carefuly.
551             debugOutput( DEBUG_LEVEL_NORMAL,
552                          "Could not read config rom from device (node id %d). "
553                          "Skip device discovering for this node\n",
554                          nodeId );
555             return false;
556         }
557
558         FFADODevice* avDevice = getSlaveDriver( configRom );
559         if ( avDevice ) {
560             debugOutput( DEBUG_LEVEL_NORMAL,
561                          "driver found for device %d\n",
562                          nodeId );
563
564             avDevice->setVerboseLevel( getDebugLevel() );
565
566             if ( !avDevice->discover() ) {
567                 debugError( "could not discover device\n" );
568                 delete avDevice;
569                 return false;
570             }
571
572             if ( !avDevice->setId( m_avDevices.size() ) ) {
573                 debugError( "setting Id failed\n" );
574             }
575             if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
576                 avDevice->showDevice();
577             }
578             m_avDevices.push_back( avDevice );
579             debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
580         }
581
582         debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
583         return true;
584     }
585 }
586
587 bool
588 DeviceManager::initStreaming()
589 {
590     // iterate over the found devices
591     // add the stream processors of the devices to the managers
592     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
593         it != m_avDevices.end();
594         ++it )
595     {
596         FFADODevice *device = *it;
597         assert(device);
598
599         debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device (%p)\n", device);
600
601         if (!device->lock()) {
602             debugWarning("Could not lock device, skipping device (%p)!\n", device);
603             continue;
604         }
605
606         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n",
607                     m_processorManager->getNominalRate(), device);
608
609         // Set the device's sampling rate to that requested
610         // FIXME: does this really belong here?  If so we need to handle errors.
611         if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
612             debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n",
613                         m_processorManager->getNominalRate(), device);
614
615             // try again:
616             if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
617                 debugFatal("Could not set sampling frequency to %d\n",m_processorManager->getNominalRate());
618                 return false;
619             }
620         }
621         // prepare the device
622         device->prepare();
623     }
624
625     // set the sync source
626     if (!m_processorManager->setSyncSource(getSyncSource())) {
627         debugWarning("Could not set processorManager sync source (%p)\n",
628             getSyncSource());
629     }
630     return true;
631 }
632
633 bool
634 DeviceManager::prepareStreaming()
635 {
636     if (!m_processorManager->prepare()) {
637         debugFatal("Could not prepare streaming...\n");
638         return false;
639     }
640     return true;
641 }
642
643 bool
644 DeviceManager::finishStreaming() {
645     bool result = true;
646     // iterate over the found devices
647     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
648         it != m_avDevices.end();
649         ++it )
650     {
651         debugOutput(DEBUG_LEVEL_VERBOSE, "Unlocking device (%p)\n", *it);
652
653         if (!(*it)->unlock()) {
654             debugWarning("Could not unlock device (%p)!\n", *it);
655             result = false;
656         }
657     }
658     return result;
659 }
660
661 bool
662 DeviceManager::startStreaming() {
663     // create the connections for all devices
664     // iterate over the found devices
665     // add the stream processors of the devices to the managers
666     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
667         it != m_avDevices.end();
668         ++it )
669     {
670         FFADODevice *device = *it;
671         assert(device);
672
673         int j=0;
674         for(j=0; j < device->getStreamCount(); j++) {
675         debugOutput(DEBUG_LEVEL_VERBOSE,"Starting stream %d of device %p\n", j, device);
676             // start the stream
677             if (!device->startStreamByIndex(j)) {
678                 debugWarning("Could not start stream %d of device %p\n", j, device);
679                 continue;
680             }
681         }
682
683         if (!device->enableStreaming()) {
684             debugWarning("Could not enable streaming on device %p!\n", device);
685         }
686     }
687
688     if(m_processorManager->start()) {
689         return true;
690     } else {
691         stopStreaming();
692         return false;
693     }
694 }
695
696 bool
697 DeviceManager::resetStreaming() {
698     return true;
699 }
700
701 bool
702 DeviceManager::stopStreaming()
703 {
704     bool result = true;
705     m_processorManager->stop();
706
707     // create the connections for all devices
708     // iterate over the found devices
709     // add the stream processors of the devices to the managers
710     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
711         it != m_avDevices.end();
712         ++it )
713     {
714         FFADODevice *device = *it;
715         assert(device);
716
717         if (!device->disableStreaming()) {
718             debugWarning("Could not disable streaming on device %p!\n", device);
719         }
720
721         int j=0;
722         for(j=0; j < device->getStreamCount(); j++) {
723             debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %p\n", j, device);
724             // stop the stream
725             // start the stream
726             if (!device->stopStreamByIndex(j)) {
727                 debugWarning("Could not stop stream %d of device %p\n", j, device);
728                 result = false;
729                 continue;
730             }
731         }
732     }
733     return result;
734 }
735
736 enum DeviceManager::eWaitResult
737 DeviceManager::waitForPeriod() {
738     if(m_processorManager->waitForPeriod()) {
739         return eWR_OK;
740     } else {
741         if(m_processorManager->shutdownNeeded()) {
742             debugWarning("Shutdown requested\n");
743             return eWR_Shutdown;
744         } else {
745             debugWarning("XRUN detected\n");
746             // do xrun recovery
747             if(m_processorManager->handleXrun()) {
748                 return eWR_Xrun;
749             } else {
750                 debugError("Could not handle XRUN\n");
751                 return eWR_Error;
752             }
753         }
754     }
755 }
756
757 bool
758 DeviceManager::setStreamingParams(unsigned int period, unsigned int rate, unsigned int nb_buffers) {
759     m_processorManager->setPeriodSize(period);
760     m_processorManager->setNominalRate(rate);
761     m_processorManager->setNbBuffers(nb_buffers);
762     return true;
763 }
764
765 FFADODevice*
766 DeviceManager::getDriverForDevice( std::auto_ptr<ConfigRom>( configRom ),
767                                    int id )
768 {
769 #ifdef ENABLE_BEBOB
770     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying BeBoB...\n" );
771     if ( BeBoB::AvDevice::probe( *configRom.get() ) ) {
772         return BeBoB::AvDevice::createDevice( *this, configRom );
773     }
774 #endif
775
776 #ifdef ENABLE_GENERICAVC
777     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" );
778     if ( GenericAVC::AvDevice::probe( *configRom.get() ) ) {
779         return GenericAVC::AvDevice::createDevice( *this, configRom );
780     }
781 #endif
782
783 #ifdef ENABLE_FIREWORKS
784     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying ECHO Audio FireWorks...\n" );
785     if ( FireWorks::Device::probe( *configRom.get() ) ) {
786         return FireWorks::Device::createDevice( *this, configRom );
787     }
788 #endif
789
790 #ifdef ENABLE_BEBOB
791     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying M-Audio...\n" );
792     if ( MAudio::AvDevice::probe( *configRom.get() ) ) {
793         return MAudio::AvDevice::createDevice( *this, configRom );
794     }
795 #endif
796
797 #ifdef ENABLE_MOTU
798     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Motu...\n" );
799     if ( Motu::MotuDevice::probe( *configRom.get() ) ) {
800         return Motu::MotuDevice::createDevice( *this, configRom );
801     }
802 #endif
803
804 #ifdef ENABLE_DICE
805     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Dice...\n" );
806     if ( Dice::DiceAvDevice::probe( *configRom.get() ) ) {
807         return Dice::DiceAvDevice::createDevice( *this, configRom );
808     }
809 #endif
810
811 #ifdef ENABLE_METRIC_HALO
812     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Metric Halo...\n" );
813     if ( MetricHalo::MHAvDevice::probe( *configRom.get() ) ) {
814         return MetricHalo::MHAvDevice::createDevice( *this, configRom );
815     }
816 #endif
817
818 #ifdef ENABLE_RME
819     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying RME...\n" );
820     if ( Rme::RmeDevice::probe( *configRom.get() ) ) {
821         return Rme::RmeDevice::createDevice( *this, configRom );
822     }
823 #endif
824
825 #ifdef ENABLE_BOUNCE
826     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Bounce...\n" );
827     if ( Bounce::BounceDevice::probe( *configRom.get() ) ) {
828         return Bounce::BounceDevice::createDevice( *this, configRom );
829     }
830 #endif
831
832     return 0;
833 }
834
835 FFADODevice*
836 DeviceManager::getSlaveDriver( std::auto_ptr<ConfigRom>( configRom ) )
837 {
838
839 #ifdef ENABLE_BOUNCE
840     if ( Bounce::BounceSlaveDevice::probe( *configRom.get() ) ) {
841         return Bounce::BounceSlaveDevice::createDevice( configRom );
842     }
843 #endif
844
845     return 0;
846 }
847
848 bool
849 DeviceManager::isValidNode(int node)
850 {
851     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
852           it != m_avDevices.end();
853           ++it )
854     {
855         FFADODevice* avDevice = *it;
856
857         if (avDevice->getConfigRom().getNodeId() == node) {
858             return true;
859     }
860     }
861     return false;
862 }
863
864 int
865 DeviceManager::getNbDevices()
866 {
867     return m_avDevices.size();
868 }
869
870 int
871 DeviceManager::getDeviceNodeId( int deviceNr )
872 {
873     if ( ! ( deviceNr < getNbDevices() ) ) {
874         debugError( "Device number out of range (%d)\n", deviceNr );
875         return -1;
876     }
877
878     FFADODevice* avDevice = m_avDevices.at( deviceNr );
879
880     if ( !avDevice ) {
881         debugError( "Could not get device at position (%d)\n",  deviceNr );
882     }
883
884     return avDevice->getConfigRom().getNodeId();
885 }
886
887 FFADODevice*
888 DeviceManager::getAvDevice( int nodeId )
889 {
890     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
891           it != m_avDevices.end();
892           ++it )
893     {
894         FFADODevice* avDevice = *it;
895         if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
896             return avDevice;
897         }
898     }
899
900     return 0;
901 }
902
903 FFADODevice*
904 DeviceManager::getAvDeviceByIndex( int idx )
905 {
906     return m_avDevices.at(idx);
907 }
908
909 unsigned int
910 DeviceManager::getAvDeviceCount( )
911 {
912     return m_avDevices.size();
913 }
914
915 /**
916  * Return the streamprocessor that is to be used as
917  * the sync source.
918  *
919  * Algorithm still to be determined
920  *
921  * @return StreamProcessor that is sync source
922  */
923 Streaming::StreamProcessor *
924 DeviceManager::getSyncSource() {
925     FFADODevice* device = getAvDeviceByIndex(0);
926
927     bool slaveMode=false;
928     if(!getOption("slaveMode", slaveMode)) {
929         debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
930     }
931
932     #warning TEST CODE FOR BOUNCE DEVICE !!
933     // this makes the bounce slave use the xmit SP as sync source
934     if (slaveMode) {
935         return device->getStreamProcessorByIndex(1);
936     } else {
937         return device->getStreamProcessorByIndex(0);
938     }
939 }
940
941 bool
942 DeviceManager::deinitialize()
943 {
944     return true;
945 }
946
947
948 void
949 DeviceManager::setVerboseLevel(int l)
950 {
951     setDebugLevel(l);
952     Control::Element::setVerboseLevel(l);
953     m_processorManager->setVerboseLevel(l);
954     m_deviceStringParser->setVerboseLevel(l);
955     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
956           it != m_avDevices.end();
957           ++it )
958     {
959         (*it)->setVerboseLevel(l);
960     }
961     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
962           it != m_1394Services.end();
963           ++it )
964     {
965         (*it)->setVerboseLevel(l);
966     }
967     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
968 }
969
970 void
971 DeviceManager::showDeviceInfo() {
972     debugOutput(DEBUG_LEVEL_NORMAL, "===== Device Manager =====\n");
973     Control::Element::show();
974
975     int i=0;
976     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
977           it != m_1394Services.end();
978           ++it )
979     {
980         debugOutput(DEBUG_LEVEL_NORMAL, "--- IEEE1394 Service %2d ---\n", i++);
981         (*it)->show();
982     }
983
984     i=0;
985     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
986         it != m_avDevices.end();
987         ++it )
988     {
989         FFADODevice* avDevice = *it;
990         debugOutput(DEBUG_LEVEL_NORMAL, "--- Device %2d ---\n", i++);
991         avDevice->showDevice();
992
993         debugOutput(DEBUG_LEVEL_NORMAL, "Clock sync sources:\n");
994         FFADODevice::ClockSourceVector sources=avDevice->getSupportedClockSources();
995         for ( FFADODevice::ClockSourceVector::const_iterator it
996                 = sources.begin();
997             it != sources.end();
998             ++it )
999         {
1000             FFADODevice::ClockSource c=*it;
1001             debugOutput(DEBUG_LEVEL_NORMAL, " Type: %s, Id: %2d, Valid: %1d, Active: %1d, Locked %1d, Slipping: %1d, Description: %s\n",
1002                 FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.locked, c.slipping, c.description.c_str());
1003         }
1004     }
1005 }
1006 void
1007 DeviceManager::showStreamingInfo() {
1008     m_processorManager->dumpInfo();
1009 }
Note: See TracBrowser for help on using the browser.