root/trunk/libffado/src/devicemanager.cpp

Revision 1163, 33.2 kB (checked in by ppalmers, 15 years ago)

make dbus server handle busresets cleanly (fixes #102)

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