diff --git a/include/hyperion/LinearColorSmoothing.h b/include/hyperion/LinearColorSmoothing.h index 5636c278..d22c5da5 100644 --- a/include/hyperion/LinearColorSmoothing.h +++ b/include/hyperion/LinearColorSmoothing.h @@ -289,6 +289,9 @@ private: int _currentConfigId; bool _enabled; + //The system enable state, to restore smoothing state after effect with smoothing ran + bool _enabledSystemCfg; + /// The type of smoothing to perform SmoothingType _smoothingType; diff --git a/libsrc/effectengine/EffectEngine.cpp b/libsrc/effectengine/EffectEngine.cpp index f192df99..2c5ab521 100644 --- a/libsrc/effectengine/EffectEngine.cpp +++ b/libsrc/effectengine/EffectEngine.cpp @@ -121,11 +121,17 @@ void EffectEngine::handleUpdatedEffectList() // add smoothing configurations to Hyperion if (def.args["smoothing-custom-settings"].toBool()) { + int settlingTime_ms = def.args["smoothing-time_ms"].toInt(); + double ledUpdateFrequency_hz = def.args["smoothing-updateFrequency"].toDouble(); + unsigned updateDelay {0}; + + Debug(_log, "Effect \"%s\": Add custom smoothing settings [%d]. Type: Linear, Settling time: %dms, Interval: %.fHz ", QSTRING_CSTR(def.name), specificId, settlingTime_ms, ledUpdateFrequency_hz); + def.smoothCfg = _hyperion->updateSmoothingConfig( - ++specificId, - def.args["smoothing-time_ms"].toInt(), - def.args["smoothing-updateFrequency"].toDouble(), - 0 ); + ++specificId, + settlingTime_ms, + ledUpdateFrequency_hz, + updateDelay ); } else { @@ -155,11 +161,18 @@ int EffectEngine::runEffect(const QString &effectName, const QJsonObject &args, //In case smoothing information is provided dynamically use temp smoothing config item (2) if (smoothCfg == SmoothingConfigID::SYSTEM && args["smoothing-custom-settings"].toBool()) { + int settlingTime_ms = args["smoothing-time_ms"].toInt(); + double ledUpdateFrequency_hz = args["smoothing-updateFrequency"].toDouble(); + unsigned updateDelay {0}; + + Debug(_log, "Effect \"%s\": Apply dynamic smoothing settings, if smoothing. Type: Linear, Settling time: %dms, Interval: %.fHz ", QSTRING_CSTR(effectName), settlingTime_ms, ledUpdateFrequency_hz); + smoothCfg = _hyperion->updateSmoothingConfig( - SmoothingConfigID::EFFECT_DYNAMIC, - args["smoothing-time_ms"].toInt(), - args["smoothing-updateFrequency"].toDouble(), - 0 ); + SmoothingConfigID::EFFECT_DYNAMIC, + settlingTime_ms, + ledUpdateFrequency_hz, + updateDelay + ); } if (pythonScript.isEmpty()) diff --git a/libsrc/hyperion/LinearColorSmoothing.cpp b/libsrc/hyperion/LinearColorSmoothing.cpp index 4cf6d4b9..c8d4d657 100644 --- a/libsrc/hyperion/LinearColorSmoothing.cpp +++ b/libsrc/hyperion/LinearColorSmoothing.cpp @@ -70,6 +70,7 @@ LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument &config, Hyperion , _pause(false) , _currentConfigId(SmoothingConfigID::SYSTEM) , _enabled(false) + , _enabledSystemCfg(false) , _smoothingType(SmoothingType::Linear) , tempValues(std::vector(0, 0L)) { @@ -114,11 +115,12 @@ void LinearColorSmoothing::handleSettingsUpdate(settings::type type, const QJson QJsonObject obj = config.object(); setEnable(obj["enable"].toBool(_enabled)); + _enabledSystemCfg = _enabled; - SmoothingCfg cfg(false, - static_cast(obj[SETTINGS_KEY_SETTLING_TIME].toInt(DEFAULT_SETTLINGTIME)), - static_cast(MS_PER_MICRO / obj[SETTINGS_KEY_UPDATE_FREQUENCY].toDouble(DEFAULT_UPDATEFREQUENCY)) - ); + int64_t settlingTime_ms = static_cast(obj[SETTINGS_KEY_SETTLING_TIME].toInt(DEFAULT_SETTLINGTIME)); + int _updateInterval_ms =static_cast(MS_PER_MICRO / obj[SETTINGS_KEY_UPDATE_FREQUENCY].toDouble(DEFAULT_UPDATEFREQUENCY)); + + SmoothingCfg cfg(false, settlingTime_ms, _updateInterval_ms); const QString typeString = obj[SETTINGS_KEY_SMOOTHING_TYPE].toString(); @@ -162,7 +164,10 @@ int LinearColorSmoothing::write(const std::vector &ledValues) _previousValues = ledValues; _previousInterpolationTime = micros(); - _timer->start(_updateInterval); + if (!_pause) + { + _timer->start(_updateInterval); + } } return 0; @@ -510,6 +515,8 @@ void LinearColorSmoothing::clearRememberedFrames() void LinearColorSmoothing::queueColors(const std::vector &ledColors) { + assert (ledColors.size() > 0); + if (_outputDelay == 0) { // No output delay => immediate write @@ -558,13 +565,16 @@ void LinearColorSmoothing::componentStateChange(hyperion::Components component, void LinearColorSmoothing::setEnable(bool enable) { - _enabled = enable; - if (!_enabled) + if ( _enabled != enable) { - clearQueuedColors(); + _enabled = enable; + if (!_enabled) + { + clearQueuedColors(); + } + // update comp register + _hyperion->setNewComponentState(hyperion::COMP_SMOOTHING, enable); } - // update comp register - _hyperion->setNewComponentState(hyperion::COMP_SMOOTHING, enable); } void LinearColorSmoothing::setPause(bool pause) @@ -603,7 +613,7 @@ unsigned LinearColorSmoothing::updateConfig(int cfgID, int settlingTime_ms, doub updateDelay }; _cfgList[updatedCfgID] = cfg; - DebugIf(verbose && _enabled, _log,"%s", QSTRING_CSTR(getConfig(updatedCfgID))); + Debug(_log,"%s", QSTRING_CSTR(getConfig(updatedCfgID))); } else { @@ -660,6 +670,19 @@ bool LinearColorSmoothing::selectConfig(int cfgID, bool force) _interpolationCounter = 0; _interpolationStatCounter = 0; + //Enable smoothing for effects with smoothing + if (cfgID >= SmoothingConfigID::EFFECT_DYNAMIC) + { + Debug(_log,"Run Effect with Smoothing enabled"); + _enabledSystemCfg = _enabled; + setEnable(true); + } + else + { + // Restore enabled state after running an effect with smoothing + setEnable(_enabledSystemCfg); + } + if (_cfgList[cfgID]._updateInterval != _updateInterval) { @@ -667,7 +690,10 @@ bool LinearColorSmoothing::selectConfig(int cfgID, bool force) _updateInterval = _cfgList[cfgID]._updateInterval; if (this->enabled()) { - _timer->start(_updateInterval); + if (!_pause && !_targetValues.empty()) + { + _timer->start(_updateInterval); + } } } _currentConfigId = cfgID; @@ -689,30 +715,36 @@ QString LinearColorSmoothing::getConfig(int cfgID) { SmoothingCfg cfg = _cfgList[cfgID]; - configText = QString ("[%1] - type: %2, pause: %3, settlingTime: %4ms, interval: %5ms (%6Hz), delay: %7 frames") - .arg(cfgID) - .arg(SmoothingCfg::EnumToString(cfg._type),(cfg._pause) ? "true" : "false") - .arg(cfg._settlingTime) - .arg(cfg._updateInterval) - .arg(int(MS_PER_MICRO/cfg._updateInterval)) - .arg(cfg._outputDelay); + configText = QString ("[%1] - Type: %2, Pause: %3") + .arg(cfgID) + .arg(SmoothingCfg::EnumToString(cfg._type),(cfg._pause) ? "true" : "false") ; switch (cfg._type) { - case SmoothingType::Linear: - break; - case SmoothingType::Decay: { const double thalf = (1.0-std::pow(1.0/2, 1.0/_decay))*_settlingTime; - configText += QString (", interpolationRate: %1Hz, dithering: %2, decay: %3 -> halftime: %4ms") - .arg(cfg._interpolationRate,0,'f',2) - .arg((cfg._dithering) ? "true" : "false") - .arg(cfg._decay,0,'f',2) - .arg(thalf,0,'f',2); + configText += QString (", Interpolation rate: %1Hz, Dithering: %2, decay: %3 -> Halftime: %4ms") + .arg(cfg._interpolationRate,0,'f',2) + .arg((cfg._dithering) ? "true" : "false") + .arg(cfg._decay,0,'f',2) + .arg(thalf,0,'f',2); + [[fallthrough]]; + } + + case SmoothingType::Linear: + { + configText += QString (", Settling time: %1ms, Interval: %2ms (%3Hz)") + .arg(cfg._settlingTime) + .arg(cfg._updateInterval) + .arg(int(MS_PER_MICRO/cfg._updateInterval)); break; } } + + configText += QString (", delay: %1 frames") + .arg(cfg._outputDelay); } + return configText; } @@ -736,7 +768,6 @@ LinearColorSmoothing::SmoothingCfg::SmoothingCfg(bool pause, int64_t settlingTim { } - QString LinearColorSmoothing::SmoothingCfg::EnumToString(SmoothingType type) { if (type == SmoothingType::Linear) {