root/branches/libffado-2.0/src/devicemanager.cpp

Revision 1229, 32.4 kB (checked in by ppalmers, 16 years ago)

implement discovery fallback (closes #121)

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