improved FPS calc resolution, added averaging & multiplier compileflags
Fixed point calculation for improved accuracy, dithering in debug builds only. Averaging and optional multiplier can be set as compile flags, example for speed testing with long averaging and a 10x multiplier: -D FPS_CALC_AVG=200 -D FPS_MULTIPLIER=10 The calculation resolution is limited (9.7bit fixed point) so values larger than 200 can hit resolution limit and get stuck before reaching the final value. If WLED_DEBUG is defined, dithering is added to the returned value so sub-frame accuracy is possible in post-processingwithout enabling the multiplier.
This commit is contained in:
@@ -1412,10 +1412,12 @@ void WS2812FX::show() {
|
||||
|
||||
unsigned long showNow = millis();
|
||||
size_t diff = showNow - _lastShow;
|
||||
size_t fpsCurr = 200;
|
||||
if (diff > 0) fpsCurr = 1000 / diff;
|
||||
_cumulativeFps = (3 * _cumulativeFps + fpsCurr +2) >> 2; // "+2" for proper rounding (2/4 = 0.5)
|
||||
_lastShow = showNow;
|
||||
|
||||
if (diff > 0) { // skip calculation if no time has passed
|
||||
size_t fpsCurr = (1000<<7) / diff; // fixed point 9.7 bit
|
||||
_cumulativeFps = (FPS_CALC_AVG * _cumulativeFps + fpsCurr + FPS_CALC_AVG / 2) / (FPS_CALC_AVG + 1); // "+FPS_CALC_AVG/2" for proper rounding
|
||||
_lastShow = showNow;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1432,7 +1434,11 @@ bool WS2812FX::isUpdating() const {
|
||||
*/
|
||||
uint16_t WS2812FX::getFps() const {
|
||||
if (millis() - _lastShow > 2000) return 0;
|
||||
return _cumulativeFps +1;
|
||||
#ifdef WLED_DEBUG
|
||||
return (FPS_MULTIPLIER * (_cumulativeFps + (random16() & 63))) >> 7; // + random("0.5") for dithering
|
||||
#else
|
||||
return (FPS_MULTIPLIER * _cumulativeFps) >> 7; // _cumulativeFps is stored in fixed point 9.7 bit
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::setTargetFps(uint8_t fps) {
|
||||
|
||||
Reference in New Issue
Block a user