root/trunk/libffado/src/devicemanager.cpp

Revision 1212, 33.2 kB (checked in by ppalmers, 16 years ago)

add a config option to globally disable the cache

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