Index: /branches/libffado-2.0/src/libieee1394/CycleTimerHelper.cpp =================================================================== --- /branches/libffado-2.0/src/libieee1394/CycleTimerHelper.cpp (revision 1466) +++ /branches/libffado-2.0/src/libieee1394/CycleTimerHelper.cpp (revision 1524) @@ -455,5 +455,5 @@ // i.e. DLL error signal int64_t diff_ticks_corr; - if (ticks_late > 0) { + if (ticks_late >= 0) { diff_ticks_corr = diff_ticks - ticks_late; debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, Index: /branches/libffado-2.0/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp =================================================================== --- /branches/libffado-2.0/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp (revision 1448) +++ /branches/libffado-2.0/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp (revision 1524) @@ -181,5 +181,5 @@ debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE, "(%p)->processReadBlock(%u, %u)\n", - this,nevents,offset); + this, nevents, offset); // update the variable parts of the cache @@ -366,18 +366,20 @@ for (i = 0; i < m_nb_midi_ports; i++) { struct _MIDI_port_cache &p = m_midi_ports.at(i); - if (p.buffer && p.enabled) { + if (p.buffer && p.enabled) { uint32_t *buffer = (quadlet_t *)(p.buffer); buffer += offset; - for (j = p.location;j < nevents; j += 8) { target_event = (quadlet_t *) (data + ((j * m_dimension) + p.position)); - sample_int=CondSwapFromBus32(*target_event); + sample_int = CondSwapFromBus32(*target_event); + // FIXME: this assumes that 2X and 3X speed isn't used, // because only the 1X slot is put into the ringbuffer - if(IEC61883_AM824_GET_LABEL(sample_int) != IEC61883_AM824_LABEL_MIDI_NO_DATA) { + if(IEC61883_AM824_HAS_LABEL(sample_int, IEC61883_AM824_LABEL_MIDI_1X)) { sample_int=(sample_int >> 16) & 0x000000FF; sample_int |= 0x01000000; // flag that there is a midi event present *buffer = sample_int; - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Received midi byte %08X on port %p index %d\n", sample_int, p, j-p.location); + } else if(IEC61883_AM824_HAS_LABEL(sample_int, IEC61883_AM824_LABEL_MIDI_2X) + || IEC61883_AM824_HAS_LABEL(sample_int, IEC61883_AM824_LABEL_MIDI_3X) ) { + debugOutput(DEBUG_LEVEL_VERBOSE, "Midi mode %X not supported.\n", IEC61883_AM824_GET_LABEL(sample_int)); } else { // make sure no event is received Index: /branches/libffado-2.0/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h =================================================================== --- /branches/libffado-2.0/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h (revision 1419) +++ /branches/libffado-2.0/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h (revision 1524) @@ -51,4 +51,6 @@ #define IEC61883_AM824_LABEL_MIDI_2X 0x82 #define IEC61883_AM824_LABEL_MIDI_3X 0x83 + +#define IEC61883_AM824_HAS_LABEL(x, lbl) (((x) & 0xFF000000) == (((quadlet_t)(lbl))<<24)) namespace Streaming { Index: /branches/libffado-2.0/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h =================================================================== --- /branches/libffado-2.0/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h (revision 1419) +++ /branches/libffado-2.0/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h (revision 1524) @@ -51,4 +51,6 @@ #define IEC61883_AM824_LABEL_MIDI_2X 0x82 #define IEC61883_AM824_LABEL_MIDI_3X 0x83 + +#define IEC61883_AM824_HAS_LABEL(x, lbl) (((x) & 0xFF000000) == (((quadlet_t)(lbl))<<24)) namespace Streaming { Index: /branches/libffado-2.0/src/libutil/Configuration.h =================================================================== --- /branches/libffado-2.0/src/libutil/Configuration.h (revision 1373) +++ /branches/libffado-2.0/src/libutil/Configuration.h (revision 1524) @@ -127,4 +127,19 @@ bool getValueForSetting(std::string path, int64_t &ref); + /** + * @brief retrieves a setting for a given device + * + * the value in the ref parameter is not changed if + * the function returns false. + * + * @param vendor_id vendor id for the device + * @param model_id model id for the device + * @param setting name of the setting + * @param ref reference to the integer that will hold the value. + * @return true if successful, false if not + */ + bool getValueForDeviceSetting(unsigned int vendor_id, unsigned model_id, std::string setting, int32_t &ref); + bool getValueForDeviceSetting(unsigned int vendor_id, unsigned model_id, std::string setting, int64_t &ref); + virtual void setVerboseLevel(int l) {setDebugLevel(l);}; virtual void show(); @@ -132,4 +147,5 @@ private: libconfig::Setting *getSetting( std::string path ); + libconfig::Setting *getDeviceSetting( unsigned int vendor_id, unsigned model_id ); int findFileName(std::string s); Index: /branches/libffado-2.0/src/libutil/Configuration.cpp =================================================================== --- /branches/libffado-2.0/src/libutil/Configuration.cpp (revision 1405) +++ /branches/libffado-2.0/src/libutil/Configuration.cpp (revision 1524) @@ -289,7 +289,40 @@ } - -Configuration::VendorModelEntry -Configuration::findDeviceVME( unsigned int vendor_id, unsigned model_id ) +bool +Configuration::getValueForDeviceSetting(unsigned int vendor_id, unsigned model_id, std::string setting, int32_t &ref) +{ + libconfig::Setting *s = getDeviceSetting( vendor_id, model_id ); + if(s) { + try { + return s->lookupValue(setting, ref); + } catch (...) { + debugOutput(DEBUG_LEVEL_VERBOSE, "Setting %s not found\n", setting.c_str()); + return false; + } + } else { + debugOutput(DEBUG_LEVEL_VERBOSE, "device %X/%X not found\n", vendor_id, model_id); + return false; + } +} + +bool +Configuration::getValueForDeviceSetting(unsigned int vendor_id, unsigned model_id, std::string setting, int64_t &ref) +{ + libconfig::Setting *s = getDeviceSetting( vendor_id, model_id ); + if(s) { + try { + return s->lookupValue(setting, ref); + } catch (...) { + debugOutput(DEBUG_LEVEL_VERBOSE, "Setting %s not found\n", setting.c_str()); + return false; + } + } else { + debugOutput(DEBUG_LEVEL_VERBOSE, "device %X/%X not found\n", vendor_id, model_id); + return false; + } +} + +libconfig::Setting * +Configuration::getDeviceSetting( unsigned int vendor_id, unsigned model_id ) { for ( std::vector::iterator it = m_ConfigFiles.begin(); @@ -309,18 +342,9 @@ uint32_t mid = modelid; if (vendor_id == vid && model_id == mid) { - struct VendorModelEntry vme; - vme.vendor_id = vendorid; - vme.model_id = modelid; - - const char *tmp = s["vendorname"]; - vme.vendor_name = tmp; - tmp = s["modelname"]; - vme.model_name = tmp; - vme.driver = s["driver"]; debugOutput(DEBUG_LEVEL_VERBOSE, " device VME for %X:%x found in %s\n", vendor_id, model_id, c->getName().c_str()); c->showSetting(s); - return vme; + return &s; } } catch (...) { @@ -330,4 +354,41 @@ } catch (...) { debugOutput(DEBUG_LEVEL_VERBOSE, " %s has no device definitions\n", c->getName().c_str()); + } + } + return NULL; +} + + + +Configuration::VendorModelEntry +Configuration::findDeviceVME( unsigned int vendor_id, unsigned model_id ) +{ + + // FIXME: clean this pointer/reference mess please + Setting *ps = getDeviceSetting(vendor_id, model_id); + + if(ps) { + Setting &s = *ps; + try { + Setting &vendorid = s["vendorid"]; + Setting &modelid = s["modelid"]; + uint32_t vid = vendorid; + uint32_t mid = modelid; + if (vendor_id == vid && model_id == mid) { + struct VendorModelEntry vme; + vme.vendor_id = vendorid; + vme.model_id = modelid; + + const char *tmp = s["vendorname"]; + vme.vendor_name = tmp; + tmp = s["modelname"]; + vme.model_name = tmp; + vme.driver = s["driver"]; + return vme; + } else { + debugError("BUG: vendor/model found but not found?\n"); + } + } catch (...) { + debugWarning("Bogus format\n"); } } Index: /branches/libffado-2.0/src/bebob/focusrite/focusrite_generic.cpp =================================================================== --- /branches/libffado-2.0/src/bebob/focusrite/focusrite_generic.cpp (revision 1371) +++ /branches/libffado-2.0/src/bebob/focusrite/focusrite_generic.cpp (revision 1524) @@ -26,5 +26,4 @@ #include "libutil/ByteSwap.h" -#include "libutil/SystemTimeSource.h" namespace BeBoB { @@ -33,4 +32,6 @@ FocusriteDevice::FocusriteDevice( DeviceManager& d, std::auto_ptr( configRom )) : BeBoB::AvDevice( d, configRom) + , m_cmd_time_interval( 0 ) + , m_earliest_next_cmd_time( 0 ) { debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Focusrite::FocusriteDevice (NodeID %d)\n", @@ -61,6 +62,16 @@ bool use_avc = false; if(!getOption("useAvcForParameters", use_avc)) { - debugWarning("Could not retrieve useAvcForParameters parameter, defauling to false\n"); - } + debugWarning("Could not retrieve useAvcForParameters parameter, defaulting to false\n"); + } + + // rate control + ffado_microsecs_t now = Util::SystemTimeSource::getCurrentTimeAsUsecs(); + if(m_cmd_time_interval && (m_earliest_next_cmd_time > now)) { + ffado_microsecs_t wait = m_earliest_next_cmd_time - now; + debugOutput( DEBUG_LEVEL_VERBOSE, "Rate control... %llu\n", wait ); + Util::SystemTimeSource::SleepUsecRelative(wait); + } + m_earliest_next_cmd_time = now + m_cmd_time_interval; + if (use_avc) { return setSpecificValueAvc(id, v); @@ -76,6 +87,17 @@ bool use_avc = false; if(!getOption("useAvcForParameters", use_avc)) { - debugWarning("Could not retrieve useAvcForParameters parameter, defauling to false\n"); - } + debugWarning("Could not retrieve useAvcForParameters parameter, defaulting to false\n"); + } + + // rate control + ffado_microsecs_t now = Util::SystemTimeSource::getCurrentTimeAsUsecs(); + if(m_cmd_time_interval && (m_earliest_next_cmd_time > now)) { + ffado_microsecs_t wait = m_earliest_next_cmd_time - now; + debugOutput( DEBUG_LEVEL_VERBOSE, "Rate control... %llu\n", wait ); + Util::SystemTimeSource::SleepUsecRelative(wait); + } + m_earliest_next_cmd_time = now + m_cmd_time_interval; + + // execute if (use_avc) { retval = getSpecificValueAvc(id, v); Index: /branches/libffado-2.0/src/bebob/focusrite/focusrite_saffire.cpp =================================================================== --- /branches/libffado-2.0/src/bebob/focusrite/focusrite_saffire.cpp (revision 1413) +++ /branches/libffado-2.0/src/bebob/focusrite/focusrite_saffire.cpp (revision 1524) @@ -25,4 +25,6 @@ #include "focusrite_cmd.h" +#include "devicemanager.h" + namespace BeBoB { namespace Focusrite { @@ -39,4 +41,17 @@ } else { m_isSaffireLE = true; + } + + // find the configured delay time for this device + Util::Configuration &config = d.getConfiguration(); + int delaytime = 0; + if(config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "cmd_interval_time", delaytime)) { + m_cmd_time_interval = delaytime; + debugOutput( DEBUG_LEVEL_VERBOSE, "Setting command interval time to %llu\n", + m_cmd_time_interval ); + } else { + m_cmd_time_interval = 10000; + debugOutput( DEBUG_LEVEL_VERBOSE, "No command interval time setting found, defaulting to %llu\n", + m_cmd_time_interval ); } } Index: /branches/libffado-2.0/src/bebob/focusrite/focusrite_generic.h =================================================================== --- /branches/libffado-2.0/src/bebob/focusrite/focusrite_generic.h (revision 1370) +++ /branches/libffado-2.0/src/bebob/focusrite/focusrite_generic.h (revision 1524) @@ -31,4 +31,6 @@ #include "libcontrol/BasicElements.h" #include "libcontrol/MatrixMixer.h" + +#include "libutil/SystemTimeSource.h" #define FR_PARAM_SPACE_START 0x000100000000LL @@ -236,4 +238,8 @@ bool setSpecificValueARM(uint32_t id, uint32_t v); bool getSpecificValueARM(uint32_t id, uint32_t *v); + +protected: + ffado_microsecs_t m_cmd_time_interval; + ffado_microsecs_t m_earliest_next_cmd_time; }; Index: /branches/libffado-2.0/src/devicemanager.cpp =================================================================== --- /branches/libffado-2.0/src/devicemanager.cpp (revision 1452) +++ /branches/libffado-2.0/src/devicemanager.cpp (revision 1524) @@ -948,4 +948,5 @@ if(dev) { debugOutput( DEBUG_LEVEL_VERBOSE, " found supported device...\n" ); + dev->setVerboseLevel(getDebugLevel()); return dev; } @@ -955,8 +956,9 @@ if(dev) { debugOutput( DEBUG_LEVEL_VERBOSE, " found generic support for device...\n" ); + dev->setVerboseLevel(getDebugLevel()); return dev; } debugOutput( DEBUG_LEVEL_VERBOSE, " device not supported...\n" ); - return 0; + return NULL; } @@ -964,5 +966,5 @@ DeviceManager::getSlaveDriver( std::auto_ptr( configRom ) ) { - return 0; + return NULL; } Index: /branches/libffado-2.0/configuration =================================================================== --- /branches/libffado-2.0/configuration (revision 1497) +++ /branches/libffado-2.0/configuration (revision 1524) @@ -106,4 +106,5 @@ driver = 1; # BeBoB mixer = "SaffireMixer"; + cmd_interval_time = 10000; }, { @@ -231,4 +232,11 @@ modelname = "Onyx 1200F"; driver = 2; + }, + { + vendorid = 0x00001260; + modelid = 0x00001000; + vendorname = "Stanton DJ"; + modelname = "SCS.1m"; + driver = 3; }, { # added by arnonym from ffado-mixers list Index: /branches/libffado-2.0/SConstruct =================================================================== --- /branches/libffado-2.0/SConstruct (revision 1513) +++ /branches/libffado-2.0/SConstruct (revision 1524) @@ -53,5 +53,5 @@ BoolOption( "DEBUG", """\ Toggle debug-build. DEBUG means \"-g -Wall\" and more, otherwise we will use - \"-O2\" to optimise.""", True ), + \"-O2\" to optimize.""", True ), BoolOption( "PROFILE", "Build with symbols and other profiling info", False ), PathOption( "PREFIX", "The prefix where ffado will be installed to.", "/usr/local", PathOption.PathAccept ),