root/trunk/libffado/src/devicemanager.cpp

Revision 960, 31.2 kB (checked in by ppalmers, 16 years ago)

make dbus server handle bus resets and dynamic add/remove of devices

  • 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 < 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     // rediscover to find new devices
230     // (only for the control server ATM, streaming can't dynamically add/remove devices)
231     if(!discover(m_used_cache_last_time, true)) {
232         debugError("Could not rediscover devices\n");
233     }
234
235     // notify any clients
236     for ( busreset_notif_vec_t::iterator it = m_busResetNotifiers.begin();
237           it != m_busResetNotifiers.end();
238           ++it )
239     {
240         Util::Functor* func = *it;
241         debugOutput( DEBUG_LEVEL_VERBOSE, " running notifier %p...\n", func );
242         ( *func )();
243     }
244 }
245
246 bool
247 DeviceManager::registerBusresetNotification(Util::Functor *handler)
248 {
249     debugOutput( DEBUG_LEVEL_VERBOSE, "register %p...\n", handler);
250     assert(handler);
251     for ( busreset_notif_vec_t::iterator it = m_busResetNotifiers.begin();
252       it != m_busResetNotifiers.end();
253       ++it )
254     {
255         if ( *it == handler ) {
256             debugOutput(DEBUG_LEVEL_VERBOSE, "already registered\n");
257             return false;
258         }
259     }
260     m_busResetNotifiers.push_back(handler);
261     return true;
262 }
263
264 bool
265 DeviceManager::unregisterBusresetNotification(Util::Functor *handler)
266 {
267     debugOutput( DEBUG_LEVEL_VERBOSE, "unregister %p...\n", handler);
268     assert(handler);
269
270     for ( busreset_notif_vec_t::iterator it = m_busResetNotifiers.begin();
271       it != m_busResetNotifiers.end();
272       ++it )
273     {
274         if ( *it == handler ) {
275             m_busResetNotifiers.erase(it);
276             return true;
277         }
278     }
279     debugError("Could not find handler (%p)\n", handler);
280     return false; //not found
281 }
282
283 bool
284 DeviceManager::discover( bool useCache, bool rediscover )
285 {
286     m_used_cache_last_time = useCache;
287     bool slaveMode=false;
288     if(!getOption("slaveMode", slaveMode)) {
289         debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
290     }
291     bool snoopMode=false;
292     if(!getOption("snoopMode", snoopMode)) {
293         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
294     }
295
296     setVerboseLevel(getDebugLevel());
297
298     ConfigRomVector configRoms;
299     // build a list of configroms on the bus.
300     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
301         it != m_1394Services.end();
302         ++it )
303     {
304         Ieee1394Service *portService = *it;
305         for ( fb_nodeid_t nodeId = 0;
306             nodeId < portService->getNodeCount();
307             ++nodeId )
308         {
309             debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
310
311             if (nodeId == portService->getLocalNodeId()) {
312                 debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
313                 continue;
314             }
315
316             ConfigRom * configRom = new ConfigRom( *portService, nodeId );
317             if ( !configRom->initialize() ) {
318                 // \todo If a PHY on the bus is in power safe mode then
319                 // the config rom is missing. So this might be just
320                 // such this case and we can safely skip it. But it might
321                 // be there is a real software problem on our side.
322                 // This should be handlede more carefuly.
323                 debugOutput( DEBUG_LEVEL_NORMAL,
324                             "Could not read config rom from device (node id %d). "
325                             "Skip device discovering for this node\n",
326                             nodeId );
327                 continue;
328             }
329             configRoms.push_back(configRom);
330         }
331     }
332
333     if(rediscover) {
334         FFADODeviceVector discovered_devices_on_bus;
335         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
336             it != m_avDevices.end();
337             ++it )
338         {
339             bool seen_device = false;
340             for ( ConfigRomVectorIterator it2 = configRoms.begin();
341                 it2 != configRoms.end();
342                 ++it2 )
343             {
344                 seen_device |= ((*it)->getConfigRom().getGuid() == (*it2)->getGuid());
345             }
346
347             if(seen_device) {
348                 debugOutput( DEBUG_LEVEL_VERBOSE,
349                             "Already discovered device with GUID: %s\n",
350                             (*it)->getConfigRom().getGuidString().c_str() );
351                 // we already discovered this device, and it is still here. keep it
352                 discovered_devices_on_bus.push_back(*it);
353             } else {
354                 debugOutput( DEBUG_LEVEL_VERBOSE,
355                             "Device with GUID: %s disappeared from bus, removing...\n",
356                             (*it)->getConfigRom().getGuidString().c_str() );
357
358                 // the device has disappeared, remove it from the control tree
359                 if (!deleteElement(*it)) {
360                     debugWarning("failed to remove AvDevice from Control::Container\n");
361                 }
362                 // delete the device
363                 // FIXME: this will mess up the any code that waits for bus resets to
364                 //        occur
365                 delete *it;
366             }
367         }
368         // prune the devices that disappeared
369         m_avDevices = discovered_devices_on_bus;
370     } else { // remove everything since we are not rediscovering
371         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
372             it != m_avDevices.end();
373             ++it )
374         {
375             if (!deleteElement(*it)) {
376                 debugWarning("failed to remove AvDevice from Control::Container\n");
377             }
378             delete *it;
379         }
380
381         m_avDevices.clear();
382     }
383
384     // delete the config rom list entries
385     // FIXME: we should reuse it
386     for ( ConfigRomVectorIterator it = configRoms.begin();
387         it != configRoms.end();
388         ++it )
389     {
390         delete *it;
391     }
392
393     assert(m_deviceStringParser);
394     // show the spec strings we're going to use
395     if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
396         m_deviceStringParser->show();
397     }
398
399     if (!slaveMode) {
400         for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
401             it != m_1394Services.end();
402             ++it )
403         {
404             Ieee1394Service *portService = *it;
405             for ( fb_nodeid_t nodeId = 0;
406                 nodeId < portService->getNodeCount();
407                 ++nodeId )
408             {
409                 debugOutput( DEBUG_LEVEL_VERBOSE, "Probing node %d...\n", nodeId );
410    
411                 if (nodeId == portService->getLocalNodeId()) {
412                     debugOutput( DEBUG_LEVEL_VERBOSE, "Skipping local node (%d)...\n", nodeId );
413                     continue;
414                 }
415    
416                 std::auto_ptr<ConfigRom> configRom =
417                     std::auto_ptr<ConfigRom>( new ConfigRom( *portService, nodeId ) );
418                 if ( !configRom->initialize() ) {
419                     // \todo If a PHY on the bus is in power safe mode then
420                     // the config rom is missing. So this might be just
421                     // such this case and we can safely skip it. But it might
422                     // be there is a real software problem on our side.
423                     // This should be handlede more carefuly.
424                     debugOutput( DEBUG_LEVEL_NORMAL,
425                                 "Could not read config rom from device (node id %d). "
426                                 "Skip device discovering for this node\n",
427                                 nodeId );
428                     continue;
429                 }
430
431                 bool already_in_vector = false;
432                 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
433                     it != m_avDevices.end();
434                     ++it )
435                 {
436                     if ((*it)->getConfigRom().getGuid() == configRom->getGuid()) {
437                         already_in_vector = true;
438                         break;
439                     }
440                 }
441                 if(already_in_vector) {
442                     if(!rediscover) {
443                         debugWarning("Device with GUID %s already discovered on other port, skipping device...\n",
444                                     configRom->getGuidString().c_str());
445                     }
446                     continue;
447                 }
448
449                 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
450                     configRom->printConfigRomDebug();
451                 }
452
453                 // if spec strings are given, only add those devices
454                 // that match the spec string(s).
455                 // if no (valid) spec strings are present, grab all
456                 // supported devices.
457                 if(m_deviceStringParser->countDeviceStrings() &&
458                   !m_deviceStringParser->match(*configRom.get())) {
459                     debugOutput(DEBUG_LEVEL_VERBOSE, "Device doesn't match any of the spec strings. skipping...\n");
460                     continue;
461                 }
462
463                 // find a driver
464                 FFADODevice* avDevice = getDriverForDevice( configRom,
465                                                             nodeId );
466
467                 if ( avDevice ) {
468                     debugOutput( DEBUG_LEVEL_NORMAL,
469                                 "driver found for device %d\n",
470                                 nodeId );
471
472                     avDevice->setVerboseLevel( getDebugLevel() );
473                     bool isFromCache = false;
474                     if ( useCache && avDevice->loadFromCache() ) {
475                         debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" );
476                         isFromCache = true;
477                         // restore the debug level for everything that was loaded
478                         avDevice->setVerboseLevel( getDebugLevel() );
479                     } else if ( avDevice->discover() ) {
480                         debugOutput( DEBUG_LEVEL_VERBOSE, "discovery successful\n" );
481                     } else {
482                         debugError( "could not discover device\n" );
483                         delete avDevice;
484                         continue;
485                     }
486
487                     if (snoopMode) {
488                         debugOutput( DEBUG_LEVEL_VERBOSE,
489                                     "Enabling snoop mode on node %d...\n", nodeId );
490
491                         if(!avDevice->setOption("snoopMode", snoopMode)) {
492                             debugWarning("Could not set snoop mode for device on node %d\n", nodeId);
493                             delete avDevice;
494                             continue;
495                         }
496                     }
497
498                     if ( !isFromCache && !avDevice->saveCache() ) {
499                         debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
500                     }
501                     m_avDevices.push_back( avDevice );
502
503                     if (!addElement(avDevice)) {
504                         debugWarning("failed to add AvDevice to Control::Container\n");
505                     }
506
507                     debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
508                 }
509             }
510         }
511
512         debugOutput( DEBUG_LEVEL_NORMAL, "Discovery finished...\n" );
513         // FIXME: do better sorting
514         // sort the m_avDevices vector on their GUID
515         // then assign reassign the id's to the devices
516         // the side effect of this is that for the same set of attached devices,
517         // a device id always corresponds to the same device
518         sort(m_avDevices.begin(), m_avDevices.end(), FFADODevice::compareGUID);
519         int i=0;
520         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
521             it != m_avDevices.end();
522             ++it )
523         {
524             if ( !(*it)->setId( i++ ) ) {
525                 debugError( "setting Id failed\n" );
526             }
527         }
528         showDeviceInfo();
529         return true;
530     } else { // slave mode
531         Ieee1394Service *portService = m_1394Services.at(0);
532         fb_nodeid_t nodeId = portService->getLocalNodeId();
533         debugOutput( DEBUG_LEVEL_VERBOSE, "Starting in slave mode on node %d...\n", nodeId );
534
535         std::auto_ptr<ConfigRom> configRom =
536             std::auto_ptr<ConfigRom>( new ConfigRom( *portService,
537                                                      nodeId ) );
538         if ( !configRom->initialize() ) {
539             // \todo If a PHY on the bus is in power safe mode then
540             // the config rom is missing. So this might be just
541             // such this case and we can safely skip it. But it might
542             // be there is a real software problem on our side.
543             // This should be handled more carefuly.
544             debugOutput( DEBUG_LEVEL_NORMAL,
545                          "Could not read config rom from device (node id %d). "
546                          "Skip device discovering for this node\n",
547                          nodeId );
548             return false;
549         }
550
551         FFADODevice* avDevice = getSlaveDriver( configRom );
552         if ( avDevice ) {
553             debugOutput( DEBUG_LEVEL_NORMAL,
554                          "driver found for device %d\n",
555                          nodeId );
556
557             avDevice->setVerboseLevel( getDebugLevel() );
558
559             if ( !avDevice->discover() ) {
560                 debugError( "could not discover device\n" );
561                 delete avDevice;
562                 return false;
563             }
564
565             if ( !avDevice->setId( m_avDevices.size() ) ) {
566                 debugError( "setting Id failed\n" );
567             }
568             if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
569                 avDevice->showDevice();
570             }
571             m_avDevices.push_back( avDevice );
572             debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
573         }
574
575         debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
576         return true;
577     }
578 }
579
580 bool
581 DeviceManager::initStreaming()
582 {
583     // iterate over the found devices
584     // add the stream processors of the devices to the managers
585     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
586         it != m_avDevices.end();
587         ++it )
588     {
589         FFADODevice *device = *it;
590         assert(device);
591
592         debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device (%p)\n", device);
593
594         if (!device->lock()) {
595             debugWarning("Could not lock device, skipping device (%p)!\n", device);
596             continue;
597         }
598
599         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n",
600                     m_processorManager->getNominalRate(), device);
601
602         // Set the device's sampling rate to that requested
603         // FIXME: does this really belong here?  If so we need to handle errors.
604         if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
605             debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n",
606                         m_processorManager->getNominalRate(), device);
607
608             // try again:
609             if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
610                 debugFatal("Could not set sampling frequency to %d\n",m_processorManager->getNominalRate());
611                 return false;
612             }
613         }
614         // prepare the device
615         device->prepare();
616     }
617
618     // set the sync source
619     if (!m_processorManager->setSyncSource(getSyncSource())) {
620         debugWarning("Could not set processorManager sync source (%p)\n",
621             getSyncSource());
622     }
623     return true;
624 }
625
626 bool
627 DeviceManager::prepareStreaming()
628 {
629     if (!m_processorManager->prepare()) {
630         debugFatal("Could not prepare streaming...\n");
631         return false;
632     }
633     return true;
634 }
635
636 bool
637 DeviceManager::finishStreaming() {
638     bool result = true;
639     // iterate over the found devices
640     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
641         it != m_avDevices.end();
642         ++it )
643     {
644         debugOutput(DEBUG_LEVEL_VERBOSE, "Unlocking device (%p)\n", *it);
645
646         if (!(*it)->unlock()) {
647             debugWarning("Could not unlock device (%p)!\n", *it);
648             result = false;
649         }
650     }
651     return result;
652 }
653
654 bool
655 DeviceManager::startStreaming() {
656     // create the connections for all devices
657     // iterate over the found devices
658     // add the stream processors of the devices to the managers
659     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
660         it != m_avDevices.end();
661         ++it )
662     {
663         FFADODevice *device = *it;
664         assert(device);
665
666         int j=0;
667         for(j=0; j < device->getStreamCount(); j++) {
668         debugOutput(DEBUG_LEVEL_VERBOSE,"Starting stream %d of device %p\n", j, device);
669             // start the stream
670             if (!device->startStreamByIndex(j)) {
671                 debugWarning("Could not start stream %d of device %p\n", j, device);
672                 continue;
673             }
674         }
675
676         if (!device->enableStreaming()) {
677             debugWarning("Could not enable streaming on device %p!\n", device);
678         }
679     }
680
681     if(m_processorManager->start()) {
682         return true;
683     } else {
684         stopStreaming();
685         return false;
686     }
687 }
688
689 bool
690 DeviceManager::resetStreaming() {
691     return true;
692 }
693
694 bool
695 DeviceManager::stopStreaming()
696 {
697     bool result = true;
698     m_processorManager->stop();
699
700     // create the connections for all devices
701     // iterate over the found devices
702     // add the stream processors of the devices to the managers
703     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
704         it != m_avDevices.end();
705         ++it )
706     {
707         FFADODevice *device = *it;
708         assert(device);
709
710         if (!device->disableStreaming()) {
711             debugWarning("Could not disable streaming on device %p!\n", device);
712         }
713
714         int j=0;
715         for(j=0; j < device->getStreamCount(); j++) {
716             debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %p\n", j, device);
717             // stop the stream
718             // start the stream
719             if (!device->stopStreamByIndex(j)) {
720                 debugWarning("Could not stop stream %d of device %p\n", j, device);
721                 result = false;
722                 continue;
723             }
724         }
725     }
726     return result;
727 }
728
729 enum DeviceManager::eWaitResult
730 DeviceManager::waitForPeriod() {
731     if(m_processorManager->waitForPeriod()) {
732         return eWR_OK;
733     } else {
734         debugWarning("XRUN detected\n");
735         // do xrun recovery
736         if(m_processorManager->handleXrun()) {
737             return eWR_Xrun;
738         } else {
739             debugError("Could not handle XRUN\n");
740             return eWR_Error;
741         }
742     }
743 }
744
745 bool
746 DeviceManager::setStreamingParams(unsigned int period, unsigned int rate, unsigned int nb_buffers) {
747     m_processorManager->setPeriodSize(period);
748     m_processorManager->setNominalRate(rate);
749     m_processorManager->setNbBuffers(nb_buffers);
750     return true;
751 }
752
753 FFADODevice*
754 DeviceManager::getDriverForDevice( std::auto_ptr<ConfigRom>( configRom ),
755                                    int id )
756 {
757 #ifdef ENABLE_BEBOB
758     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying BeBoB...\n" );
759     if ( BeBoB::AvDevice::probe( *configRom.get() ) ) {
760         return BeBoB::AvDevice::createDevice( *this, configRom );
761     }
762 #endif
763
764 #ifdef ENABLE_GENERICAVC
765     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" );
766     if ( GenericAVC::AvDevice::probe( *configRom.get() ) ) {
767         return GenericAVC::AvDevice::createDevice( *this, configRom );
768     }
769 #endif
770
771 #ifdef ENABLE_FIREWORKS
772     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying ECHO Audio FireWorks...\n" );
773     if ( FireWorks::Device::probe( *configRom.get() ) ) {
774         return FireWorks::Device::createDevice( *this, configRom );
775     }
776 #endif
777
778 #ifdef ENABLE_BEBOB
779     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying M-Audio...\n" );
780     if ( MAudio::AvDevice::probe( *configRom.get() ) ) {
781         return MAudio::AvDevice::createDevice( *this, configRom );
782     }
783 #endif
784
785 #ifdef ENABLE_MOTU
786     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Motu...\n" );
787     if ( Motu::MotuDevice::probe( *configRom.get() ) ) {
788         return Motu::MotuDevice::createDevice( *this, configRom );
789     }
790 #endif
791
792 #ifdef ENABLE_DICE
793     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Dice...\n" );
794     if ( Dice::DiceAvDevice::probe( *configRom.get() ) ) {
795         return Dice::DiceAvDevice::createDevice( *this, configRom );
796     }
797 #endif
798
799 #ifdef ENABLE_METRIC_HALO
800     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Metric Halo...\n" );
801     if ( MetricHalo::MHAvDevice::probe( *configRom.get() ) ) {
802         return MetricHalo::MHAvDevice::createDevice( *this, configRom );
803     }
804 #endif
805
806 #ifdef ENABLE_RME
807     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying RME...\n" );
808     if ( Rme::RmeDevice::probe( *configRom.get() ) ) {
809         return Rme::RmeDevice::createDevice( *this, configRom );
810     }
811 #endif
812
813 #ifdef ENABLE_BOUNCE
814     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Bounce...\n" );
815     if ( Bounce::BounceDevice::probe( *configRom.get() ) ) {
816         return Bounce::BounceDevice::createDevice( *this, configRom );
817     }
818 #endif
819
820     return 0;
821 }
822
823 FFADODevice*
824 DeviceManager::getSlaveDriver( std::auto_ptr<ConfigRom>( configRom ) )
825 {
826
827 #ifdef ENABLE_BOUNCE
828     if ( Bounce::BounceSlaveDevice::probe( *configRom.get() ) ) {
829         return Bounce::BounceSlaveDevice::createDevice( configRom );
830     }
831 #endif
832
833     return 0;
834 }
835
836 bool
837 DeviceManager::isValidNode(int node)
838 {
839     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
840           it != m_avDevices.end();
841           ++it )
842     {
843         FFADODevice* avDevice = *it;
844
845         if (avDevice->getConfigRom().getNodeId() == node) {
846             return true;
847     }
848     }
849     return false;
850 }
851
852 int
853 DeviceManager::getNbDevices()
854 {
855     return m_avDevices.size();
856 }
857
858 int
859 DeviceManager::getDeviceNodeId( int deviceNr )
860 {
861     if ( ! ( deviceNr < getNbDevices() ) ) {
862         debugError( "Device number out of range (%d)\n", deviceNr );
863         return -1;
864     }
865
866     FFADODevice* avDevice = m_avDevices.at( deviceNr );
867
868     if ( !avDevice ) {
869         debugError( "Could not get device at position (%d)\n",  deviceNr );
870     }
871
872     return avDevice->getConfigRom().getNodeId();
873 }
874
875 FFADODevice*
876 DeviceManager::getAvDevice( int nodeId )
877 {
878     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
879           it != m_avDevices.end();
880           ++it )
881     {
882         FFADODevice* avDevice = *it;
883         if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
884             return avDevice;
885         }
886     }
887
888     return 0;
889 }
890
891 FFADODevice*
892 DeviceManager::getAvDeviceByIndex( int idx )
893 {
894     return m_avDevices.at(idx);
895 }
896
897 unsigned int
898 DeviceManager::getAvDeviceCount( )
899 {
900     return m_avDevices.size();
901 }
902
903 /**
904  * Return the streamprocessor that is to be used as
905  * the sync source.
906  *
907  * Algorithm still to be determined
908  *
909  * @return StreamProcessor that is sync source
910  */
911 Streaming::StreamProcessor *
912 DeviceManager::getSyncSource() {
913     FFADODevice* device = getAvDeviceByIndex(0);
914
915     bool slaveMode=false;
916     if(!getOption("slaveMode", slaveMode)) {
917         debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
918     }
919
920     #warning TEST CODE FOR BOUNCE DEVICE !!
921     // this makes the bounce slave use the xmit SP as sync source
922     if (slaveMode) {
923         return device->getStreamProcessorByIndex(1);
924     } else {
925         return device->getStreamProcessorByIndex(0);
926     }
927 }
928
929 bool
930 DeviceManager::deinitialize()
931 {
932     return true;
933 }
934
935
936 void
937 DeviceManager::setVerboseLevel(int l)
938 {
939     setDebugLevel(l);
940     Control::Element::setVerboseLevel(l);
941     m_processorManager->setVerboseLevel(l);
942     m_deviceStringParser->setVerboseLevel(l);
943     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
944           it != m_avDevices.end();
945           ++it )
946     {
947         (*it)->setVerboseLevel(l);
948     }
949     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
950           it != m_1394Services.end();
951           ++it )
952     {
953         (*it)->setVerboseLevel(l);
954     }
955     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
956 }
957
958 void
959 DeviceManager::showDeviceInfo() {
960     debugOutput(DEBUG_LEVEL_NORMAL, "===== Device Manager =====\n");
961     Control::Element::show();
962
963     int i=0;
964     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
965           it != m_1394Services.end();
966           ++it )
967     {
968         debugOutput(DEBUG_LEVEL_NORMAL, "--- IEEE1394 Service %2d ---\n", i++);
969         (*it)->show();
970     }
971
972     i=0;
973     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
974         it != m_avDevices.end();
975         ++it )
976     {
977         FFADODevice* avDevice = *it;
978         debugOutput(DEBUG_LEVEL_NORMAL, "--- Device %2d ---\n", i++);
979         avDevice->showDevice();
980
981         debugOutput(DEBUG_LEVEL_NORMAL, "Clock sync sources:\n");
982         FFADODevice::ClockSourceVector sources=avDevice->getSupportedClockSources();
983         for ( FFADODevice::ClockSourceVector::const_iterator it
984                 = sources.begin();
985             it != sources.end();
986             ++it )
987         {
988             FFADODevice::ClockSource c=*it;
989             debugOutput(DEBUG_LEVEL_NORMAL, " Type: %s, Id: %2d, Valid: %1d, Active: %1d, Locked %1d, Slipping: %1d, Description: %s\n",
990                 FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.locked, c.slipping, c.description.c_str());
991         }
992     }
993 }
994 void
995 DeviceManager::showStreamingInfo() {
996     m_processorManager->dumpInfo();
997 }
Note: See TracBrowser for help on using the browser.