diff --git a/.github/workflows/push-master.yml b/.github/workflows/push-master.yml index 772704112..859b2a13e 100644 --- a/.github/workflows/push-master.yml +++ b/.github/workflows/push-master.yml @@ -165,7 +165,10 @@ jobs: windows: name: Windows - runs-on: windows-2025 + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-2022] env: MSVC: 2022 QT_VERSION: 6.8.3 @@ -181,7 +184,7 @@ jobs: id: cache-toolkit-windows with: path: ${{ env.TOOLKIT_DIR }} - key: ${{ runner.os }}-Toolkit-Qt.${{ env.QT_VERSION }}-NSIS-TurboJPEG + key: ${{ matrix.os }}-Toolkit-Qt.${{ env.QT_VERSION }}-NSIS-TurboJPEG - name: Python 3.13 for aqtinstall if: steps.cache-toolkit-windows.outputs.cache-hit != 'true' diff --git a/CHANGELOG.md b/CHANGELOG.md index 8158c35c5..0a1c2d62d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +- Fix smoothing algorithm drift in long-running sessions (#1561) - v22 🆕 - RGBW with Temporal Dithering - powered by Infinite Color Engine (#1483) - v22beta2 🆕 - Temporal Dithering: Improved Precision and Adaptive Stabilization (#1490) - v22beta2 🆕 - Add RGBW dithering for legacy RPi PWM & SPI sk6812 driver (#1498) - v22beta2 🆕 diff --git a/include/infinite-color-engine/InfiniteExponentialInterpolator.h b/include/infinite-color-engine/InfiniteExponentialInterpolator.h index e9db531de..f0cd8d0ff 100644 --- a/include/infinite-color-engine/InfiniteExponentialInterpolator.h +++ b/include/infinite-color-engine/InfiniteExponentialInterpolator.h @@ -16,8 +16,8 @@ class InfiniteExponentialInterpolator : public InfiniteInterpolator public: InfiniteExponentialInterpolator(); - void setTargetColors(std::vector&& new_rgb_targets, float startTimeMs, bool debug = false) override; - void updateCurrentColors(float currentTimeMs, float minBrightness) override; + void setTargetColors(std::vector&& new_rgb_targets, long long startTimeMs, bool debug = false) override; + void updateCurrentColors(long long currentTimeMs, float minBrightness) override; SharedOutputColors getCurrentColors(float minBrightness = 0.f) override; void resetState() override; @@ -31,7 +31,7 @@ class InfiniteExponentialInterpolator : public InfiniteInterpolator float _initialDuration = 150.0f; float _tau = 150.0f; - float _startAnimationTimeMs = 0.0f; - float _targetTime = 0.0f; - float _lastUpdate = 0.0f; + long long _startAnimationTimeMs = 0; + long long _targetTime = 0; + long long _lastUpdate = 0; }; diff --git a/include/infinite-color-engine/InfiniteHybridInterpolator.h b/include/infinite-color-engine/InfiniteHybridInterpolator.h index 995ec1bef..95b24b526 100644 --- a/include/infinite-color-engine/InfiniteHybridInterpolator.h +++ b/include/infinite-color-engine/InfiniteHybridInterpolator.h @@ -15,8 +15,8 @@ class InfiniteHybridInterpolator : public InfiniteInterpolator public: InfiniteHybridInterpolator(); - void setTargetColors(std::vector&& new_rgb_to_yuv_targets, float startTimeMs, bool debug = false) override; - void updateCurrentColors(float currentTimeMs, float minBrightness) override; + void setTargetColors(std::vector&& new_rgb_to_yuv_targets, long long startTimeMs, bool debug = false) override; + void updateCurrentColors(long long currentTimeMs, float minBrightness) override; SharedOutputColors getCurrentColors(float minBrightness = 0.f) override; void resetState() override; @@ -35,9 +35,9 @@ class InfiniteHybridInterpolator : public InfiniteInterpolator std::vector _velocitiesYUV; float _initialDuration = 150.0f; - float _startAnimationTimeMs = 0.0f; - float _targetTime = 0.0f; - float _lastUpdate = 0.0f; + long long _startAnimationTimeMs = 0; + long long _targetTime = 0; + long long _lastUpdate = 0; float _stiffness = 150.0f; float _damping = 26.0f; float _maxLuminanceChangePerStep = 0.02f; diff --git a/include/infinite-color-engine/InfiniteHybridRgbInterpolator.h b/include/infinite-color-engine/InfiniteHybridRgbInterpolator.h index 78c955d7c..26d44936b 100644 --- a/include/infinite-color-engine/InfiniteHybridRgbInterpolator.h +++ b/include/infinite-color-engine/InfiniteHybridRgbInterpolator.h @@ -15,8 +15,8 @@ class InfiniteHybridRgbInterpolator : public InfiniteInterpolator public: InfiniteHybridRgbInterpolator(); - void setTargetColors(std::vector&& new_rgb_targets, float startTimeMs, bool debug = false) override; - void updateCurrentColors(float currentTimeMs, float minBrightness) override; + void setTargetColors(std::vector&& new_rgb_targets, long long startTimeMs, bool debug = false) override; + void updateCurrentColors(long long currentTimeMs, float minBrightness) override; SharedOutputColors getCurrentColors(float minBrightness = 0.f) override; void resetState() override; @@ -33,9 +33,9 @@ class InfiniteHybridRgbInterpolator : public InfiniteInterpolator std::vector _velocitiesRGB; float _initialDuration = 150.0f; - float _startAnimationTimeMs = 0.0f; - float _targetTime = 0.0f; - float _lastUpdate = 0.0f; + long long _startAnimationTimeMs = 0; + long long _targetTime = 0; + long long _lastUpdate = 0; float _stiffness = 150.0f; float _damping = 26.0f; float _smoothingFactor = 0.0f; diff --git a/include/infinite-color-engine/InfiniteInterpolator.h b/include/infinite-color-engine/InfiniteInterpolator.h index 3a86b12ad..514149325 100644 --- a/include/infinite-color-engine/InfiniteInterpolator.h +++ b/include/infinite-color-engine/InfiniteInterpolator.h @@ -18,8 +18,8 @@ class InfiniteInterpolator { public: virtual ~InfiniteInterpolator() = default; - virtual void setTargetColors(std::vector&& new_rgb_targets, float startTimeMs, bool debug) = 0; - virtual void updateCurrentColors(float currentTimeMs, float minBrightness) = 0; + virtual void setTargetColors(std::vector&& new_rgb_targets, long long startTimeMs, bool debug) = 0; + virtual void updateCurrentColors(long long currentTimeMs, float minBrightness) = 0; virtual SharedOutputColors getCurrentColors(float minBrightness) = 0; virtual void resetState() = 0; diff --git a/include/infinite-color-engine/InfiniteRgbInterpolator.h b/include/infinite-color-engine/InfiniteRgbInterpolator.h index a2d67e8c4..9647f7077 100644 --- a/include/infinite-color-engine/InfiniteRgbInterpolator.h +++ b/include/infinite-color-engine/InfiniteRgbInterpolator.h @@ -15,8 +15,8 @@ class InfiniteRgbInterpolator : public InfiniteInterpolator public: InfiniteRgbInterpolator(); - void setTargetColors(std::vector&& new_rgb_targets, float startTimeMs, bool debug = false) override; - void updateCurrentColors(float currentTimeMs, float minBrightness) override; + void setTargetColors(std::vector&& new_rgb_targets, long long startTimeMs, bool debug = false) override; + void updateCurrentColors(long long currentTimeMs, float minBrightness) override; SharedOutputColors getCurrentColors(float minBrightness = 0.f) override; void resetState() override; @@ -32,7 +32,7 @@ class InfiniteRgbInterpolator : public InfiniteInterpolator float _smoothingFactor = 0.0f; float _initialDuration = 150.0f; - float _startAnimationTimeMs = 0.0f; - float _targetTime = 0.0f; - float _lastUpdate = 0.0f; + long long _startAnimationTimeMs = 0; + long long _targetTime = 0; + long long _lastUpdate = 0; }; diff --git a/include/infinite-color-engine/InfiniteStepperInterpolator.h b/include/infinite-color-engine/InfiniteStepperInterpolator.h index c7bf93598..8ff2e11c3 100644 --- a/include/infinite-color-engine/InfiniteStepperInterpolator.h +++ b/include/infinite-color-engine/InfiniteStepperInterpolator.h @@ -16,8 +16,8 @@ class InfiniteStepperInterpolator : public InfiniteInterpolator public: InfiniteStepperInterpolator(); - void setTargetColors(std::vector&& new_rgb_targets, float startTimeMs, bool debug = false) override; - void updateCurrentColors(float currentTimeMs, float minBrightness) override; + void setTargetColors(std::vector&& new_rgb_targets, long long startTimeMs, bool debug = false) override; + void updateCurrentColors(long long currentTimeMs, float minBrightness) override; SharedOutputColors getCurrentColors(float minBrightness = 0.f) override; void resetState() override; @@ -30,7 +30,7 @@ class InfiniteStepperInterpolator : public InfiniteInterpolator std::vector _targetColorsRGB; float _initialDuration = 150.0f; - float _startAnimationTimeMs = 0.0f; - float _targetTime = 0.0f; - float _lastUpdate = 0.0f; + long long _startAnimationTimeMs = 0; + long long _targetTime = 0; + long long _lastUpdate = 0; }; diff --git a/include/infinite-color-engine/InfiniteYuvInterpolator.h b/include/infinite-color-engine/InfiniteYuvInterpolator.h index 947fa3c04..eef756d53 100644 --- a/include/infinite-color-engine/InfiniteYuvInterpolator.h +++ b/include/infinite-color-engine/InfiniteYuvInterpolator.h @@ -15,8 +15,8 @@ class InfiniteYuvInterpolator : public InfiniteInterpolator public: InfiniteYuvInterpolator(); - void setTargetColors(std::vector&& new_rgb_to_yuv_targets, float startTimeMs, bool debug = false) override; - void updateCurrentColors(float currentTimeMs, float minBrightness) override; + void setTargetColors(std::vector&& new_rgb_to_yuv_targets, long long startTimeMs, bool debug = false) override; + void updateCurrentColors(long long currentTimeMs, float minBrightness) override; SharedOutputColors getCurrentColors(float minBrightness = 0.f) override; void resetState() override; @@ -34,9 +34,9 @@ class InfiniteYuvInterpolator : public InfiniteInterpolator std::vector _targetColorsYUV; float _initialDuration = 150.0f; - float _startAnimationTimeMs = 0.0f; - float _targetTime = 0.0f; - float _lastUpdate = 0.0f; + long long _startAnimationTimeMs = 0; + long long _targetTime = 0; + long long _lastUpdate = 0; float _maxLuminanceChangePerStep = 0.02f; float _smoothingFactor = 0.0f; }; diff --git a/sources/grabber/GrabberWorker.cpp b/sources/grabber/GrabberWorker.cpp index 6d4e66dec..5f8b6fc50 100644 --- a/sources/grabber/GrabberWorker.cpp +++ b/sources/grabber/GrabberWorker.cpp @@ -255,7 +255,7 @@ void GrabberWorker::process_image_jpg_mt() } else if (image.width() != (uint)_width || image.height() != (uint)_height) { - MemoryBuffer jpgBuffer(_width * _height * 3); + MemoryBuffer jpgBuffer(static_cast(_width) * _height * 3); if (tjDecompress2(_decompress, frameData, _size, jpgBuffer.data(), _width, 0, _height, TJPF_BGR, TJFLAG_BOTTOMUP | TJFLAG_FASTDCT | TJFLAG_FASTUPSAMPLE) != 0 && tjGetErrorCode(_decompress) == TJERR_FATAL) diff --git a/sources/infinite-color-engine/InfiniteExponentialInterpolator.cpp b/sources/infinite-color-engine/InfiniteExponentialInterpolator.cpp index c75cc2e36..bab58af79 100644 --- a/sources/infinite-color-engine/InfiniteExponentialInterpolator.cpp +++ b/sources/infinite-color-engine/InfiniteExponentialInterpolator.cpp @@ -60,7 +60,7 @@ void InfiniteExponentialInterpolator::resetToColors(std::vector&& colors setTargetColors(std::move(colors), startTimeMs); } -void InfiniteExponentialInterpolator::setTargetColors(std::vector&& new_rgb_targets, float startTimeMs, bool debug) +void InfiniteExponentialInterpolator::setTargetColors(std::vector&& new_rgb_targets, long long startTimeMs, bool debug) { if (new_rgb_targets.empty()) return; @@ -89,12 +89,12 @@ void InfiniteExponentialInterpolator::setTargetColors(std::vector&& new_ void InfiniteExponentialInterpolator::resetState() { _isAnimationComplete = true; - _lastUpdate = 0.0f; + _lastUpdate = 0; _currentColorsRGB.clear(); _targetColorsRGB.clear(); } -void InfiniteExponentialInterpolator::updateCurrentColors(float currentTimeMs, float /*minBrightness*/) +void InfiniteExponentialInterpolator::updateCurrentColors(long long currentTimeMs, float /*minBrightness*/) { if (_isAnimationComplete) { diff --git a/sources/infinite-color-engine/InfiniteHybridInterpolator.cpp b/sources/infinite-color-engine/InfiniteHybridInterpolator.cpp index cfa750601..b1f37e61c 100644 --- a/sources/infinite-color-engine/InfiniteHybridInterpolator.cpp +++ b/sources/infinite-color-engine/InfiniteHybridInterpolator.cpp @@ -70,11 +70,11 @@ void InfiniteHybridInterpolator::resetToColors(std::vector colors, float setTargetColors(std::move(colors), startTimeMs); } -void InfiniteHybridInterpolator::setTargetColors(std::vector&& new_rgb_to_yuv_targets, float startTimeMs, bool debug) { +void InfiniteHybridInterpolator::setTargetColors(std::vector&& new_rgb_to_yuv_targets, long long startTimeMs, bool debug) { if (new_rgb_to_yuv_targets.empty()) return; - const float delta = (!_isAnimationComplete) ? std::clamp(startTimeMs - _lastUpdate, 0.f, 100.0f) : 0.f; + const float delta = (!_isAnimationComplete) ? std::clamp(static_cast(startTimeMs - _lastUpdate), 0.f, 100.0f) : 0.f; if (debug) { @@ -111,7 +111,7 @@ void InfiniteHybridInterpolator::setTargetColors(std::vector&& new_rgb_t void InfiniteHybridInterpolator::resetState() { _isAnimationComplete = true; - _lastUpdate = 0.0f; + _lastUpdate = 0; _targetColorsRGB.clear(); _currentColorsRGB.reset(); _currentColorsYUV.clear(); @@ -119,14 +119,14 @@ void InfiniteHybridInterpolator::resetState() { _velocitiesYUV.clear(); } -void InfiniteHybridInterpolator::updateCurrentColors(float currentTimeMs, float minBrightness) { +void InfiniteHybridInterpolator::updateCurrentColors(long long currentTimeMs, float minBrightness) { if (_isAnimationComplete) { _lastUpdate = currentTimeMs; return; } - float dt = std::clamp(currentTimeMs - _lastUpdate, 0.001f, 100.0f); + float dt = std::clamp(static_cast(currentTimeMs - _lastUpdate), 0.001f, 100.0f); _lastUpdate = currentTimeMs; auto computeChannelVec = [&](float3& cur, const float3& diff, float3& vel) -> bool { diff --git a/sources/infinite-color-engine/InfiniteHybridRgbInterpolator.cpp b/sources/infinite-color-engine/InfiniteHybridRgbInterpolator.cpp index 0fbf84ae9..08ebb0d43 100644 --- a/sources/infinite-color-engine/InfiniteHybridRgbInterpolator.cpp +++ b/sources/infinite-color-engine/InfiniteHybridRgbInterpolator.cpp @@ -70,11 +70,11 @@ void InfiniteHybridRgbInterpolator::resetToColors(std::vector colors, fl setTargetColors(std::move(colors), startTimeMs); } -void InfiniteHybridRgbInterpolator::setTargetColors(std::vector&& new_rgb_targets, float startTimeMs, bool debug) { +void InfiniteHybridRgbInterpolator::setTargetColors(std::vector&& new_rgb_targets, long long startTimeMs, bool debug) { if (new_rgb_targets.empty()) return; - const float delta = (!_isAnimationComplete) ? std::clamp(startTimeMs - _lastUpdate, 0.f, 100.0f) : 0.f; + const float delta = (!_isAnimationComplete) ? std::clamp(static_cast(startTimeMs - _lastUpdate), 0.f, 100.0f) : 0.f; if (debug) { @@ -118,20 +118,20 @@ void InfiniteHybridRgbInterpolator::setTargetColors(std::vector&& new_rg void InfiniteHybridRgbInterpolator::resetState() { _isAnimationComplete = true; - _lastUpdate = 0.0f; + _lastUpdate = 0; _targetColorsRGB.clear(); _currentColorsRGB.clear(); _velocitiesRGB.clear(); } -void InfiniteHybridRgbInterpolator::updateCurrentColors(float currentTimeMs, float minBrightness) { +void InfiniteHybridRgbInterpolator::updateCurrentColors(long long currentTimeMs, float minBrightness) { if (_isAnimationComplete) { _lastUpdate = currentTimeMs; return; } - float dt = std::clamp(currentTimeMs - _lastUpdate, 0.001f, 100.0f); + float dt = std::clamp(static_cast(currentTimeMs - _lastUpdate), 0.001f, 100.0f); _lastUpdate = currentTimeMs; auto computeChannelVec = [&](float3& cur, const float3& tgt, const float3& diff, float3& vel) -> bool { diff --git a/sources/infinite-color-engine/InfiniteRgbInterpolator.cpp b/sources/infinite-color-engine/InfiniteRgbInterpolator.cpp index 8ed98b645..523ee1601 100644 --- a/sources/infinite-color-engine/InfiniteRgbInterpolator.cpp +++ b/sources/infinite-color-engine/InfiniteRgbInterpolator.cpp @@ -60,12 +60,12 @@ void InfiniteRgbInterpolator::resetToColors(std::vector colors) _isAnimationComplete = true; } -void InfiniteRgbInterpolator::setTargetColors(std::vector&& new_rgb_targets, float startTimeMs, bool debug) +void InfiniteRgbInterpolator::setTargetColors(std::vector&& new_rgb_targets, long long startTimeMs, bool debug) { if (new_rgb_targets.empty()) return; - const float delta = (!_isAnimationComplete) ? std::clamp(startTimeMs - _lastUpdate, 0.f, 100.0f) : 0.f; + const float delta = (!_isAnimationComplete) ? std::clamp(static_cast(startTimeMs - _lastUpdate), 0.f, 100.0f) : 0.f; if (debug) { @@ -108,7 +108,7 @@ void InfiniteRgbInterpolator::setTargetColors(std::vector&& new_rgb_targ void InfiniteRgbInterpolator::resetState() { _isAnimationComplete = true; - _lastUpdate = 0.0f; + _lastUpdate = 0; _currentColorsRGB.clear(); _targetColorsRGB.clear(); } @@ -118,7 +118,7 @@ void InfiniteRgbInterpolator::setSmoothingFactor(float factor) _smoothingFactor = std::max(0.0f, std::min(factor, 1.0f)); } -void InfiniteRgbInterpolator::updateCurrentColors(float currentTimeMs, float /*minBrightness*/) +void InfiniteRgbInterpolator::updateCurrentColors(long long currentTimeMs, float /*minBrightness*/) { if (_isAnimationComplete) { diff --git a/sources/infinite-color-engine/InfiniteStepperInterpolator.cpp b/sources/infinite-color-engine/InfiniteStepperInterpolator.cpp index ef043c82e..ee2b40c7b 100644 --- a/sources/infinite-color-engine/InfiniteStepperInterpolator.cpp +++ b/sources/infinite-color-engine/InfiniteStepperInterpolator.cpp @@ -59,12 +59,12 @@ void InfiniteStepperInterpolator::resetToColors(std::vector&& colors, fl setTargetColors(std::move(colors), startTimeMs); } -void InfiniteStepperInterpolator::setTargetColors(std::vector&& new_rgb_targets, float startTimeMs, bool debug) +void InfiniteStepperInterpolator::setTargetColors(std::vector&& new_rgb_targets, long long startTimeMs, bool debug) { if (new_rgb_targets.empty()) return; - const float delta = (!_isAnimationComplete) ? std::clamp(startTimeMs - _lastUpdate, 0.f, 100.0f) : 0.f; + const float delta = (!_isAnimationComplete) ? std::clamp(static_cast(startTimeMs - _lastUpdate), 0.f, 100.0f) : 0.f; if (debug) { @@ -92,12 +92,12 @@ void InfiniteStepperInterpolator::setTargetColors(std::vector&& new_rgb_ void InfiniteStepperInterpolator::resetState() { _isAnimationComplete = true; - _lastUpdate = 0.0f; + _lastUpdate = 0; _currentColorsRGB.clear(); _targetColorsRGB.clear(); } -void InfiniteStepperInterpolator::updateCurrentColors(float currentTimeMs, float /*minBrightness*/) +void InfiniteStepperInterpolator::updateCurrentColors(long long currentTimeMs, float /*minBrightness*/) { if (_isAnimationComplete) { diff --git a/sources/infinite-color-engine/InfiniteYuvInterpolator.cpp b/sources/infinite-color-engine/InfiniteYuvInterpolator.cpp index 2d4609381..4e2cac477 100644 --- a/sources/infinite-color-engine/InfiniteYuvInterpolator.cpp +++ b/sources/infinite-color-engine/InfiniteYuvInterpolator.cpp @@ -73,12 +73,12 @@ void InfiniteYuvInterpolator::setSmoothingFactor(float factor) _smoothingFactor = std::max(0.0f, std::min(factor, 1.0f)); } -void InfiniteYuvInterpolator::setTargetColors(std::vector&& new_rgb_to_yuv_targets, float startTimeMs, bool debug) +void InfiniteYuvInterpolator::setTargetColors(std::vector&& new_rgb_to_yuv_targets, long long startTimeMs, bool debug) { if (new_rgb_to_yuv_targets.empty()) return; - const float delta = (!_isAnimationComplete) ? std::clamp(startTimeMs - _lastUpdate, 0.f, 100.0f) : 0.f; + const float delta = (!_isAnimationComplete) ? std::clamp(static_cast(startTimeMs - _lastUpdate), 0.f, 100.0f) : 0.f; if (debug) { @@ -127,14 +127,14 @@ void InfiniteYuvInterpolator::setTargetColors(std::vector&& new_rgb_to_y void InfiniteYuvInterpolator::resetState() { _isAnimationComplete = true; - _lastUpdate = 0.0f; + _lastUpdate = 0; _targetColorsRGB.clear(); _currentColorsRGB.reset(); _currentColorsYUV.clear(); _targetColorsYUV.clear(); } -void InfiniteYuvInterpolator::updateCurrentColors(float currentTimeMs, float /*minBrightness*/) +void InfiniteYuvInterpolator::updateCurrentColors(long long currentTimeMs, float /*minBrightness*/) { if (_isAnimationComplete) {