root/tags/2.0-beta3/src/devicemanager.cpp

Revision 1092, 31.8 kB (checked in by ppalmers, 4 years ago)

fixes #100

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