2 * Copyright (C) 2005-2008 by Daniel Wagner
3 * Copyright (C) 2005-2008 by Pieter Palmers
5 * This file is part of FFADO
6 * FFADO = Free Firewire (pro-)audio drivers for linux
8 * FFADO is based upon FreeBoB.
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.
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.
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/>.
28 #include "devicemanager.h"
29 #include "ffadodevice.h"
30 #include "DeviceStringParser.h"
32 #include "libieee1394/configrom.h"
33 #include "libieee1394/ieee1394service.h"
34 #include "libieee1394/IsoHandlerManager.h"
36 #include "libstreaming/generic/StreamProcessor.h"
37 #include "libstreaming/StreamProcessorManager.h"
39 #include "debugmodule/debugmodule.h"
41 #include "libutil/PosixMutex.h"
44 #include "bebob/bebob_avdevice.h"
47 #ifdef ENABLE_GENERICAVC
48 #include "genericavc/avc_avdevice.h"
51 #ifdef ENABLE_FIREWORKS
52 #include "fireworks/fireworks_device.h"
56 #include "oxford/oxford_device.h"
60 #include "bounce/bounce_avdevice.h"
61 #include "bounce/bounce_slave_avdevice.h"
65 #include "motu/motu_avdevice.h"
69 #include "rme/rme_avdevice.h"
73 #include "dice/dice_avdevice.h"
76 #ifdef ENABLE_METRIC_HALO
77 #include "metrichalo/mh_avdevice.h"
87 IMPL_DEBUG_MODULE( DeviceManager
, DeviceManager
, DEBUG_LEVEL_NORMAL
);
89 DeviceManager::DeviceManager()
90 : Control::Container(NULL
, "devicemanager") // this is the control root node
91 , m_DeviceListLock( new Util::PosixMutex("DEVLST") )
92 , m_BusResetLock( new Util::PosixMutex("DEVBR") )
93 , m_processorManager( new Streaming::StreamProcessorManager( *this ) )
94 , m_deviceStringParser( new DeviceStringParser() )
95 , m_configuration ( new Util::Configuration() )
96 , m_used_cache_last_time( false )
97 , m_thread_realtime( false )
98 , m_thread_priority( 0 )
100 addOption(Util::OptionContainer::Option("slaveMode", false));
101 addOption(Util::OptionContainer::Option("snoopMode", false));
104 DeviceManager::~DeviceManager()
106 // save configuration
107 if(!m_configuration
->save()) {
108 debugWarning("could not save configuration\n");
111 m_BusResetLock
->Lock(); // make sure we are not handling a busreset.
112 m_DeviceListLock
->Lock(); // make sure nobody is using this
113 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
114 it
!= m_avDevices
.end();
117 if (!deleteElement(*it
)) {
118 debugWarning("failed to remove Device from Control::Container\n");
122 m_DeviceListLock
->Unlock();
124 // the SP's are automatically unregistered from the SPM
125 delete m_processorManager
;
127 // the device list is empty, so wake up any waiting
129 m_BusResetLock
->Unlock();
131 // remove the bus-reset handlers
132 for ( FunctorVectorIterator it
= m_busreset_functors
.begin();
133 it
!= m_busreset_functors
.end();
139 for ( Ieee1394ServiceVectorIterator it
= m_1394Services
.begin();
140 it
!= m_1394Services
.end();
146 delete m_DeviceListLock
;
147 delete m_BusResetLock
;
148 delete m_deviceStringParser
;
152 DeviceManager::setThreadParameters(bool rt
, int priority
) {
153 if (!m_processorManager
->setThreadParameters(rt
, priority
)) {
154 debugError("Could not set processor manager thread parameters\n");
157 for ( Ieee1394ServiceVectorIterator it
= m_1394Services
.begin();
158 it
!= m_1394Services
.end();
161 if (!(*it
)->setThreadParameters(rt
, priority
)) {
162 debugError("Could not set 1394 service thread parameters\n");
166 m_thread_realtime
= rt
;
167 m_thread_priority
= priority
;
172 DeviceManager::initialize()
174 assert(m_1394Services
.size() == 0);
175 assert(m_busreset_functors
.size() == 0);
177 m_configuration
->openFile( "temporary", Util::Configuration::eFM_Temporary
);
178 m_configuration
->openFile( USER_CONFIG_FILE
, Util::Configuration::eFM_ReadWrite
);
179 m_configuration
->openFile( SYSTEM_CONFIG_FILE
, Util::Configuration::eFM_ReadOnly
);
181 int nb_detected_ports
= Ieee1394Service::detectNbPorts();
182 if (nb_detected_ports
< 0) {
183 debugFatal("Failed to detect the number of 1394 adapters. Is the IEEE1394 stack loaded (raw1394)?\n");
186 if (nb_detected_ports
== 0) {
187 debugFatal("No firewire adapters (ports) found.\n");
190 debugOutput( DEBUG_LEVEL_VERBOSE
, "Found %d firewire adapters (ports)\n", nb_detected_ports
);
191 for (unsigned int port
= 0; port
< (unsigned int)nb_detected_ports
; port
++) {
192 Ieee1394Service
* tmp1394Service
= new Ieee1394Service();
193 if ( !tmp1394Service
) {
194 debugFatal( "Could not create Ieee1349Service object for port %d\n", port
);
197 tmp1394Service
->setVerboseLevel( getDebugLevel() );
198 m_1394Services
.push_back(tmp1394Service
);
200 if(!tmp1394Service
->useConfiguration(m_configuration
)) {
201 debugWarning("Could not load config to 1394service\n");
204 tmp1394Service
->setThreadParameters(m_thread_realtime
, m_thread_priority
);
205 if ( !tmp1394Service
->initialize( port
) ) {
206 debugFatal( "Could not initialize Ieee1349Service object for port %d\n", port
);
209 // add the bus reset handler
210 Util::Functor
* tmp_busreset_functor
= new Util::MemberFunctor1
< DeviceManager
*,
211 void (DeviceManager::*)(Ieee1394Service
&), Ieee1394Service
& >
212 ( this, &DeviceManager::busresetHandler
, *tmp1394Service
, false );
213 if ( !tmp_busreset_functor
) {
214 debugFatal( "Could not create busreset handler for port %d\n", port
);
217 m_busreset_functors
.push_back(tmp_busreset_functor
);
219 tmp1394Service
->addBusResetHandler( tmp_busreset_functor
);
226 DeviceManager::addSpecString(char *s
) {
227 std::string spec
= s
;
228 if(isSpecStringValid(spec
)) {
229 debugOutput(DEBUG_LEVEL_VERBOSE
, "Adding spec string %s\n", spec
.c_str());
230 assert(m_deviceStringParser
);
231 m_deviceStringParser
->parseString(spec
);
234 debugError("Invalid spec string: %s\n", spec
.c_str());
240 DeviceManager::isSpecStringValid(std::string s
) {
241 assert(m_deviceStringParser
);
242 return m_deviceStringParser
->isValidString(s
);
246 DeviceManager::busresetHandler(Ieee1394Service
&service
)
248 // serialize bus reset handling since it can be that a new one occurs while we're
250 debugOutput( DEBUG_LEVEL_NORMAL
, "Bus reset detected on service %p...\n", &service
);
251 Util::MutexLockHelper
lock(*m_BusResetLock
);
252 debugOutput( DEBUG_LEVEL_NORMAL
, " handling busreset...\n" );
254 // FIXME: what if the devices are gone? (device should detect this!)
255 // propagate the bus reset to all avDevices
256 m_DeviceListLock
->Lock(); // make sure nobody is using this
257 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
258 it
!= m_avDevices
.end();
261 if(&service
== &((*it
)->get1394Service())) {
262 debugOutput(DEBUG_LEVEL_NORMAL
,
263 "issue busreset on device GUID %s\n",
264 (*it
)->getConfigRom().getGuidString().c_str());
265 (*it
)->handleBusReset();
267 debugOutput(DEBUG_LEVEL_NORMAL
,
268 "skipping device GUID %s since not on service %p\n",
269 (*it
)->getConfigRom().getGuidString().c_str(), &service
);
272 m_DeviceListLock
->Unlock();
274 // now that the devices have been updates, we can request to update the iso streams
275 if(!service
.getIsoHandlerManager().handleBusReset()) {
276 debugError("IsoHandlerManager failed to handle busreset\n");
279 // notify the streamprocessormanager of the busreset
280 // if(m_processorManager) {
281 // m_processorManager->handleBusReset(service);
283 // debugWarning("No valid SPM\n");
286 // rediscover to find new devices
287 // (only for the control server ATM, streaming can't dynamically add/remove devices)
288 if(!discover(m_used_cache_last_time
, true)) {
289 debugError("Could not rediscover devices\n");
292 // notify any clients
293 signalNotifiers(m_busResetNotifiers
);
295 // display the new state
296 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE
) {
302 DeviceManager::signalNotifiers(notif_vec_t
& list
)
304 for ( notif_vec_t::iterator it
= list
.begin();
308 Util::Functor
* func
= *it
;
309 debugOutput( DEBUG_LEVEL_VERBOSE
, " running notifier %p...\n", func
);
315 DeviceManager::registerNotification(notif_vec_t
& list
, Util::Functor
*handler
)
317 debugOutput( DEBUG_LEVEL_VERBOSE
, "register %p...\n", handler
);
319 for ( notif_vec_t::iterator it
= list
.begin();
323 if ( *it
== handler
) {
324 debugOutput(DEBUG_LEVEL_VERBOSE
, "already registered\n");
328 list
.push_back(handler
);
333 DeviceManager::unregisterNotification(notif_vec_t
& list
, Util::Functor
*handler
)
335 debugOutput( DEBUG_LEVEL_VERBOSE
, "unregister %p...\n", handler
);
338 for ( notif_vec_t::iterator it
= list
.begin();
342 if ( *it
== handler
) {
347 debugError("Could not find handler (%p)\n", handler
);
348 return false; //not found
352 DeviceManager::discover( bool useCache
, bool rediscover
)
354 debugOutput( DEBUG_LEVEL_NORMAL
, "Starting discovery...\n" );
355 useCache
= useCache
&& ENABLE_DISCOVERY_CACHE
;
356 m_used_cache_last_time
= useCache
;
357 bool slaveMode
=false;
358 if(!getOption("slaveMode", slaveMode
)) {
359 debugWarning("Could not retrieve slaveMode parameter, defauling to false\n");
361 bool snoopMode
=false;
362 if(!getOption("snoopMode", snoopMode
)) {
363 debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
366 setVerboseLevel(getDebugLevel());
368 // FIXME: it could be that a 1394service has disappeared (cardbus)
370 ConfigRomVector configRoms
;
371 // build a list of configroms on the bus.
372 for ( Ieee1394ServiceVectorIterator it
= m_1394Services
.begin();
373 it
!= m_1394Services
.end();
376 Ieee1394Service
*portService
= *it
;
377 for ( fb_nodeid_t nodeId
= 0;
378 nodeId
< portService
->getNodeCount();
381 debugOutput( DEBUG_LEVEL_VERBOSE
, "Probing node %d...\n", nodeId
);
383 if (nodeId
== portService
->getLocalNodeId()) {
384 debugOutput( DEBUG_LEVEL_VERBOSE
, "Skipping local node (%d)...\n", nodeId
);
388 ConfigRom
* configRom
= new ConfigRom( *portService
, nodeId
);
389 if ( !configRom
->initialize() ) {
390 // \todo If a PHY on the bus is in power safe mode then
391 // the config rom is missing. So this might be just
392 // such this case and we can safely skip it. But it might
393 // be there is a real software problem on our side.
394 // This should be handlede more carefuly.
395 debugOutput( DEBUG_LEVEL_NORMAL
,
396 "Could not read config rom from device (node id %d). "
397 "Skip device discovering for this node\n",
401 configRoms
.push_back(configRom
);
406 // notify that we are going to manipulate the list
407 signalNotifiers(m_preUpdateNotifiers
);
408 m_DeviceListLock
->Lock(); // make sure nobody starts using the list
411 FFADODeviceVector discovered_devices_on_bus
;
412 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
413 it
!= m_avDevices
.end();
416 bool seen_device
= false;
417 for ( ConfigRomVectorIterator it2
= configRoms
.begin();
418 it2
!= configRoms
.end();
421 seen_device
|= ((*it
)->getConfigRom().getGuid() == (*it2
)->getGuid());
425 debugOutput( DEBUG_LEVEL_VERBOSE
,
426 "Already discovered device with GUID: %s\n",
427 (*it
)->getConfigRom().getGuidString().c_str() );
428 // we already discovered this device, and it is still here. keep it
429 discovered_devices_on_bus
.push_back(*it
);
431 debugOutput( DEBUG_LEVEL_VERBOSE
,
432 "Device with GUID: %s disappeared from bus, removing...\n",
433 (*it
)->getConfigRom().getGuidString().c_str() );
435 // the device has disappeared, remove it from the control tree
436 if (!deleteElement(*it
)) {
437 debugWarning("failed to remove Device from Control::Container\n");
440 // FIXME: this will mess up the any code that waits for bus resets to
445 // prune the devices that disappeared
446 m_avDevices
= discovered_devices_on_bus
;
447 } else { // remove everything since we are not rediscovering
448 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
449 it
!= m_avDevices
.end();
452 if (!deleteElement(*it
)) {
453 debugWarning("failed to remove Device from Control::Container\n");
461 // delete the config rom list entries
462 // FIXME: we should reuse it
463 for ( ConfigRomVectorIterator it
= configRoms
.begin();
464 it
!= configRoms
.end();
470 assert(m_deviceStringParser
);
471 // show the spec strings we're going to use
472 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE
) {
473 m_deviceStringParser
->show();
477 // for the devices that are still in the list check if they require re-discovery
478 FFADODeviceVector failed_to_rediscover
;
479 for ( FFADODeviceVectorIterator it_dev
= m_avDevices
.begin();
480 it_dev
!= m_avDevices
.end();
483 FFADODevice
* avDevice
= *it_dev
;
484 if(avDevice
->needsRediscovery()) {
485 debugOutput( DEBUG_LEVEL_NORMAL
,
486 "Device with GUID %s requires rediscovery (state changed)...\n",
487 avDevice
->getConfigRom().getGuidString().c_str());
489 bool isFromCache
= false;
490 if ( useCache
&& avDevice
->loadFromCache() ) {
491 debugOutput( DEBUG_LEVEL_VERBOSE
, "could load from cache\n" );
493 // restore the debug level for everything that was loaded
494 avDevice
->setVerboseLevel( getDebugLevel() );
495 } else if ( avDevice
->discover() ) {
496 debugOutput( DEBUG_LEVEL_VERBOSE
, "discovery successful\n" );
498 debugError( "could not discover device\n" );
499 failed_to_rediscover
.push_back(avDevice
);
502 if ( !isFromCache
&& !avDevice
->saveCache() ) {
503 debugOutput( DEBUG_LEVEL_VERBOSE
, "No cached version of AVC model created\n" );
506 debugOutput( DEBUG_LEVEL_NORMAL
,
507 "Device with GUID %s does not require rediscovery...\n",
508 avDevice
->getConfigRom().getGuidString().c_str());
511 // remove devices that failed to rediscover
512 // FIXME: surely there has to be a better way to do this
513 FFADODeviceVector to_keep
;
514 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
515 it
!= m_avDevices
.end();
518 bool keep_this_device
= true;
519 for ( FFADODeviceVectorIterator it2
= failed_to_rediscover
.begin();
520 it2
!= failed_to_rediscover
.end();
524 debugOutput( DEBUG_LEVEL_NORMAL
,
525 "Removing device with GUID %s due to failed discovery...\n",
526 (*it
)->getConfigRom().getGuidString().c_str());
527 keep_this_device
= false;
531 if(keep_this_device
) {
532 to_keep
.push_back(*it
);
535 for ( FFADODeviceVectorIterator it2
= failed_to_rediscover
.begin();
536 it2
!= failed_to_rediscover
.end();
539 if (!deleteElement(*it2
)) {
540 debugWarning("failed to remove Device from Control::Container\n");
544 m_avDevices
= to_keep
;
546 // pick up new devices
547 for ( Ieee1394ServiceVectorIterator it
= m_1394Services
.begin();
548 it
!= m_1394Services
.end();
551 Ieee1394Service
*portService
= *it
;
552 for ( fb_nodeid_t nodeId
= 0;
553 nodeId
< portService
->getNodeCount();
556 debugOutput( DEBUG_LEVEL_VERBOSE
, "Probing node %d...\n", nodeId
);
558 if (nodeId
== portService
->getLocalNodeId()) {
559 debugOutput( DEBUG_LEVEL_VERBOSE
, "Skipping local node (%d)...\n", nodeId
);
563 ConfigRom
*configRom
= new ConfigRom( *portService
, 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 handlede 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",
577 bool already_in_vector
= false;
578 for ( FFADODeviceVectorIterator it_dev
= m_avDevices
.begin();
579 it_dev
!= m_avDevices
.end();
582 if ((*it_dev
)->getConfigRom().getGuid() == configRom
->getGuid()) {
583 already_in_vector
= true;
587 if(already_in_vector
) {
589 debugWarning("Device with GUID %s already discovered on other port, skipping device...\n",
590 configRom
->getGuidString().c_str());
595 if(getDebugLevel() >= DEBUG_LEVEL_VERBOSE
) {
596 configRom
->printConfigRomDebug();
599 // if spec strings are given, only add those devices
600 // that match the spec string(s).
601 // if no (valid) spec strings are present, grab all
602 // supported devices.
603 if(m_deviceStringParser
->countDeviceStrings() &&
604 !m_deviceStringParser
->match(*configRom
)) {
605 debugOutput(DEBUG_LEVEL_VERBOSE
, "Device doesn't match any of the spec strings. skipping...\n");
610 FFADODevice
* avDevice
= getDriverForDevice( configRom
,
614 debugOutput( DEBUG_LEVEL_NORMAL
,
615 "driver found for device %d\n",
618 avDevice
->setVerboseLevel( getDebugLevel() );
619 bool isFromCache
= false;
620 if ( useCache
&& avDevice
->loadFromCache() ) {
621 debugOutput( DEBUG_LEVEL_VERBOSE
, "could load from cache\n" );
623 // restore the debug level for everything that was loaded
624 avDevice
->setVerboseLevel( getDebugLevel() );
625 } else if ( avDevice
->discover() ) {
626 debugOutput( DEBUG_LEVEL_VERBOSE
, "discovery successful\n" );
628 debugError( "could not discover device\n" );
634 debugOutput( DEBUG_LEVEL_VERBOSE
,
635 "Enabling snoop mode on node %d...\n", nodeId
);
637 if(!avDevice
->setOption("snoopMode", snoopMode
)) {
638 debugWarning("Could not set snoop mode for device on node %d\n", nodeId
);
644 if ( !isFromCache
&& !avDevice
->saveCache() ) {
645 debugOutput( DEBUG_LEVEL_VERBOSE
, "No cached version of AVC model created\n" );
647 m_avDevices
.push_back( avDevice
);
649 if (!addElement(avDevice
)) {
650 debugWarning("failed to add Device to Control::Container\n");
653 debugOutput( DEBUG_LEVEL_NORMAL
, "discovery of node %d on port %d done...\n", nodeId
, portService
->getPort() );
655 // we didn't get a device, hence we have to delete the configrom ptr manually
661 debugOutput( DEBUG_LEVEL_NORMAL
, "Discovery finished...\n" );
662 // FIXME: do better sorting
663 // sort the m_avDevices vector on their GUID
664 // then assign reassign the id's to the devices
665 // the side effect of this is that for the same set of attached devices,
666 // a device id always corresponds to the same device
667 sort(m_avDevices
.begin(), m_avDevices
.end(), FFADODevice::compareGUID
);
670 if(m_deviceStringParser
->countDeviceStrings()) { // only if there are devicestrings
671 // first map the devices to a position using the device spec strings
672 std::map
<fb_octlet_t
, int> positionMap
;
673 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
674 it
!= m_avDevices
.end();
677 int pos
= m_deviceStringParser
->matchPosition((*it
)->getConfigRom());
678 fb_octlet_t guid
= (*it
)->getConfigRom().getGuid();
679 positionMap
[guid
] = pos
;
680 debugOutput( DEBUG_LEVEL_VERBOSE
, "Mapping %s to position %d...\n", (*it
)->getConfigRom().getGuidString().c_str(), pos
);
683 // now run over all positions, and add the devices that belong to it
684 FFADODeviceVector sorted
;
685 int nbPositions
= m_deviceStringParser
->countDeviceStrings();
686 for (i
=0; i
< nbPositions
; i
++) {
687 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
688 it
!= m_avDevices
.end();
691 fb_octlet_t guid
= (*it
)->getConfigRom().getGuid();
692 if(positionMap
[guid
] == i
) {
693 sorted
.push_back(*it
);
697 // assign the new vector
699 assert(sorted
.size() == m_avDevices
.size());
700 m_avDevices
= sorted
;
705 } else { // slave mode
706 // notify any clients
707 signalNotifiers(m_preUpdateNotifiers
);
708 Ieee1394Service
*portService
= m_1394Services
.at(0);
709 fb_nodeid_t nodeId
= portService
->getLocalNodeId();
710 debugOutput( DEBUG_LEVEL_VERBOSE
, "Starting in slave mode on node %d...\n", nodeId
);
712 std::auto_ptr
<ConfigRom
> configRom
=
713 std::auto_ptr
<ConfigRom
>( new ConfigRom( *portService
,
715 if ( !configRom
->initialize() ) {
716 // \todo If a PHY on the bus is in power safe mode then
717 // the config rom is missing. So this might be just
718 // such this case and we can safely skip it. But it might
719 // be there is a real software problem on our side.
720 // This should be handled more carefuly.
721 debugOutput( DEBUG_LEVEL_NORMAL
,
722 "Could not read config rom from device (node id %d). "
723 "Skip device discovering for this node\n",
728 // remove any already present devices
729 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
730 it
!= m_avDevices
.end();
733 if (!deleteElement(*it
)) {
734 debugWarning("failed to remove Device from Control::Container\n");
741 // get the slave driver
742 FFADODevice
* avDevice
= getSlaveDriver( configRom
);
744 debugOutput( DEBUG_LEVEL_NORMAL
,
745 "driver found for device %d\n",
748 avDevice
->setVerboseLevel( getDebugLevel() );
750 if ( !avDevice
->discover() ) {
751 debugError( "could not discover device\n" );
756 if ( getDebugLevel() >= DEBUG_LEVEL_VERBOSE
) {
757 avDevice
->showDevice();
759 m_avDevices
.push_back( avDevice
);
760 debugOutput( DEBUG_LEVEL_NORMAL
, "discovery of node %d on port %d done...\n", nodeId
, portService
->getPort() );
763 debugOutput( DEBUG_LEVEL_NORMAL
, "discovery finished...\n" );
766 m_DeviceListLock
->Unlock();
767 // notify any clients
768 signalNotifiers(m_postUpdateNotifiers
);
773 DeviceManager::initStreaming()
775 // iterate over the found devices
776 // add the stream processors of the devices to the managers
777 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
778 it
!= m_avDevices
.end();
781 FFADODevice
*device
= *it
;
784 debugOutput(DEBUG_LEVEL_VERBOSE
, "Locking device (%p)\n", device
);
786 if (!device
->lock()) {
787 debugWarning("Could not lock device, skipping device (%p)!\n", device
);
791 debugOutput(DEBUG_LEVEL_VERBOSE
, "Setting samplerate to %d for (%p)\n",
792 m_processorManager
->getNominalRate(), device
);
794 // Set the device's sampling rate to that requested
795 // FIXME: does this really belong here? If so we need to handle errors.
796 if (!device
->setSamplingFrequency(m_processorManager
->getNominalRate())) {
797 debugOutput(DEBUG_LEVEL_VERBOSE
, " => Retry setting samplerate to %d for (%p)\n",
798 m_processorManager
->getNominalRate(), device
);
801 if (!device
->setSamplingFrequency(m_processorManager
->getNominalRate())) {
802 debugFatal("Could not set sampling frequency to %d\n",m_processorManager
->getNominalRate());
806 // prepare the device
810 // set the sync source
811 if (!m_processorManager
->setSyncSource(getSyncSource())) {
812 debugWarning("Could not set processorManager sync source (%p)\n",
820 DeviceManager::prepareStreaming()
822 if (!m_processorManager
->prepare()) {
823 debugFatal("Could not prepare streaming...\n");
830 DeviceManager::finishStreaming() {
832 // iterate over the found devices
833 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
834 it
!= m_avDevices
.end();
837 debugOutput(DEBUG_LEVEL_VERBOSE
, "Unlocking device (%p)\n", *it
);
839 if (!(*it
)->unlock()) {
840 debugWarning("Could not unlock device (%p)!\n", *it
);
848 DeviceManager::startStreamingOnDevice(FFADODevice
*device
)
853 bool all_streams_started
= true;
854 bool device_start_failed
= false;
856 if (device
->resetForStreaming() == false)
859 for(j
=0; j
< device
->getStreamCount(); j
++) {
860 debugOutput(DEBUG_LEVEL_VERBOSE
,"Starting stream %d of device %p\n", j
, device
);
862 if (!device
->startStreamByIndex(j
)) {
863 debugWarning("Could not start stream %d of device %p\n", j
, device
);
864 all_streams_started
= false;
869 if(!all_streams_started
) {
870 // disable all streams that did start up correctly
871 for(j
= j
-1; j
>= 0; j
--) {
872 debugOutput(DEBUG_LEVEL_VERBOSE
,"Stopping stream %d of device %p\n", j
, device
);
874 if (!device
->stopStreamByIndex(j
)) {
875 debugWarning("Could not stop stream %d of device %p\n", j
, device
);
878 device_start_failed
= true;
880 if (!device
->enableStreaming()) {
881 debugWarning("Could not enable streaming on device %p!\n", device
);
882 device_start_failed
= true;
885 return !device_start_failed
;
889 DeviceManager::startStreaming() {
890 bool device_start_failed
= false;
891 FFADODeviceVectorIterator it
;
893 // create the connections for all devices
894 // iterate over the found devices
895 for ( it
= m_avDevices
.begin();
896 it
!= m_avDevices
.end();
899 if (!startStreamingOnDevice(*it
)) {
900 debugWarning("Could not start streaming on device %p!\n", *it
);
901 device_start_failed
= true;
906 // if one of the devices failed to start,
907 // the previous routine should have cleaned up the failing one.
908 // we still have to stop all devices that were started before this one.
909 if(device_start_failed
) {
910 for (FFADODeviceVectorIterator it2
= m_avDevices
.begin();
914 if (!stopStreamingOnDevice(*it2
)) {
915 debugWarning("Could not stop streaming on device %p!\n", *it2
);
921 // start the stream processor manager to tune in to the channels
922 if(m_processorManager
->start()) {
925 debugWarning("Failed to start SPM!\n");
926 for( it
= m_avDevices
.begin();
927 it
!= m_avDevices
.end();
930 if (!stopStreamingOnDevice(*it
)) {
931 debugWarning("Could not stop streaming on device %p!\n", *it
);
939 DeviceManager::resetStreaming() {
944 DeviceManager::stopStreamingOnDevice(FFADODevice
*device
)
949 if (!device
->disableStreaming()) {
950 debugWarning("Could not disable streaming on device %p!\n", device
);
954 for(j
=0; j
< device
->getStreamCount(); j
++) {
955 debugOutput(DEBUG_LEVEL_VERBOSE
,"Stopping stream %d of device %p\n", j
, device
);
958 if (!device
->stopStreamByIndex(j
)) {
959 debugWarning("Could not stop stream %d of device %p\n", j
, device
);
968 DeviceManager::stopStreaming()
971 m_processorManager
->stop();
973 // create the connections for all devices
974 // iterate over the found devices
975 // add the stream processors of the devices to the managers
976 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
977 it
!= m_avDevices
.end();
980 stopStreamingOnDevice(*it
);
985 enum DeviceManager::eWaitResult
986 DeviceManager::waitForPeriod() {
987 if(m_processorManager
->waitForPeriod()) {
990 if(m_processorManager
->shutdownNeeded()) {
991 debugWarning("Shutdown requested\n");
994 debugWarning("XRUN detected\n");
996 if(m_processorManager
->handleXrun()) {
999 debugError("Could not handle XRUN\n");
1007 DeviceManager::setPeriodSize(unsigned int period
) {
1008 // Useful for cases where only the period size needs adjusting
1009 if (!m_processorManager
->streamingParamsOk(period
, -1, -1)) {
1012 m_processorManager
->setPeriodSize(period
);
1017 DeviceManager::setStreamingParams(unsigned int period
, unsigned int rate
, unsigned int nb_buffers
) {
1018 if (!m_processorManager
->streamingParamsOk(period
, rate
, nb_buffers
)) {
1021 m_processorManager
->setPeriodSize(period
);
1022 m_processorManager
->setNominalRate(rate
);
1023 m_processorManager
->setNbBuffers(nb_buffers
);
1028 DeviceManager::getDriverForDeviceDo( ConfigRom
*configRom
,
1029 int id
, bool generic
)
1032 debugOutput( DEBUG_LEVEL_VERBOSE
, "Trying BeBoB...\n" );
1033 if ( BeBoB::Device::probe( getConfiguration(), *configRom
, generic
) ) {
1034 return BeBoB::Device::createDevice( *this, std::auto_ptr
<ConfigRom
>( configRom
) );
1038 #ifdef ENABLE_FIREWORKS
1039 debugOutput( DEBUG_LEVEL_VERBOSE
, "Trying ECHO Audio FireWorks...\n" );
1040 if ( FireWorks::Device::probe( getConfiguration(), *configRom
, generic
) ) {
1041 return FireWorks::Device::createDevice( *this, std::auto_ptr
<ConfigRom
>( configRom
) );
1045 #ifdef ENABLE_OXFORD
1046 debugOutput( DEBUG_LEVEL_VERBOSE
, "Trying Oxford FW90x...\n" );
1047 if ( Oxford::Device::probe( getConfiguration(), *configRom
, generic
) ) {
1048 return Oxford::Device::createDevice( *this, std::auto_ptr
<ConfigRom
>( configRom
) );
1052 // we want to try the non-generic AV/C platforms before trying the generic ones
1053 #ifdef ENABLE_GENERICAVC
1054 debugOutput( DEBUG_LEVEL_VERBOSE
, "Trying Generic AV/C...\n" );
1055 if ( GenericAVC::Device::probe( getConfiguration(), *configRom
, generic
) ) {
1056 return GenericAVC::Device::createDevice( *this, std::auto_ptr
<ConfigRom
>( configRom
) );
1061 debugOutput( DEBUG_LEVEL_VERBOSE
, "Trying Motu...\n" );
1062 if ( Motu::MotuDevice::probe( getConfiguration(), *configRom
, generic
) ) {
1063 return Motu::MotuDevice::createDevice( *this, std::auto_ptr
<ConfigRom
>( configRom
) );
1068 debugOutput( DEBUG_LEVEL_VERBOSE
, "Trying Dice...\n" );
1069 if ( Dice::Device::probe( getConfiguration(), *configRom
, generic
) ) {
1070 return Dice::Device::createDevice( *this, std::auto_ptr
<ConfigRom
>( configRom
) );
1074 #ifdef ENABLE_METRIC_HALO
1075 debugOutput( DEBUG_LEVEL_VERBOSE
, "Trying Metric Halo...\n" );
1076 if ( MetricHalo::Device::probe( getConfiguration(), *configRom
, generic
) ) {
1077 return MetricHalo::Device::createDevice( *this, std::auto_ptr
<ConfigRom
>( configRom
) );
1082 debugOutput( DEBUG_LEVEL_VERBOSE
, "Trying RME...\n" );
1083 if ( Rme::Device::probe( getConfiguration(), *configRom
, generic
) ) {
1084 return Rme::Device::createDevice( *this, std::auto_ptr
<ConfigRom
>( configRom
) );
1088 #ifdef ENABLE_BOUNCE
1089 debugOutput( DEBUG_LEVEL_VERBOSE
, "Trying Bounce...\n" );
1090 if ( Bounce::Device::probe( getConfiguration(), *configRom
, generic
) ) {
1091 return Bounce::Device::createDevice( *this, std::auto_ptr
<ConfigRom
>( configRom
) );
1099 DeviceManager::getDriverForDevice( ConfigRom
*configRom
,
1102 debugOutput( DEBUG_LEVEL_VERBOSE
, "Probing for supported device...\n" );
1103 FFADODevice
* dev
= getDriverForDeviceDo(configRom
, id
, false);
1105 debugOutput( DEBUG_LEVEL_VERBOSE
, " found supported device...\n" );
1106 dev
->setVerboseLevel(getDebugLevel());
1110 debugOutput( DEBUG_LEVEL_VERBOSE
, " no supported device found, trying generic support...\n" );
1111 dev
= getDriverForDeviceDo(configRom
, id
, true);
1113 debugOutput( DEBUG_LEVEL_VERBOSE
, " found generic support for device...\n" );
1114 dev
->setVerboseLevel(getDebugLevel());
1117 debugOutput( DEBUG_LEVEL_VERBOSE
, " device not supported...\n" );
1122 DeviceManager::getSlaveDriver( std::auto_ptr
<ConfigRom
>( configRom
) )
1124 #ifdef ENABLE_BOUNCE
1125 if ( Bounce::SlaveDevice::probe( getConfiguration(), *configRom
, false ) ) {
1126 return Bounce::SlaveDevice::createDevice( *this, std::auto_ptr
<ConfigRom
>( configRom
) );
1133 DeviceManager::isValidNode(int node
)
1135 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
1136 it
!= m_avDevices
.end();
1139 FFADODevice
* avDevice
= *it
;
1141 if (avDevice
->getConfigRom().getNodeId() == node
) {
1149 DeviceManager::getNbDevices()
1151 return m_avDevices
.size();
1155 DeviceManager::getDeviceNodeId( int deviceNr
)
1157 if ( ! ( deviceNr
< getNbDevices() ) ) {
1158 debugError( "Device number out of range (%d)\n", deviceNr
);
1162 FFADODevice
* avDevice
= m_avDevices
.at( deviceNr
);
1165 debugError( "Could not get device at position (%d)\n", deviceNr
);
1168 return avDevice
->getConfigRom().getNodeId();
1172 DeviceManager::getAvDevice( int nodeId
)
1174 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
1175 it
!= m_avDevices
.end();
1178 FFADODevice
* avDevice
= *it
;
1179 if ( avDevice
->getConfigRom().getNodeId() == nodeId
) {
1188 DeviceManager::getAvDeviceByIndex( int idx
)
1190 return m_avDevices
.at(idx
);
1194 DeviceManager::getAvDeviceCount( )
1196 return m_avDevices
.size();
1200 * Return the streamprocessor that is to be used as
1203 * Algorithm still to be determined
1205 * @return StreamProcessor that is sync source
1207 Streaming::StreamProcessor
*
1208 DeviceManager::getSyncSource() {
1209 FFADODevice
* device
= getAvDeviceByIndex(0);
1211 bool slaveMode
=false;
1212 if(!getOption("slaveMode", slaveMode
)) {
1213 debugOutput(DEBUG_LEVEL_NORMAL
,
1214 "Could not retrieve slaveMode parameter, defauling to false\n");
1216 return device
->getStreamProcessorByIndex(0);
1218 #warning TEST CODE FOR BOUNCE DEVICE !!
1219 // this makes the bounce slave use the xmit SP as sync source
1221 return device->getStreamProcessorByIndex(1);
1223 return device->getStreamProcessorByIndex(0);
1228 DeviceManager::deinitialize()
1234 DeviceManager::setVerboseLevel(int l
)
1237 Control::Element::setVerboseLevel(l
);
1238 m_processorManager
->setVerboseLevel(l
);
1239 m_deviceStringParser
->setVerboseLevel(l
);
1240 m_configuration
->setVerboseLevel(l
);
1241 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
1242 it
!= m_avDevices
.end();
1245 (*it
)->setVerboseLevel(l
);
1247 for ( Ieee1394ServiceVectorIterator it
= m_1394Services
.begin();
1248 it
!= m_1394Services
.end();
1251 (*it
)->setVerboseLevel(l
);
1253 debugOutput( DEBUG_LEVEL_VERBOSE
, "Setting verbose level to %d...\n", l
);
1257 DeviceManager::showDeviceInfo() {
1258 debugOutput(DEBUG_LEVEL_NORMAL
, "===== Device Manager =====\n");
1259 Control::Element::show();
1262 for ( Ieee1394ServiceVectorIterator it
= m_1394Services
.begin();
1263 it
!= m_1394Services
.end();
1266 debugOutput(DEBUG_LEVEL_NORMAL
, "--- IEEE1394 Service %2d ---\n", i
++);
1271 for ( FFADODeviceVectorIterator it
= m_avDevices
.begin();
1272 it
!= m_avDevices
.end();
1275 FFADODevice
* avDevice
= *it
;
1276 debugOutput(DEBUG_LEVEL_NORMAL
, "--- Device %2d ---\n", i
++);
1277 avDevice
->showDevice();
1279 debugOutput(DEBUG_LEVEL_NORMAL
, "Clock sync sources:\n");
1280 FFADODevice::ClockSourceVector sources
=avDevice
->getSupportedClockSources();
1281 for ( FFADODevice::ClockSourceVector::const_iterator it
1283 it
!= sources
.end();
1286 FFADODevice::ClockSource c
=*it
;
1287 debugOutput(DEBUG_LEVEL_NORMAL
, " Type: %s, Id: %2d, Valid: %1d, Active: %1d, Locked %1d, Slipping: %1d, Description: %s\n",
1288 FFADODevice::ClockSourceTypeToString(c
.type
), c
.id
, c
.valid
, c
.active
, c
.locked
, c
.slipping
, c
.description
.c_str());
1293 DeviceManager::showStreamingInfo() {
1294 m_processorManager
->dumpInfo();