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

Revision 1213, 31.4 kB (checked in by ppalmers, 13 years ago)

merge trunk changes r1209:1212 (svn merge -r 1209:1212 svn+ssh://ffadosvn@ffado.org/ffado/trunk/libffado)

  • 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                 std::auto_ptr<ConfigRom> configRom =
439                     std::auto_ptr<ConfigRom>( new ConfigRom( *portService, nodeId ) );
440                 if ( !configRom->initialize() ) {
441                     // \todo If a PHY on the bus is in power safe mode then
442                     // the config rom is missing. So this might be just
443                     // such this case and we can safely skip it. But it might
444                     // be there is a real software problem on our side.
445                     // This should be handlede more carefuly.
446                     debugOutput( DEBUG_LEVEL_NORMAL,
447                                 "Could not read config rom from device (node id %d). "
448                                 "Skip device discovering for this node\n",
449                                 nodeId );
450                     continue;
451                 }
452
453                 bool already_in_vector = false;
454                 for ( FFADODeviceVectorIterator it = m_avDevices.begin();
455                     it != m_avDevices.end();
456                     ++it )
457                 {
458                     if ((*it)->getConfigRom().getGuid() == configRom->getGuid()) {
459                         already_in_vector = true;
460                         break;
461                     }
462                 }
463                 if(already_in_vector) {
464                     if(!rediscover) {
465                         debugWarning("Device with GUID %s already discovered on other port, skipping device...\n",
466                                     configRom->getGuidString().c_str());
467                     }
468                     continue;
469                 }
470
471                 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE) {
472                     configRom->printConfigRomDebug();
473                 }
474
475                 // if spec strings are given, only add those devices
476                 // that match the spec string(s).
477                 // if no (valid) spec strings are present, grab all
478                 // supported devices.
479                 if(m_deviceStringParser->countDeviceStrings() &&
480                   !m_deviceStringParser->match(*configRom.get())) {
481                     debugOutput(DEBUG_LEVEL_VERBOSE, "Device doesn't match any of the spec strings. skipping...\n");
482                     continue;
483                 }
484
485                 // find a driver
486                 FFADODevice* avDevice = getDriverForDevice( configRom,
487                                                             nodeId );
488
489                 if ( avDevice ) {
490                     debugOutput( DEBUG_LEVEL_NORMAL,
491                                 "driver found for device %d\n",
492                                 nodeId );
493
494                     avDevice->setVerboseLevel( getDebugLevel() );
495                     bool isFromCache = false;
496                     if ( useCache && avDevice->loadFromCache() ) {
497                         debugOutput( DEBUG_LEVEL_VERBOSE, "could load from cache\n" );
498                         isFromCache = true;
499                         // restore the debug level for everything that was loaded
500                         avDevice->setVerboseLevel( getDebugLevel() );
501                     } else if ( avDevice->discover() ) {
502                         debugOutput( DEBUG_LEVEL_VERBOSE, "discovery successful\n" );
503                     } else {
504                         debugError( "could not discover device\n" );
505                         delete avDevice;
506                         continue;
507                     }
508
509                     if (snoopMode) {
510                         debugOutput( DEBUG_LEVEL_VERBOSE,
511                                     "Enabling snoop mode on node %d...\n", nodeId );
512
513                         if(!avDevice->setOption("snoopMode", snoopMode)) {
514                             debugWarning("Could not set snoop mode for device on node %d\n", nodeId);
515                             delete avDevice;
516                             continue;
517                         }
518                     }
519
520                     if ( !isFromCache && !avDevice->saveCache() ) {
521                         debugOutput( DEBUG_LEVEL_VERBOSE, "No cached version of AVC model created\n" );
522                     }
523                     m_avDevices.push_back( avDevice );
524
525                     if (!addElement(avDevice)) {
526                         debugWarning("failed to add AvDevice to Control::Container\n");
527                     }
528
529                     debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
530                 }
531             }
532         }
533
534         debugOutput( DEBUG_LEVEL_NORMAL, "Discovery finished...\n" );
535         // FIXME: do better sorting
536         // sort the m_avDevices vector on their GUID
537         // then assign reassign the id's to the devices
538         // the side effect of this is that for the same set of attached devices,
539         // a device id always corresponds to the same device
540         sort(m_avDevices.begin(), m_avDevices.end(), FFADODevice::compareGUID);
541         int i=0;
542         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
543             it != m_avDevices.end();
544             ++it )
545         {
546             if ( !(*it)->setId( i++ ) ) {
547                 debugError( "setting Id failed\n" );
548             }
549         }
550         showDeviceInfo();
551
552     } else { // slave mode
553         // notify any clients
554         signalNotifiers(m_preUpdateNotifiers);
555         Ieee1394Service *portService = m_1394Services.at(0);
556         fb_nodeid_t nodeId = portService->getLocalNodeId();
557         debugOutput( DEBUG_LEVEL_VERBOSE, "Starting in slave mode on node %d...\n", nodeId );
558
559         std::auto_ptr<ConfigRom> configRom =
560             std::auto_ptr<ConfigRom>( new ConfigRom( *portService,
561                                                      nodeId ) );
562         if ( !configRom->initialize() ) {
563             // \todo If a PHY on the bus is in power safe mode then
564             // the config rom is missing. So this might be just
565             // such this case and we can safely skip it. But it might
566             // be there is a real software problem on our side.
567             // This should be handled more carefuly.
568             debugOutput( DEBUG_LEVEL_NORMAL,
569                          "Could not read config rom from device (node id %d). "
570                          "Skip device discovering for this node\n",
571                          nodeId );
572             return false;
573         }
574
575         // remove any already present devices
576         for ( FFADODeviceVectorIterator it = m_avDevices.begin();
577             it != m_avDevices.end();
578             ++it )
579         {
580             if (!deleteElement(*it)) {
581                 debugWarning("failed to remove AvDevice from Control::Container\n");
582             }
583             delete *it;
584         }
585
586         m_avDevices.clear();
587
588         // get the slave driver
589         FFADODevice* avDevice = getSlaveDriver( configRom );
590         if ( avDevice ) {
591             debugOutput( DEBUG_LEVEL_NORMAL,
592                          "driver found for device %d\n",
593                          nodeId );
594
595             avDevice->setVerboseLevel( getDebugLevel() );
596
597             if ( !avDevice->discover() ) {
598                 debugError( "could not discover device\n" );
599                 delete avDevice;
600                 return false;
601             }
602
603             if ( !avDevice->setId( m_avDevices.size() ) ) {
604                 debugError( "setting Id failed\n" );
605             }
606             if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE ) {
607                 avDevice->showDevice();
608             }
609             m_avDevices.push_back( avDevice );
610             debugOutput( DEBUG_LEVEL_NORMAL, "discovery of node %d on port %d done...\n", nodeId, portService->getPort() );
611         }
612
613         debugOutput( DEBUG_LEVEL_NORMAL, "discovery finished...\n" );
614     }
615
616     m_avDevicesLock->Unlock();
617     // notify any clients
618     signalNotifiers(m_postUpdateNotifiers);
619     return true;
620 }
621
622 bool
623 DeviceManager::initStreaming()
624 {
625     // iterate over the found devices
626     // add the stream processors of the devices to the managers
627     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
628         it != m_avDevices.end();
629         ++it )
630     {
631         FFADODevice *device = *it;
632         assert(device);
633
634         debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device (%p)\n", device);
635
636         if (!device->lock()) {
637             debugWarning("Could not lock device, skipping device (%p)!\n", device);
638             continue;
639         }
640
641         debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n",
642                     m_processorManager->getNominalRate(), device);
643
644         // Set the device's sampling rate to that requested
645         // FIXME: does this really belong here?  If so we need to handle errors.
646         if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
647             debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n",
648                         m_processorManager->getNominalRate(), device);
649
650             // try again:
651             if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) {
652                 debugFatal("Could not set sampling frequency to %d\n",m_processorManager->getNominalRate());
653                 return false;
654             }
655         }
656         // prepare the device
657         device->prepare();
658     }
659
660     // set the sync source
661     if (!m_processorManager->setSyncSource(getSyncSource())) {
662         debugWarning("Could not set processorManager sync source (%p)\n",
663             getSyncSource());
664     }
665     return true;
666 }
667
668 bool
669 DeviceManager::prepareStreaming()
670 {
671     if (!m_processorManager->prepare()) {
672         debugFatal("Could not prepare streaming...\n");
673         return false;
674     }
675     return true;
676 }
677
678 bool
679 DeviceManager::finishStreaming() {
680     bool result = true;
681     // iterate over the found devices
682     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
683         it != m_avDevices.end();
684         ++it )
685     {
686         debugOutput(DEBUG_LEVEL_VERBOSE, "Unlocking device (%p)\n", *it);
687
688         if (!(*it)->unlock()) {
689             debugWarning("Could not unlock device (%p)!\n", *it);
690             result = false;
691         }
692     }
693     return result;
694 }
695
696 bool
697 DeviceManager::startStreaming() {
698     // create the connections for all devices
699     // iterate over the found devices
700     // add the stream processors of the devices to the managers
701     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
702         it != m_avDevices.end();
703         ++it )
704     {
705         FFADODevice *device = *it;
706         assert(device);
707
708         int j=0;
709         for(j=0; j < device->getStreamCount(); j++) {
710         debugOutput(DEBUG_LEVEL_VERBOSE,"Starting stream %d of device %p\n", j, device);
711             // start the stream
712             if (!device->startStreamByIndex(j)) {
713                 debugWarning("Could not start stream %d of device %p\n", j, device);
714                 continue;
715             }
716         }
717
718         if (!device->enableStreaming()) {
719             debugWarning("Could not enable streaming on device %p!\n", device);
720         }
721     }
722
723     if(m_processorManager->start()) {
724         return true;
725     } else {
726         stopStreaming();
727         return false;
728     }
729 }
730
731 bool
732 DeviceManager::resetStreaming() {
733     return true;
734 }
735
736 bool
737 DeviceManager::stopStreaming()
738 {
739     bool result = true;
740     m_processorManager->stop();
741
742     // create the connections for all devices
743     // iterate over the found devices
744     // add the stream processors of the devices to the managers
745     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
746         it != m_avDevices.end();
747         ++it )
748     {
749         FFADODevice *device = *it;
750         assert(device);
751
752         if (!device->disableStreaming()) {
753             debugWarning("Could not disable streaming on device %p!\n", device);
754         }
755
756         int j=0;
757         for(j=0; j < device->getStreamCount(); j++) {
758             debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %p\n", j, device);
759             // stop the stream
760             // start the stream
761             if (!device->stopStreamByIndex(j)) {
762                 debugWarning("Could not stop stream %d of device %p\n", j, device);
763                 result = false;
764                 continue;
765             }
766         }
767     }
768     return result;
769 }
770
771 enum DeviceManager::eWaitResult
772 DeviceManager::waitForPeriod() {
773     if(m_processorManager->waitForPeriod()) {
774         return eWR_OK;
775     } else {
776         if(m_processorManager->shutdownNeeded()) {
777             debugWarning("Shutdown requested\n");
778             return eWR_Shutdown;
779         } else {
780             debugWarning("XRUN detected\n");
781             // do xrun recovery
782             if(m_processorManager->handleXrun()) {
783                 return eWR_Xrun;
784             } else {
785                 debugError("Could not handle XRUN\n");
786                 return eWR_Error;
787             }
788         }
789     }
790 }
791
792 bool
793 DeviceManager::setStreamingParams(unsigned int period, unsigned int rate, unsigned int nb_buffers) {
794     m_processorManager->setPeriodSize(period);
795     m_processorManager->setNominalRate(rate);
796     m_processorManager->setNbBuffers(nb_buffers);
797     return true;
798 }
799
800 FFADODevice*
801 DeviceManager::getDriverForDevice( std::auto_ptr<ConfigRom>( configRom ),
802                                    int id )
803 {
804 #ifdef ENABLE_BEBOB
805     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying BeBoB...\n" );
806     if ( BeBoB::AvDevice::probe( *configRom.get() ) ) {
807         return BeBoB::AvDevice::createDevice( *this, configRom );
808     }
809 #endif
810
811 #ifdef ENABLE_GENERICAVC
812     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Generic AV/C...\n" );
813     if ( GenericAVC::AvDevice::probe( *configRom.get() ) ) {
814         return GenericAVC::AvDevice::createDevice( *this, configRom );
815     }
816 #endif
817
818 #ifdef ENABLE_FIREWORKS
819     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying ECHO Audio FireWorks...\n" );
820     if ( FireWorks::Device::probe( *configRom.get() ) ) {
821         return FireWorks::Device::createDevice( *this, configRom );
822     }
823 #endif
824
825 #ifdef ENABLE_MOTU
826     debugOutput( DEBUG_LEVEL_VERBOSE, "Trying Motu...\n" );
827     if ( Motu::MotuDevice::probe( *configRom.get() ) ) {
828         return Motu::MotuDevice::createDevice( *this, configRom );
829     }
830 #endif
831
832     return 0;
833 }
834
835 FFADODevice*
836 DeviceManager::getSlaveDriver( std::auto_ptr<ConfigRom>( configRom ) )
837 {
838     return 0;
839 }
840
841 bool
842 DeviceManager::isValidNode(int node)
843 {
844     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
845           it != m_avDevices.end();
846           ++it )
847     {
848         FFADODevice* avDevice = *it;
849
850         if (avDevice->getConfigRom().getNodeId() == node) {
851             return true;
852     }
853     }
854     return false;
855 }
856
857 int
858 DeviceManager::getNbDevices()
859 {
860     return m_avDevices.size();
861 }
862
863 int
864 DeviceManager::getDeviceNodeId( int deviceNr )
865 {
866     if ( ! ( deviceNr < getNbDevices() ) ) {
867         debugError( "Device number out of range (%d)\n", deviceNr );
868         return -1;
869     }
870
871     FFADODevice* avDevice = m_avDevices.at( deviceNr );
872
873     if ( !avDevice ) {
874         debugError( "Could not get device at position (%d)\n",  deviceNr );
875     }
876
877     return avDevice->getConfigRom().getNodeId();
878 }
879
880 FFADODevice*
881 DeviceManager::getAvDevice( int nodeId )
882 {
883     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
884           it != m_avDevices.end();
885           ++it )
886     {
887         FFADODevice* avDevice = *it;
888         if ( avDevice->getConfigRom().getNodeId() == nodeId ) {
889             return avDevice;
890         }
891     }
892
893     return 0;
894 }
895
896 FFADODevice*
897 DeviceManager::getAvDeviceByIndex( int idx )
898 {
899     return m_avDevices.at(idx);
900 }
901
902 unsigned int
903 DeviceManager::getAvDeviceCount( )
904 {
905     return m_avDevices.size();
906 }
907
908 /**
909  * Return the streamprocessor that is to be used as
910  * the sync source.
911  *
912  * Algorithm still to be determined
913  *
914  * @return StreamProcessor that is sync source
915  */
916 Streaming::StreamProcessor *
917 DeviceManager::getSyncSource() {
918     FFADODevice* device = getAvDeviceByIndex(0);
919
920     bool slaveMode=false;
921     if(!getOption("slaveMode", slaveMode)) {
922         debugOutput(DEBUG_LEVEL_NORMAL,
923                     "Could not retrieve slaveMode parameter, defauling to false\n");
924     }
925     return device->getStreamProcessorByIndex(0);
926 }
927
928 bool
929 DeviceManager::deinitialize()
930 {
931     return true;
932 }
933
934
935 void
936 DeviceManager::setVerboseLevel(int l)
937 {
938     setDebugLevel(l);
939     Control::Element::setVerboseLevel(l);
940     m_processorManager->setVerboseLevel(l);
941     m_deviceStringParser->setVerboseLevel(l);
942     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
943           it != m_avDevices.end();
944           ++it )
945     {
946         (*it)->setVerboseLevel(l);
947     }
948     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
949           it != m_1394Services.end();
950           ++it )
951     {
952         (*it)->setVerboseLevel(l);
953     }
954     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
955 }
956
957 void
958 DeviceManager::showDeviceInfo() {
959     debugOutput(DEBUG_LEVEL_NORMAL, "===== Device Manager =====\n");
960     Control::Element::show();
961
962     int i=0;
963     for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin();
964           it != m_1394Services.end();
965           ++it )
966     {
967         debugOutput(DEBUG_LEVEL_NORMAL, "--- IEEE1394 Service %2d ---\n", i++);
968         (*it)->show();
969     }
970
971     i=0;
972     for ( FFADODeviceVectorIterator it = m_avDevices.begin();
973         it != m_avDevices.end();
974         ++it )
975     {
976         FFADODevice* avDevice = *it;
977         debugOutput(DEBUG_LEVEL_NORMAL, "--- Device %2d ---\n", i++);
978         avDevice->showDevice();
979
980         debugOutput(DEBUG_LEVEL_NORMAL, "Clock sync sources:\n");
981         FFADODevice::ClockSourceVector sources=avDevice->getSupportedClockSources();
982         for ( FFADODevice::ClockSourceVector::const_iterator it
983                 = sources.begin();
984             it != sources.end();
985             ++it )
986         {
987             FFADODevice::ClockSource c=*it;
988             debugOutput(DEBUG_LEVEL_NORMAL, " Type: %s, Id: %2d, Valid: %1d, Active: %1d, Locked %1d, Slipping: %1d, Description: %s\n",
989                 FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.locked, c.slipping, c.description.c_str());
990         }
991     }
992 }
993 void
994 DeviceManager::showStreamingInfo() {
995     m_processorManager->dumpInfo();
996 }
Note: See TracBrowser for help on using the browser.