mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Fix Effects and refactor Smoothing (#1442)
This commit is contained in:
		@@ -211,6 +211,7 @@
 | 
				
			|||||||
    "dashboard_newsbox_readmore": "Read more",
 | 
					    "dashboard_newsbox_readmore": "Read more",
 | 
				
			||||||
    "dashboard_newsbox_visitblog": "Visit Hyperion-Blog",
 | 
					    "dashboard_newsbox_visitblog": "Visit Hyperion-Blog",
 | 
				
			||||||
    "edt_append_degree": "°",
 | 
					    "edt_append_degree": "°",
 | 
				
			||||||
 | 
					    "edt_append_frames": "frames",
 | 
				
			||||||
    "edt_append_hz": "Hz",
 | 
					    "edt_append_hz": "Hz",
 | 
				
			||||||
    "edt_append_leds": "LEDs",
 | 
					    "edt_append_leds": "LEDs",
 | 
				
			||||||
    "edt_append_ms": "ms",
 | 
					    "edt_append_ms": "ms",
 | 
				
			||||||
@@ -424,8 +425,8 @@
 | 
				
			|||||||
    "edt_conf_smooth_time_ms_title": "Time",
 | 
					    "edt_conf_smooth_time_ms_title": "Time",
 | 
				
			||||||
    "edt_conf_smooth_type_expl": "Type of smoothing.",
 | 
					    "edt_conf_smooth_type_expl": "Type of smoothing.",
 | 
				
			||||||
    "edt_conf_smooth_type_title": "Type",
 | 
					    "edt_conf_smooth_type_title": "Type",
 | 
				
			||||||
    "edt_conf_smooth_updateDelay_expl": "Delay the output in case your ambient light is faster than your TV.",
 | 
					    "edt_conf_smooth_updateDelay_expl": "Delay the output by n updates in case your ambient light is faster than your TV.",
 | 
				
			||||||
    "edt_conf_smooth_updateDelay_title": "Update delay",
 | 
					    "edt_conf_smooth_updateDelay_title": "Output delay",
 | 
				
			||||||
    "edt_conf_smooth_updateFrequency_expl": "The output speed to your LED controller.",
 | 
					    "edt_conf_smooth_updateFrequency_expl": "The output speed to your LED controller.",
 | 
				
			||||||
    "edt_conf_smooth_updateFrequency_title": "Update frequency",
 | 
					    "edt_conf_smooth_updateFrequency_title": "Update frequency",
 | 
				
			||||||
    "edt_conf_v4l2_blueSignalThreshold_expl": "Darkens low blue values (recognized as black)",
 | 
					    "edt_conf_v4l2_blueSignalThreshold_expl": "Darkens low blue values (recognized as black)",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,6 +154,7 @@ $(document).ready(function () {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // Start test
 | 
					  // Start test
 | 
				
			||||||
  $('#btn_start_test').off().on('click', function () {
 | 
					  $('#btn_start_test').off().on('click', function () {
 | 
				
			||||||
 | 
					    $('#btn_start_test').prop('disabled', true);
 | 
				
			||||||
    triggerTestEffect();
 | 
					    triggerTestEffect();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -161,6 +162,7 @@ $(document).ready(function () {
 | 
				
			|||||||
  $('#btn_stop_test').off().on('click', function () {
 | 
					  $('#btn_stop_test').off().on('click', function () {
 | 
				
			||||||
    requestPriorityClear();
 | 
					    requestPriorityClear();
 | 
				
			||||||
    testrun = false;
 | 
					    testrun = false;
 | 
				
			||||||
 | 
					    $('#btn_start_test').prop('disabled', false);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Continuous test
 | 
					  // Continuous test
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,8 @@
 | 
				
			|||||||
#include <effectengine/EffectSchema.h>
 | 
					#include <effectengine/EffectSchema.h>
 | 
				
			||||||
#include <utils/Logger.h>
 | 
					#include <utils/Logger.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <hyperion/LinearColorSmoothing.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// pre-declaration
 | 
					// pre-declaration
 | 
				
			||||||
class Effect;
 | 
					class Effect;
 | 
				
			||||||
class EffectFileHandler;
 | 
					class EffectFileHandler;
 | 
				
			||||||
@@ -79,7 +81,7 @@ public slots:
 | 
				
			|||||||
				, int timeout = PriorityMuxer::ENDLESS
 | 
									, int timeout = PriorityMuxer::ENDLESS
 | 
				
			||||||
				, const QString &pythonScript = ""
 | 
									, const QString &pythonScript = ""
 | 
				
			||||||
				, const QString &origin = "System"
 | 
									, const QString &origin = "System"
 | 
				
			||||||
				, unsigned smoothCfg=0
 | 
									, unsigned smoothCfg=SmoothingConfigID::SYSTEM
 | 
				
			||||||
				, const QString &imageData = ""
 | 
									, const QString &imageData = ""
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -105,7 +107,7 @@ private:
 | 
				
			|||||||
				, int priority
 | 
									, int priority
 | 
				
			||||||
				, int timeout = PriorityMuxer::ENDLESS
 | 
									, int timeout = PriorityMuxer::ENDLESS
 | 
				
			||||||
				, const QString &origin="System"
 | 
									, const QString &origin="System"
 | 
				
			||||||
				, unsigned smoothCfg=0
 | 
									, unsigned smoothCfg=SmoothingConfigID::SYSTEM
 | 
				
			||||||
				, const QString &imageData = ""
 | 
									, const QString &imageData = ""
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
#pragma once
 | 
					#ifndef LINEARCOLORSMOOTHING_H
 | 
				
			||||||
 | 
					#define LINEARCOLORSMOOTHING_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// STL includes
 | 
					// STL includes
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
@@ -10,6 +11,7 @@
 | 
				
			|||||||
// hyperion includes
 | 
					// hyperion includes
 | 
				
			||||||
#include <leddevice/LedDevice.h>
 | 
					#include <leddevice/LedDevice.h>
 | 
				
			||||||
#include <utils/Components.h>
 | 
					#include <utils/Components.h>
 | 
				
			||||||
 | 
					#include <hyperion/PriorityMuxer.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// settings
 | 
					// settings
 | 
				
			||||||
#include <utils/settings.h>
 | 
					#include <utils/settings.h>
 | 
				
			||||||
@@ -21,13 +23,12 @@ class QTimer;
 | 
				
			|||||||
class Logger;
 | 
					class Logger;
 | 
				
			||||||
class Hyperion;
 | 
					class Hyperion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The type of smoothing to perform
 | 
					enum SmoothingConfigID
 | 
				
			||||||
enum SmoothingType {
 | 
					{
 | 
				
			||||||
	/// "Linear" smoothing algorithm
 | 
						SYSTEM = 0,
 | 
				
			||||||
	Linear,
 | 
						PAUSE = 1,
 | 
				
			||||||
 | 
						EFFECT_DYNAMIC = 2,
 | 
				
			||||||
	/// Decay based smoothing algorithm
 | 
						EFFECT_SPECIFIC = 3
 | 
				
			||||||
	Decay,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Linear Smoothing class
 | 
					/// Linear Smoothing class
 | 
				
			||||||
@@ -80,6 +81,7 @@ public:
 | 
				
			|||||||
	/// @param hyperion  The hyperion parent instance
 | 
						/// @param hyperion  The hyperion parent instance
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
	LinearColorSmoothing(const QJsonDocument &config, Hyperion *hyperion);
 | 
						LinearColorSmoothing(const QJsonDocument &config, Hyperion *hyperion);
 | 
				
			||||||
 | 
						~LinearColorSmoothing() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// LED values as input for the smoothing filter
 | 
						/// LED values as input for the smoothing filter
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
@@ -114,16 +116,16 @@ public:
 | 
				
			|||||||
	///
 | 
						///
 | 
				
			||||||
	/// @return The index of the configuration, which can be passed to selectConfig()
 | 
						/// @return The index of the configuration, which can be passed to selectConfig()
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
	unsigned updateConfig(unsigned cfgID, int settlingTime_ms, double ledUpdateFrequency_hz = 25.0, unsigned updateDelay = 0);
 | 
						unsigned updateConfig(int cfgID, int settlingTime_ms, double ledUpdateFrequency_hz = 25.0, unsigned updateDelay = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
	/// @brief select a smoothing configuration given by cfg index from addConfig()
 | 
						/// @brief select a smoothing configuration given by cfg index from addConfig()
 | 
				
			||||||
	/// @param   cfg     The index to use
 | 
						/// @param   cfgID   The index to use
 | 
				
			||||||
	/// @param   force   Overwrite in any case the current values (used for cfg 0 settings update)
 | 
						/// @param   force   Overwrite in any case the current values (used for cfg 0 settings update)
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
	/// @return  On success return else false (and falls back to cfg 0)
 | 
						/// @return  On success return else false (and falls back to cfg 0)
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
	bool selectConfig(unsigned cfg, bool force = false);
 | 
						bool selectConfig(int cfgID, bool force = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public slots:
 | 
					public slots:
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
@@ -160,12 +162,17 @@ private:
 | 
				
			|||||||
	///
 | 
						///
 | 
				
			||||||
	virtual int write(const std::vector<ColorRgb> &ledValues);
 | 
						virtual int write(const std::vector<ColorRgb> &ledValues);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QString getConfig(int cfgID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Logger instance
 | 
						/// Logger instance
 | 
				
			||||||
	Logger *_log;
 | 
						Logger *_log;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Hyperion instance
 | 
						/// Hyperion instance
 | 
				
			||||||
	Hyperion *_hyperion;
 | 
						Hyperion *_hyperion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// priority muxer instance
 | 
				
			||||||
 | 
						PriorityMuxer* _prioMuxer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// The interval at which to update the leds (msec)
 | 
						/// The interval at which to update the leds (msec)
 | 
				
			||||||
	int _updateInterval;
 | 
						int _updateInterval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -210,14 +217,12 @@ private:
 | 
				
			|||||||
		REMEMBERED_FRAME ( const REMEMBERED_FRAME & ) = default;
 | 
							REMEMBERED_FRAME ( const REMEMBERED_FRAME & ) = default;
 | 
				
			||||||
		REMEMBERED_FRAME & operator= ( const REMEMBERED_FRAME & ) = default;
 | 
							REMEMBERED_FRAME & operator= ( const REMEMBERED_FRAME & ) = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		REMEMBERED_FRAME(const int64_t time, const std::vector<ColorRgb> colors)
 | 
							REMEMBERED_FRAME(int64_t time, const std::vector<ColorRgb> colors)
 | 
				
			||||||
		: time(time)
 | 
							: time(time)
 | 
				
			||||||
		, colors(colors)
 | 
							, colors(colors)
 | 
				
			||||||
		{}
 | 
							{}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// The type of smoothing to perform
 | 
					 | 
				
			||||||
	SmoothingType _smoothingType;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// The queue of temporarily remembered frames
 | 
						/// The queue of temporarily remembered frames
 | 
				
			||||||
	std::deque<REMEMBERED_FRAME> _frameQueue;
 | 
						std::deque<REMEMBERED_FRAME> _frameQueue;
 | 
				
			||||||
@@ -246,41 +251,53 @@ private:
 | 
				
			|||||||
	/// Value of 1.0 / settlingTime; inverse of the window size used for weighting of frames.
 | 
						/// Value of 1.0 / settlingTime; inverse of the window size used for weighting of frames.
 | 
				
			||||||
	floatT _invWindow;
 | 
						floatT _invWindow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct SMOOTHING_CFG
 | 
						enum class SmoothingType { Linear = 0, Decay = 1 };
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		/// The type of smoothing to perform
 | 
					 | 
				
			||||||
		SmoothingType smoothingType;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						class SmoothingCfg
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
		/// Whether to pause output
 | 
							/// Whether to pause output
 | 
				
			||||||
		bool pause;
 | 
							bool _pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// The time of the smoothing window.
 | 
							/// The time of the smoothing window.
 | 
				
			||||||
		int64_t settlingTime;
 | 
							int64_t _settlingTime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// The interval time in milliseconds of the timer used for scheduling LED update operations. A value of 0 indicates sub-millisecond timing.
 | 
							/// The interval time in milliseconds of the timer used for scheduling LED update operations. A value of 0 indicates sub-millisecond timing.
 | 
				
			||||||
		int updateInterval;
 | 
							int _updateInterval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// The rate at which color frames should be written to LED device.
 | 
							/// The type of smoothing to perform
 | 
				
			||||||
		double outputRate;
 | 
							SmoothingType _type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// The rate at which color frames should be written to LED device.
 | 
				
			||||||
 | 
							double _outputRate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// The rate at which interpolation of LED frames should be performed.
 | 
							/// The rate at which interpolation of LED frames should be performed.
 | 
				
			||||||
		double interpolationRate;
 | 
							double _interpolationRate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// The number of frames the output is delayed
 | 
							/// The number of frames the output is delayed
 | 
				
			||||||
		unsigned outputDelay;
 | 
							unsigned _outputDelay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// Whether to apply temporal dithering to diffuse rounding errors when downsampling to 8-bit RGB colors. Improves color accuracy.
 | 
							/// Whether to apply temporal dithering to diffuse rounding errors when downsampling to 8-bit RGB colors. Improves color accuracy.
 | 
				
			||||||
		bool dithering;
 | 
							bool _dithering;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// The decay power > 0. A value of exactly 1 is linear decay, higher numbers indicate a faster decay rate.
 | 
							/// The decay power > 0. A value of exactly 1 is linear decay, higher numbers indicate a faster decay rate.
 | 
				
			||||||
		double decay;
 | 
							double _decay;
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	/// smooth configuration list
 | 
					 | 
				
			||||||
	QVector<SMOOTHING_CFG> _cfgList;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned _currentConfigId;
 | 
							SmoothingCfg();
 | 
				
			||||||
 | 
							SmoothingCfg(bool pause, int64_t settlingTime, int updateInterval, SmoothingType type = SmoothingType::Linear, double outputRate = 0, double interpolationRate = 0, unsigned outputDelay = 0, bool dithering = false, double decay = 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							static QString EnumToString(SmoothingType type);
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// smoothing configurations
 | 
				
			||||||
 | 
						QVector<SmoothingCfg> _cfgList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int _currentConfigId;
 | 
				
			||||||
	bool _enabled;
 | 
						bool _enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// The type of smoothing to perform
 | 
				
			||||||
 | 
						SmoothingType _smoothingType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Pushes the colors into the frame queue and cleans outdated frames from memory.
 | 
						/// Pushes the colors into the frame queue and cleans outdated frames from memory.
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
	/// @param ledColors The next colors to queue
 | 
						/// @param ledColors The next colors to queue
 | 
				
			||||||
@@ -292,7 +309,7 @@ private:
 | 
				
			|||||||
	/// (Re-)Initializes the color-component vectors with given number of values.
 | 
						/// (Re-)Initializes the color-component vectors with given number of values.
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
	/// @param ledCount The number of colors.
 | 
						/// @param ledCount The number of colors.
 | 
				
			||||||
	void intitializeComponentVectors(const size_t ledCount);
 | 
						void intitializeComponentVectors(size_t ledCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// The number of led component-values that must be held per color; i.e. size of the color vectors reds / greens / blues
 | 
						/// The number of led component-values that must be held per color; i.e. size of the color vectors reds / greens / blues
 | 
				
			||||||
	size_t _ledCount = 0;
 | 
						size_t _ledCount = 0;
 | 
				
			||||||
@@ -330,10 +347,10 @@ private:
 | 
				
			|||||||
	///
 | 
						///
 | 
				
			||||||
	/// When downsampling the average color values to the 8-bit RGB resolution of the LED device, rounding errors are minimized
 | 
						/// When downsampling the average color values to the 8-bit RGB resolution of the LED device, rounding errors are minimized
 | 
				
			||||||
	/// by temporal dithering algorithm (error diffusion of residual errors).
 | 
						/// by temporal dithering algorithm (error diffusion of residual errors).
 | 
				
			||||||
	void performDecay(const int64_t now);
 | 
						void performDecay(int64_t now);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Performs a linear smoothing effect
 | 
						/// Performs a linear smoothing effect
 | 
				
			||||||
	void performLinear(const int64_t now);
 | 
						void performLinear(int64_t now);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Aggregates the RGB components of the LED colors using the given weight and updates weighted accordingly
 | 
						/// Aggregates the RGB components of the LED colors using the given weight and updates weighted accordingly
 | 
				
			||||||
	///
 | 
						///
 | 
				
			||||||
@@ -343,7 +360,7 @@ private:
 | 
				
			|||||||
	static inline void aggregateComponents(const std::vector<ColorRgb>& colors, std::vector<uint64_t>& weighted, const floatT weight);
 | 
						static inline void aggregateComponents(const std::vector<ColorRgb>& colors, std::vector<uint64_t>& weighted, const floatT weight);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Gets the current time in microseconds from high precision system clock.
 | 
						/// Gets the current time in microseconds from high precision system clock.
 | 
				
			||||||
	inline int64_t micros() const;
 | 
						static inline int64_t micros() ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// The time, when the rendering statistics were logged previously
 | 
						/// The time, when the rendering statistics were logged previously
 | 
				
			||||||
	int64_t _renderedStatTime;
 | 
						int64_t _renderedStatTime;
 | 
				
			||||||
@@ -368,3 +385,5 @@ private:
 | 
				
			|||||||
	/// @returns The frame weight.
 | 
						/// @returns The frame weight.
 | 
				
			||||||
	std::function<floatT(int64_t, int64_t, int64_t)> _weightFrame;
 | 
						std::function<floatT(int64_t, int64_t, int64_t)> _weightFrame;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // LINEARCOLORSMOOTHING_H
 | 
				
			||||||
@@ -112,14 +112,17 @@ void EffectEngine::handleUpdatedEffectList()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	_availableEffects.clear();
 | 
						_availableEffects.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned id = 2;
 | 
						//Add smoothing config entry to support dynamic effects done in configurator
 | 
				
			||||||
 | 
						_hyperion->updateSmoothingConfig(SmoothingConfigID::EFFECT_DYNAMIC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned specificId = SmoothingConfigID::EFFECT_SPECIFIC;
 | 
				
			||||||
	for (auto def : _effectFileHandler->getEffects())
 | 
						for (auto def : _effectFileHandler->getEffects())
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// add smoothing configs to Hyperion
 | 
							// add smoothing configurations to Hyperion
 | 
				
			||||||
		if (def.args["smoothing-custom-settings"].toBool())
 | 
							if (def.args["smoothing-custom-settings"].toBool())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			def.smoothCfg = _hyperion->updateSmoothingConfig(
 | 
								def.smoothCfg = _hyperion->updateSmoothingConfig(
 | 
				
			||||||
				id,
 | 
									++specificId,
 | 
				
			||||||
				def.args["smoothing-time_ms"].toInt(),
 | 
									def.args["smoothing-time_ms"].toInt(),
 | 
				
			||||||
				def.args["smoothing-updateFrequency"].toDouble(),
 | 
									def.args["smoothing-updateFrequency"].toDouble(),
 | 
				
			||||||
				0 );
 | 
									0 );
 | 
				
			||||||
@@ -127,7 +130,7 @@ void EffectEngine::handleUpdatedEffectList()
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			def.smoothCfg = _hyperion->updateSmoothingConfig(id);
 | 
								def.smoothCfg = SmoothingConfigID::SYSTEM;
 | 
				
			||||||
			//Debug( _log, "Default Settings: Update effect %s, script %s, file %s, smoothCfg [%u]", QSTRING_CSTR(def.name), QSTRING_CSTR(def.script), QSTRING_CSTR(def.file), def.smoothCfg);
 | 
								//Debug( _log, "Default Settings: Update effect %s, script %s, file %s, smoothCfg [%u]", QSTRING_CSTR(def.name), QSTRING_CSTR(def.script), QSTRING_CSTR(def.file), def.smoothCfg);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		_availableEffects.push_back(def);
 | 
							_availableEffects.push_back(def);
 | 
				
			||||||
@@ -137,11 +140,30 @@ void EffectEngine::handleUpdatedEffectList()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int EffectEngine::runEffect(const QString &effectName, int priority, int timeout, const QString &origin)
 | 
					int EffectEngine::runEffect(const QString &effectName, int priority, int timeout, const QString &origin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return runEffect(effectName, QJsonObject(), priority, timeout, "", origin);
 | 
						unsigned smoothCfg = SmoothingConfigID::SYSTEM;
 | 
				
			||||||
 | 
						for (const auto &def : _availableEffects)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (def.name == effectName)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								smoothCfg = def.smoothCfg;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return runEffect(effectName, QJsonObject(), priority, timeout, "", origin, smoothCfg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int EffectEngine::runEffect(const QString &effectName, const QJsonObject &args, int priority, int timeout, const QString &pythonScript, const QString &origin, unsigned smoothCfg, const QString &imageData)
 | 
					int EffectEngine::runEffect(const QString &effectName, const QJsonObject &args, int priority, int timeout, const QString &pythonScript, const QString &origin, unsigned smoothCfg, const QString &imageData)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						//In case smoothing information is provided dynamically use temp smoothing config item (2)
 | 
				
			||||||
 | 
						if (smoothCfg == SmoothingConfigID::SYSTEM && args["smoothing-custom-settings"].toBool())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							smoothCfg = _hyperion->updateSmoothingConfig(
 | 
				
			||||||
 | 
								SmoothingConfigID::EFFECT_DYNAMIC,
 | 
				
			||||||
 | 
								args["smoothing-time_ms"].toInt(),
 | 
				
			||||||
 | 
								args["smoothing-updateFrequency"].toDouble(),
 | 
				
			||||||
 | 
								0 );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pythonScript.isEmpty())
 | 
						if (pythonScript.isEmpty())
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		const EffectDefinition *effectDefinition = nullptr;
 | 
							const EffectDefinition *effectDefinition = nullptr;
 | 
				
			||||||
@@ -181,7 +203,7 @@ int EffectEngine::runEffectScript(const QString &script, const QString &name, co
 | 
				
			|||||||
	_activeEffects.push_back(effect);
 | 
						_activeEffects.push_back(effect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// start the effect
 | 
						// start the effect
 | 
				
			||||||
	Debug(_log, "Start the effect: name [%s], smoothCfg [%u]", QSTRING_CSTR(name), smoothCfg);
 | 
						Debug(_log, "Start the effect: name [%s]", QSTRING_CSTR(name));
 | 
				
			||||||
	_hyperion->registerInput(priority, hyperion::COMP_EFFECT, origin, name ,smoothCfg);
 | 
						_hyperion->registerInput(priority, hyperion::COMP_EFFECT, origin, name ,smoothCfg);
 | 
				
			||||||
	effect->start();
 | 
						effect->start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,7 @@
 | 
				
			|||||||
#include <leddevice/LedDeviceWrapper.h>
 | 
					#include <leddevice/LedDeviceWrapper.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <hyperion/MultiColorAdjustment.h>
 | 
					#include <hyperion/MultiColorAdjustment.h>
 | 
				
			||||||
#include "LinearColorSmoothing.h"
 | 
					#include <hyperion/LinearColorSmoothing.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(ENABLE_EFFECTENGINE)
 | 
					#if defined(ENABLE_EFFECTENGINE)
 | 
				
			||||||
// effect engine includes
 | 
					// effect engine includes
 | 
				
			||||||
@@ -303,10 +303,6 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// TODO: Check, if framegrabber frequency is lower than latchtime..., if yes, stop
 | 
							// TODO: Check, if framegrabber frequency is lower than latchtime..., if yes, stop
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if(type == settings::SMOOTHING)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		_deviceSmooth->handleSettingsUpdate( type, config);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// update once to push single color sets / adjustments/ ledlayout resizes and update ledBuffer color
 | 
						// update once to push single color sets / adjustments/ ledlayout resizes and update ledBuffer color
 | 
				
			||||||
	update();
 | 
						update();
 | 
				
			||||||
@@ -707,8 +703,6 @@ void Hyperion::update()
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			_deviceSmooth->selectConfig(priorityInfo.smooth_cfg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// feed smoothing in pause mode to maintain a smooth transition back to smooth mode
 | 
								// feed smoothing in pause mode to maintain a smooth transition back to smooth mode
 | 
				
			||||||
			if (_deviceSmooth->enabled() || _deviceSmooth->pause())
 | 
								if (_deviceSmooth->enabled() || _deviceSmooth->pause())
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,16 +2,13 @@
 | 
				
			|||||||
#include <QDateTime>
 | 
					#include <QDateTime>
 | 
				
			||||||
#include <QTimer>
 | 
					#include <QTimer>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "LinearColorSmoothing.h"
 | 
					#include <hyperion/LinearColorSmoothing.h>
 | 
				
			||||||
#include <hyperion/Hyperion.h>
 | 
					#include <hyperion/Hyperion.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cmath>
 | 
					#include <cmath>
 | 
				
			||||||
#include <chrono>
 | 
					#include <chrono>
 | 
				
			||||||
#include <thread>
 | 
					#include <thread>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The number of microseconds per millisecond = 1000.
 | 
					 | 
				
			||||||
const int64_t MS_PER_MICRO = 1000;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(COMPILER_GCC)
 | 
					#if defined(COMPILER_GCC)
 | 
				
			||||||
#define ALWAYS_INLINE inline __attribute__((__always_inline__))
 | 
					#define ALWAYS_INLINE inline __attribute__((__always_inline__))
 | 
				
			||||||
#elif defined(COMPILER_MSVC)
 | 
					#elif defined(COMPILER_MSVC)
 | 
				
			||||||
@@ -25,6 +22,14 @@ ALWAYS_INLINE long clampRounded(const floatT x) {
 | 
				
			|||||||
	return std::min(255L, std::max(0L, std::lroundf(x)));
 | 
						return std::min(255L, std::max(0L, std::lroundf(x)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Constants
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const bool verbose = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// The number of microseconds per millisecond = 1000.
 | 
				
			||||||
 | 
					const int64_t MS_PER_MICRO = 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The number of bits that are used for shifting the fixed point values
 | 
					/// The number of bits that are used for shifting the fixed point values
 | 
				
			||||||
const int FPShift = (sizeof(uint64_t)*8 - (12 + 9));
 | 
					const int FPShift = (sizeof(uint64_t)*8 - (12 + 9));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,97 +40,113 @@ const int SmallShiftBis = sizeof(uint8_t)*8;
 | 
				
			|||||||
const int FPShiftSmall = (sizeof(uint64_t)*8 - (12 + 9 + SmallShiftBis));
 | 
					const int FPShiftSmall = (sizeof(uint64_t)*8 - (12 + 9 + SmallShiftBis));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char* SETTINGS_KEY_SMOOTHING_TYPE = "type";
 | 
					const char* SETTINGS_KEY_SMOOTHING_TYPE = "type";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char* SETTINGS_KEY_SETTLING_TIME = "time_ms";
 | 
				
			||||||
 | 
					const char* SETTINGS_KEY_UPDATE_FREQUENCY = "updateFrequency";
 | 
				
			||||||
 | 
					const char* SETTINGS_KEY_OUTPUT_DELAY = "updateDelay";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char* SETTINGS_KEY_DECAY = "decay";
 | 
				
			||||||
const char* SETTINGS_KEY_INTERPOLATION_RATE = "interpolationRate";
 | 
					const char* SETTINGS_KEY_INTERPOLATION_RATE = "interpolationRate";
 | 
				
			||||||
const char* SETTINGS_KEY_OUTPUT_RATE = "outputRate";
 | 
					const char* SETTINGS_KEY_OUTPUT_RATE = "outputRate";
 | 
				
			||||||
const char* SETTINGS_KEY_DITHERING = "dithering";
 | 
					const char* SETTINGS_KEY_DITHERING = "dithering";
 | 
				
			||||||
const char* SETTINGS_KEY_DECAY = "decay";
 | 
					
 | 
				
			||||||
 | 
					const int64_t DEFAULT_SETTLINGTIME = 200;	// in ms
 | 
				
			||||||
 | 
					const int DEFAULT_UPDATEFREQUENCY = 25;		// in Hz
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr std::chrono::milliseconds DEFAULT_UPDATEINTERVALL{MS_PER_MICRO/ DEFAULT_UPDATEFREQUENCY};
 | 
				
			||||||
 | 
					const unsigned DEFAULT_OUTPUTDEPLAY = 0;	// in frames
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace hyperion;
 | 
					using namespace hyperion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const int64_t DEFAUL_SETTLINGTIME = 200;													// settlingtime in ms
 | 
					 | 
				
			||||||
const int DEFAUL_UPDATEFREQUENCY = 25;													// updatefrequncy in hz
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
constexpr std::chrono::milliseconds DEFAUL_UPDATEINTERVALL{1000/ DEFAUL_UPDATEFREQUENCY};
 | 
					 | 
				
			||||||
const unsigned DEFAUL_OUTPUTDEPLAY = 0;														// outputdelay in ms
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument &config, Hyperion *hyperion)
 | 
					LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument &config, Hyperion *hyperion)
 | 
				
			||||||
	: QObject(hyperion)
 | 
						: QObject(hyperion)
 | 
				
			||||||
	  , _log(nullptr)
 | 
						  , _log(nullptr)
 | 
				
			||||||
	  , _hyperion(hyperion)
 | 
						  , _hyperion(hyperion)
 | 
				
			||||||
	  , _updateInterval(DEFAUL_UPDATEINTERVALL.count())
 | 
						  , _prioMuxer(_hyperion->getMuxerInstance())
 | 
				
			||||||
	  , _settlingTime(DEFAUL_SETTLINGTIME)
 | 
						  , _updateInterval(DEFAULT_UPDATEINTERVALL.count())
 | 
				
			||||||
	  , _timer(new QTimer(this))
 | 
						  , _settlingTime(DEFAULT_SETTLINGTIME)
 | 
				
			||||||
	  , _outputDelay(DEFAUL_OUTPUTDEPLAY)
 | 
						  , _timer(nullptr)
 | 
				
			||||||
	  , _smoothingType(SmoothingType::Linear)
 | 
						  , _outputDelay(DEFAULT_OUTPUTDEPLAY)
 | 
				
			||||||
	  , _pause(false)
 | 
						  , _pause(false)
 | 
				
			||||||
	  , _currentConfigId(0)
 | 
						  , _currentConfigId(SmoothingConfigID::SYSTEM)
 | 
				
			||||||
	  , _enabled(false)
 | 
						  , _enabled(false)
 | 
				
			||||||
 | 
						  , _smoothingType(SmoothingType::Linear)
 | 
				
			||||||
	  , tempValues(std::vector<uint64_t>(0, 0L))
 | 
						  , tempValues(std::vector<uint64_t>(0, 0L))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QString subComponent = hyperion->property("instance").toString();
 | 
						QString subComponent = hyperion->property("instance").toString();
 | 
				
			||||||
	_log= Logger::getInstance("SMOOTHING", subComponent);
 | 
						_log= Logger::getInstance("SMOOTHING", subComponent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// init cfg 0 (default)
 | 
						// timer
 | 
				
			||||||
	addConfig(DEFAUL_SETTLINGTIME, DEFAUL_UPDATEFREQUENCY, DEFAUL_OUTPUTDEPLAY);
 | 
						_timer = new QTimer(this);
 | 
				
			||||||
 | 
						_timer->setTimerType(Qt::PreciseTimer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// init cfg (default)
 | 
				
			||||||
 | 
						updateConfig(SmoothingConfigID::SYSTEM, DEFAULT_SETTLINGTIME, DEFAULT_UPDATEFREQUENCY, DEFAULT_OUTPUTDEPLAY);
 | 
				
			||||||
	handleSettingsUpdate(settings::SMOOTHING, config);
 | 
						handleSettingsUpdate(settings::SMOOTHING, config);
 | 
				
			||||||
	selectConfig(0, true);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// add pause on cfg 1
 | 
						// add pause on cfg 1
 | 
				
			||||||
	SMOOTHING_CFG cfg = {SmoothingType::Linear, false, 0, 0, 0, 0, 0, false, 1};
 | 
						SmoothingCfg cfg {true, 0, 0};
 | 
				
			||||||
	_cfgList.append(cfg);
 | 
						_cfgList.append(cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// listen for comp changes
 | 
						// listen for comp changes
 | 
				
			||||||
	connect(_hyperion, &Hyperion::compStateChangeRequest, this, &LinearColorSmoothing::componentStateChange);
 | 
						connect(_hyperion, &Hyperion::compStateChangeRequest, this, &LinearColorSmoothing::componentStateChange);
 | 
				
			||||||
	// timer
 | 
					 | 
				
			||||||
	connect(_timer, &QTimer::timeout, this, &LinearColorSmoothing::updateLeds);
 | 
						connect(_timer, &QTimer::timeout, this, &LinearColorSmoothing::updateLeds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//Debug(_log, "LinearColorSmoothing sizeof floatT == %d", (sizeof(floatT)));
 | 
						connect(_prioMuxer, &PriorityMuxer::prioritiesChanged, this, [=] (int priority){
 | 
				
			||||||
 | 
							const PriorityMuxer::InputInfo priorityInfo = _prioMuxer->getInputInfo(priority);
 | 
				
			||||||
 | 
							int smooth_cfg = priorityInfo.smooth_cfg;
 | 
				
			||||||
 | 
							if (smooth_cfg != _currentConfigId || smooth_cfg == SmoothingConfigID::EFFECT_DYNAMIC)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								this->selectConfig(smooth_cfg, false);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LinearColorSmoothing::~LinearColorSmoothing()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						delete _timer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LinearColorSmoothing::handleSettingsUpdate(settings::type type, const QJsonDocument &config)
 | 
					void LinearColorSmoothing::handleSettingsUpdate(settings::type type, const QJsonDocument &config)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (type == settings::SMOOTHING)
 | 
						if (type == settings::type::SMOOTHING)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		//	std::cout << "LinearColorSmoothing::handleSettingsUpdate" << std::endl;
 | 
					 | 
				
			||||||
		//	std::cout << config.toJson().toStdString() << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		QJsonObject obj = config.object();
 | 
							QJsonObject obj = config.object();
 | 
				
			||||||
		if (enabled() != obj["enable"].toBool(true))
 | 
							if (enabled() != obj["enable"].toBool(true))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			setEnable(obj["enable"].toBool(true));
 | 
								setEnable(obj["enable"].toBool(true));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		SMOOTHING_CFG cfg = {SmoothingType::Linear,true, 0, 0, 0, 0, 0, false, 1};
 | 
							SmoothingCfg cfg(false,
 | 
				
			||||||
 | 
											  static_cast<int64_t>(obj[SETTINGS_KEY_SETTLING_TIME].toInt(DEFAULT_SETTLINGTIME)),
 | 
				
			||||||
 | 
											  static_cast<int64_t>(MS_PER_MICRO / obj[SETTINGS_KEY_UPDATE_FREQUENCY].toDouble(DEFAULT_UPDATEFREQUENCY))
 | 
				
			||||||
 | 
											  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const QString typeString = obj[SETTINGS_KEY_SMOOTHING_TYPE].toString();
 | 
							const QString typeString = obj[SETTINGS_KEY_SMOOTHING_TYPE].toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if(typeString == "linear") {
 | 
							if(typeString == SETTINGS_KEY_DECAY) {
 | 
				
			||||||
			cfg.smoothingType = SmoothingType::Linear;
 | 
								cfg._type = SmoothingType::Decay;
 | 
				
			||||||
		} else if(typeString == "decay") {
 | 
							}
 | 
				
			||||||
			cfg.smoothingType = SmoothingType::Decay;
 | 
							else {
 | 
				
			||||||
 | 
								cfg._type = SmoothingType::Linear;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cfg.pause = false;
 | 
							cfg._pause = false;
 | 
				
			||||||
		cfg.settlingTime = static_cast<int64_t>(obj["time_ms"].toInt(DEFAUL_SETTLINGTIME));
 | 
							cfg._outputDelay = static_cast<unsigned>(obj[SETTINGS_KEY_OUTPUT_DELAY].toInt(DEFAULT_OUTPUTDEPLAY));
 | 
				
			||||||
		cfg.updateInterval = static_cast<int>(1000.0 / obj["updateFrequency"].toDouble(DEFAUL_UPDATEFREQUENCY));
 | 
					 | 
				
			||||||
		cfg.outputRate = obj[SETTINGS_KEY_OUTPUT_RATE].toDouble(DEFAUL_UPDATEFREQUENCY);
 | 
					 | 
				
			||||||
		cfg.interpolationRate = obj[SETTINGS_KEY_INTERPOLATION_RATE].toDouble(DEFAUL_UPDATEFREQUENCY);
 | 
					 | 
				
			||||||
		cfg.outputDelay = static_cast<unsigned>(obj["updateDelay"].toInt(DEFAUL_OUTPUTDEPLAY));
 | 
					 | 
				
			||||||
		cfg.dithering = obj[SETTINGS_KEY_DITHERING].toBool(false);
 | 
					 | 
				
			||||||
		cfg.decay = obj[SETTINGS_KEY_DECAY].toDouble(1.0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//Debug( _log, "smoothing cfg_id %d: pause: %d bool, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _currentConfigId, cfg.pause, cfg.settlingTime, cfg.updateInterval, unsigned(1000.0/cfg.updateInterval), cfg.outputDelay );
 | 
							cfg._outputRate = obj[SETTINGS_KEY_OUTPUT_RATE].toDouble(DEFAULT_UPDATEFREQUENCY);
 | 
				
			||||||
		_cfgList[0] = cfg;
 | 
							cfg._interpolationRate = obj[SETTINGS_KEY_INTERPOLATION_RATE].toDouble(DEFAULT_UPDATEFREQUENCY);
 | 
				
			||||||
 | 
							cfg._dithering = obj[SETTINGS_KEY_DITHERING].toBool(false);
 | 
				
			||||||
 | 
							cfg._decay = obj[SETTINGS_KEY_DECAY].toDouble(1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							_cfgList[SmoothingConfigID::SYSTEM] = cfg;
 | 
				
			||||||
 | 
							DebugIf(_enabled,_log,"%s", QSTRING_CSTR(getConfig(SmoothingConfigID::SYSTEM)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// if current id is 0, we need to apply the settings (forced)
 | 
							// if current id is 0, we need to apply the settings (forced)
 | 
				
			||||||
		if (_currentConfigId == 0)
 | 
							if (_currentConfigId == SmoothingConfigID::SYSTEM)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			//Debug( _log, "_currentConfigId == 0");
 | 
								selectConfig(SmoothingConfigID::SYSTEM, true);
 | 
				
			||||||
			selectConfig(0, true);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			//Debug( _log, "_currentConfigId != 0");
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -145,8 +166,7 @@ int LinearColorSmoothing::write(const std::vector<ColorRgb> &ledValues)
 | 
				
			|||||||
		_previousValues = ledValues;
 | 
							_previousValues = ledValues;
 | 
				
			||||||
		_previousInterpolationTime = micros();
 | 
							_previousInterpolationTime = micros();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//Debug( _log, "Start Smoothing timer: settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames", _settlingTime, _updateInterval, unsigned(1000.0/_updateInterval), _outputDelay );
 | 
							_timer->start(_updateInterval);
 | 
				
			||||||
		QMetaObject::invokeMethod(_timer, "start", Qt::QueuedConnection, Q_ARG(int, _updateInterval));
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
@@ -202,7 +222,7 @@ void LinearColorSmoothing::writeFrame()
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ALWAYS_INLINE int64_t LinearColorSmoothing::micros() const
 | 
					ALWAYS_INLINE int64_t LinearColorSmoothing::micros()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const auto now = std::chrono::high_resolution_clock::now();
 | 
						const auto now = std::chrono::high_resolution_clock::now();
 | 
				
			||||||
	return (std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch())).count();
 | 
						return (std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch())).count();
 | 
				
			||||||
@@ -215,7 +235,7 @@ void LinearColorSmoothing::assembleAndDitherFrame()
 | 
				
			|||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The number of leds present in each frame
 | 
						// The number of LEDs present in each frame
 | 
				
			||||||
	const size_t N = _targetValues.size();
 | 
						const size_t N = _targetValues.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (size_t i = 0; i < N; ++i)
 | 
						for (size_t i = 0; i < N; ++i)
 | 
				
			||||||
@@ -250,7 +270,7 @@ void LinearColorSmoothing::assembleFrame()
 | 
				
			|||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The number of leds present in each frame
 | 
						// The number of LEDs present in each frame
 | 
				
			||||||
	const size_t N = _targetValues.size();
 | 
						const size_t N = _targetValues.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (size_t i = 0; i < N; ++i)
 | 
						for (size_t i = 0; i < N; ++i)
 | 
				
			||||||
@@ -438,7 +458,6 @@ void LinearColorSmoothing::updateLeds()
 | 
				
			|||||||
	const int64_t now = micros();
 | 
						const int64_t now = micros();
 | 
				
			||||||
	const int64_t deltaTime = _targetTime - now;
 | 
						const int64_t deltaTime = _targetTime - now;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//Debug(_log, "elapsed Time [%d], _targetTime [%d] - now [%d], deltaTime [%d]", now -_previousWriteTime, _targetTime, now, deltaTime);
 | 
					 | 
				
			||||||
	if (deltaTime < 0)
 | 
						if (deltaTime < 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		writeDirect();
 | 
							writeDirect();
 | 
				
			||||||
@@ -447,12 +466,11 @@ void LinearColorSmoothing::updateLeds()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	switch (_smoothingType)
 | 
						switch (_smoothingType)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	case Decay:
 | 
						case SmoothingType::Decay:
 | 
				
			||||||
		performDecay(now);
 | 
							performDecay(now);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case Linear:
 | 
						case SmoothingType::Linear:
 | 
				
			||||||
		// Linear interpolation is default
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		performLinear(now);
 | 
							performLinear(now);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
@@ -461,8 +479,6 @@ void LinearColorSmoothing::updateLeds()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void LinearColorSmoothing::rememberFrame(const std::vector<ColorRgb> &ledColors)
 | 
					void LinearColorSmoothing::rememberFrame(const std::vector<ColorRgb> &ledColors)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	//Debug(_log, "rememberFrame -  before _frameQueue.size() [%d]", _frameQueue.size());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const int64_t now = micros();
 | 
						const int64_t now = micros();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Maintain the queue by removing outdated frames
 | 
						// Maintain the queue by removing outdated frames
 | 
				
			||||||
@@ -478,15 +494,12 @@ void LinearColorSmoothing::rememberFrame(const std::vector<ColorRgb> &ledColors)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (p > 0)
 | 
						if (p > 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		//Debug(_log, "rememberFrame -  erasing %d frames", p);
 | 
					 | 
				
			||||||
		_frameQueue.erase(_frameQueue.begin(), _frameQueue.begin() + p);
 | 
							_frameQueue.erase(_frameQueue.begin(), _frameQueue.begin() + p);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Append the latest frame at back of the queue
 | 
						// Append the latest frame at back of the queue
 | 
				
			||||||
	const REMEMBERED_FRAME frame = REMEMBERED_FRAME(now, ledColors);
 | 
						const REMEMBERED_FRAME frame = REMEMBERED_FRAME(now, ledColors);
 | 
				
			||||||
	_frameQueue.push_back(frame);
 | 
						_frameQueue.push_back(frame);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	//Debug(_log, "rememberFrame -  after _frameQueue.size() [%d]", _frameQueue.size());
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -532,7 +545,8 @@ void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> &ledColors)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void LinearColorSmoothing::clearQueuedColors()
 | 
					void LinearColorSmoothing::clearQueuedColors()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection);
 | 
						_timer->stop();
 | 
				
			||||||
 | 
						//QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection);
 | 
				
			||||||
	_previousValues.clear();
 | 
						_previousValues.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_targetValues.clear();
 | 
						_targetValues.clear();
 | 
				
			||||||
@@ -566,71 +580,65 @@ void LinearColorSmoothing::setPause(bool pause)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
unsigned LinearColorSmoothing::addConfig(int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay)
 | 
					unsigned LinearColorSmoothing::addConfig(int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	SMOOTHING_CFG cfg = {
 | 
						SmoothingCfg cfg {
 | 
				
			||||||
		SmoothingType::Linear,
 | 
					 | 
				
			||||||
		false,
 | 
							false,
 | 
				
			||||||
		settlingTime_ms,
 | 
							settlingTime_ms,
 | 
				
			||||||
		static_cast<int>(1000.0 / ledUpdateFrequency_hz),
 | 
							static_cast<int>(MS_PER_MICRO / ledUpdateFrequency_hz),
 | 
				
			||||||
 | 
							SmoothingType::Linear,
 | 
				
			||||||
		ledUpdateFrequency_hz,
 | 
							ledUpdateFrequency_hz,
 | 
				
			||||||
		ledUpdateFrequency_hz,
 | 
							ledUpdateFrequency_hz,
 | 
				
			||||||
		updateDelay,
 | 
							updateDelay
 | 
				
			||||||
		false,
 | 
					 | 
				
			||||||
		1
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	_cfgList.append(cfg);
 | 
						_cfgList.append(cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//Debug( _log, "smoothing cfg %d: pause: %d bool, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _cfgList.count()-1, cfg.pause, cfg.settlingTime, cfg.updateInterval, unsigned(1000.0/cfg.updateInterval), cfg.outputDelay );
 | 
						DebugIf(verbose && _enabled, _log,"%s", QSTRING_CSTR(getConfig(_cfgList.count()-1)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return _cfgList.count() - 1;
 | 
						return _cfgList.count() - 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned LinearColorSmoothing::updateConfig(unsigned cfgID, int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay)
 | 
					unsigned LinearColorSmoothing::updateConfig(int cfgID, int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned updatedCfgID = cfgID;
 | 
						int updatedCfgID = cfgID;
 | 
				
			||||||
	if (cfgID < static_cast<unsigned>(_cfgList.count()))
 | 
						if (cfgID < _cfgList.count())
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		SMOOTHING_CFG cfg = {
 | 
							SmoothingCfg cfg {
 | 
				
			||||||
			SmoothingType::Linear,
 | 
					 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
			settlingTime_ms,
 | 
								settlingTime_ms,
 | 
				
			||||||
			static_cast<int>(1000.0 / ledUpdateFrequency_hz),
 | 
								static_cast<int>(MS_PER_MICRO / ledUpdateFrequency_hz),
 | 
				
			||||||
 | 
								SmoothingType::Linear,
 | 
				
			||||||
			ledUpdateFrequency_hz,
 | 
								ledUpdateFrequency_hz,
 | 
				
			||||||
			ledUpdateFrequency_hz,
 | 
								ledUpdateFrequency_hz,
 | 
				
			||||||
			updateDelay,
 | 
								updateDelay
 | 
				
			||||||
			false,
 | 
							};
 | 
				
			||||||
			1};
 | 
					 | 
				
			||||||
		_cfgList[updatedCfgID] = cfg;
 | 
							_cfgList[updatedCfgID] = cfg;
 | 
				
			||||||
 | 
							DebugIf(verbose && _enabled, _log,"%s", QSTRING_CSTR(getConfig(updatedCfgID)));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		updatedCfgID = addConfig(settlingTime_ms, ledUpdateFrequency_hz, updateDelay);
 | 
							updatedCfgID = addConfig(settlingTime_ms, ledUpdateFrequency_hz, updateDelay);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//	Debug( _log, "smoothing updatedCfgID %u: settlingTime: %d ms, "
 | 
					 | 
				
			||||||
	//				 "interval: %d ms (%u Hz), updateDelay: %u frames",  cfgID, _settlingTime, int64_t(1000.0/ledUpdateFrequency_hz), unsigned(ledUpdateFrequency_hz), updateDelay );
 | 
					 | 
				
			||||||
	return updatedCfgID;
 | 
						return updatedCfgID;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool LinearColorSmoothing::selectConfig(unsigned cfg, bool force)
 | 
					bool LinearColorSmoothing::selectConfig(int cfgID, bool force)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (_currentConfigId == cfg && !force)
 | 
						if (_currentConfigId == cfgID && !force)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		//Debug( _log, "selectConfig SAME as before, not FORCED - _currentConfigId [%u], force [%d]", cfg, force);
 | 
					 | 
				
			||||||
		//Debug( _log, "current smoothing cfg: %d, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _currentConfigId, _settlingTime, _updateInterval, unsigned(1000.0/_updateInterval), _outputDelay );
 | 
					 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//Debug( _log, "selectConfig FORCED - _currentConfigId [%u], force [%d]", cfg, force);
 | 
						if (cfgID < _cfgList.count() )
 | 
				
			||||||
	if (cfg < static_cast<uint>(_cfgList.count()) )
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		_smoothingType = _cfgList[cfg].smoothingType;
 | 
							_smoothingType = _cfgList[cfgID]._type;
 | 
				
			||||||
		_settlingTime = _cfgList[cfg].settlingTime;
 | 
							_settlingTime = _cfgList[cfgID]._settlingTime;
 | 
				
			||||||
		_outputDelay = _cfgList[cfg].outputDelay;
 | 
							_outputDelay = _cfgList[cfgID]._outputDelay;
 | 
				
			||||||
		_pause = _cfgList[cfg].pause;
 | 
							_pause = _cfgList[cfgID]._pause;
 | 
				
			||||||
		_outputRate = _cfgList[cfg].outputRate;
 | 
							_outputRate = _cfgList[cfgID]._outputRate;
 | 
				
			||||||
		_outputIntervalMicros = int64_t(1000000.0 / _outputRate); // 1s = 1e6 µs
 | 
							_outputIntervalMicros = int64_t(1000000.0 / _outputRate); // 1s = 1e6 µs
 | 
				
			||||||
		_interpolationRate = _cfgList[cfg].interpolationRate;
 | 
							_interpolationRate = _cfgList[cfgID]._interpolationRate;
 | 
				
			||||||
		_interpolationIntervalMicros = int64_t(1000000.0 / _interpolationRate);
 | 
							_interpolationIntervalMicros = int64_t(1000000.0 / _interpolationRate);
 | 
				
			||||||
		_dithering = _cfgList[cfg].dithering;
 | 
							_dithering = _cfgList[cfgID]._dithering;
 | 
				
			||||||
		_decay = _cfgList[cfg].decay;
 | 
							_decay = _cfgList[cfgID]._decay;
 | 
				
			||||||
		_invWindow = 1.0F / (MS_PER_MICRO * _settlingTime);
 | 
							_invWindow = 1.0F / (MS_PER_MICRO * _settlingTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Set _weightFrame based on the given decay
 | 
							// Set _weightFrame based on the given decay
 | 
				
			||||||
@@ -661,33 +669,95 @@ bool LinearColorSmoothing::selectConfig(unsigned cfg, bool force)
 | 
				
			|||||||
		_interpolationCounter = 0;
 | 
							_interpolationCounter = 0;
 | 
				
			||||||
		_interpolationStatCounter = 0;
 | 
							_interpolationStatCounter = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (_cfgList[cfg].updateInterval != _updateInterval)
 | 
							if (_cfgList[cfgID]._updateInterval != _updateInterval)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection);
 | 
								_timer->stop();
 | 
				
			||||||
			_updateInterval = _cfgList[cfg].updateInterval;
 | 
								_updateInterval = _cfgList[cfgID]._updateInterval;
 | 
				
			||||||
			if (this->enabled())
 | 
								if (this->enabled())
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				//Debug( _log, "_cfgList[cfg].updateInterval != _updateInterval - Restart timer - _updateInterval [%d]", _updateInterval);
 | 
									_timer->start(_updateInterval);
 | 
				
			||||||
				QMetaObject::invokeMethod(_timer, "start", Qt::QueuedConnection, Q_ARG(int, _updateInterval));
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				//Debug( _log, "Smoothing disabled, do NOT restart timer");
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		_currentConfigId = cfg;
 | 
							_currentConfigId = cfgID;
 | 
				
			||||||
		// Debug( _log, "current smoothing cfg: %d, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _currentConfigId, _settlingTime, _updateInterval, unsigned(1000.0/_updateInterval), _outputDelay );
 | 
							DebugIf(_enabled, _log,"%s", QSTRING_CSTR(getConfig(_currentConfigId)));
 | 
				
			||||||
		//	DebugIf( enabled() && !_pause, _log, "set smoothing cfg: %u settlingTime: %d ms, interval: %d ms,  updateDelay: %u frames",  _currentConfigId, _settlingTime, _updateInterval,  _outputDelay );
 | 
					 | 
				
			||||||
		// DebugIf( _pause, _log, "set smoothing cfg: %d, pause",  _currentConfigId );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		const float thalf = (1.0-std::pow(1.0/2, 1.0/_decay))*_settlingTime;
 | 
					 | 
				
			||||||
		Debug( _log, "cfg [%d]:  Type: %s - Time: %d ms, outputRate %f Hz, interpolationRate: %f Hz, timer: %d ms, Dithering: %d, Decay: %f -> HalfTime: %f ms", cfg, _smoothingType == SmoothingType::Decay ? "decay" : "linear", _settlingTime, _outputRate, _interpolationRate, _updateInterval, _dithering ? 1 : 0, _decay, thalf);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// reset to default
 | 
						// reset to default
 | 
				
			||||||
	_currentConfigId = 0;
 | 
						_currentConfigId = SmoothingConfigID::SYSTEM;
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString LinearColorSmoothing::getConfig(int cfgID)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						QString configText;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cfgID < _cfgList.count())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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 (", outputRate %1Hz, interpolationRate: %2Hz, dithering: %3, decay: %4 -> halftime: %5ms")
 | 
				
			||||||
 | 
												  .arg(cfg._outputRate,0,'f',2)
 | 
				
			||||||
 | 
												  .arg(cfg._interpolationRate,0,'f',2)
 | 
				
			||||||
 | 
												  .arg((cfg._dithering) ? "true" : "false")
 | 
				
			||||||
 | 
												  .arg(cfg._decay,0,'f',2)
 | 
				
			||||||
 | 
												  .arg(thalf,0,'f',2);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return configText;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LinearColorSmoothing::SmoothingCfg::SmoothingCfg() :
 | 
				
			||||||
 | 
						  _pause(false),
 | 
				
			||||||
 | 
						  _settlingTime(DEFAULT_SETTLINGTIME),
 | 
				
			||||||
 | 
						  _updateInterval(DEFAULT_UPDATEFREQUENCY),
 | 
				
			||||||
 | 
						  _type(SmoothingType::Linear)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LinearColorSmoothing::SmoothingCfg::SmoothingCfg(bool pause, int64_t settlingTime, int updateInterval, SmoothingType type, double outputRate, double interpolationRate, unsigned outputDelay, bool dithering, double decay) :
 | 
				
			||||||
 | 
						  _pause(pause),
 | 
				
			||||||
 | 
						  _settlingTime(settlingTime),
 | 
				
			||||||
 | 
						  _updateInterval(updateInterval),
 | 
				
			||||||
 | 
						  _type(type),
 | 
				
			||||||
 | 
						  _outputRate(outputRate),
 | 
				
			||||||
 | 
						  _interpolationRate(interpolationRate),
 | 
				
			||||||
 | 
						  _outputDelay(outputDelay),
 | 
				
			||||||
 | 
						  _dithering(dithering),
 | 
				
			||||||
 | 
						  _decay(decay)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString LinearColorSmoothing::SmoothingCfg::EnumToString(SmoothingType type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (type == SmoothingType::Linear) {
 | 
				
			||||||
 | 
							return QString("Linear");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (type == SmoothingType::Decay)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return QString("Decay");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return QString("Unknown");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,7 @@ PriorityMuxer::PriorityMuxer(int ledCount, QObject * parent)
 | 
				
			|||||||
	_lowestPriorityInfo.componentId    = hyperion::COMP_COLOR;
 | 
						_lowestPriorityInfo.componentId    = hyperion::COMP_COLOR;
 | 
				
			||||||
	_lowestPriorityInfo.origin         = "System";
 | 
						_lowestPriorityInfo.origin         = "System";
 | 
				
			||||||
	_lowestPriorityInfo.owner          = "";
 | 
						_lowestPriorityInfo.owner          = "";
 | 
				
			||||||
 | 
						_lowestPriorityInfo.smooth_cfg	   = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_activeInputs[PriorityMuxer::LOWEST_PRIORITY] = _lowestPriorityInfo;
 | 
						_activeInputs[PriorityMuxer::LOWEST_PRIORITY] = _lowestPriorityInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -94,7 +94,7 @@
 | 
				
			|||||||
      "minimum": 0,
 | 
					      "minimum": 0,
 | 
				
			||||||
      "maximum": 2048,
 | 
					      "maximum": 2048,
 | 
				
			||||||
      "default": 0,
 | 
					      "default": 0,
 | 
				
			||||||
      "append": "edt_append_ms",
 | 
					      "append": "edt_append_frames",
 | 
				
			||||||
      "propertyOrder": 9
 | 
					      "propertyOrder": 9
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user