From 0e0728b15db9a4314aec2796e872669a87992447 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Thu, 18 Apr 2024 12:57:29 +0200 Subject: [PATCH 1/9] audioreactive: workaround for ArduinoFFT bug 93 This fix works around a problem that was solved in upstream ArduinoFFT 2.0.2 --- usermods/audioreactive/audio_reactive.h | 1 + 1 file changed, 1 insertion(+) diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index 46d1fe36..b21db32b 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -601,6 +601,7 @@ void FFTcode(void * parameter) FFT.windowing(FFTWindow::Blackman_Harris, FFTDirection::Forward); // Weigh data using "Blackman- Harris" window - sharp peaks due to excellent sideband rejection #endif FFT.compute( FFTDirection::Forward ); // Compute FFT + vReal[0] = 0; // The remaining DC offset on the signal produces a strong spike on position 0 that should be eliminated to avoid issues. FFT.complexToMagnitude(); // Compute magnitudes #else FFT.DCRemoval(); // let FFT lib remove DC component, so we don't need to care about this in getSamples() From 7dc6659e701a1efd4217acbdbe5969113f7eacc4 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 18 Apr 2024 13:36:00 +0200 Subject: [PATCH 2/9] audioreactive: better do DC removal after FFT.complexToMagnitude(); --- usermods/audioreactive/audio_reactive.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index b21db32b..c3efd367 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -601,8 +601,8 @@ void FFTcode(void * parameter) FFT.windowing(FFTWindow::Blackman_Harris, FFTDirection::Forward); // Weigh data using "Blackman- Harris" window - sharp peaks due to excellent sideband rejection #endif FFT.compute( FFTDirection::Forward ); // Compute FFT - vReal[0] = 0; // The remaining DC offset on the signal produces a strong spike on position 0 that should be eliminated to avoid issues. FFT.complexToMagnitude(); // Compute magnitudes + vReal[0] = 0; // The remaining DC offset on the signal produces a strong spike on position 0 that should be eliminated to avoid issues. #else FFT.DCRemoval(); // let FFT lib remove DC component, so we don't need to care about this in getSamples() From 48c64aecff9fc19fa00988c19a61a568eeebad01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Tue, 16 Apr 2024 17:41:20 +0200 Subject: [PATCH 3/9] Merge pull request #3904 from DedeHai/FX_fcn_improvements added improvements to color scaling and blurring --- wled00/FX.h | 77 ++++++++++++++++++++++------------------ wled00/FX_2Dfcn.cpp | 86 +++++++++++++++++++++++++-------------------- wled00/FX_fcn.cpp | 57 ++++++++++++++---------------- wled00/colors.cpp | 62 ++++++++++++++++++++++++++------ 4 files changed, 168 insertions(+), 114 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index 8df52855..2bceeb5f 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -617,7 +617,7 @@ typedef struct Segment { void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); } uint32_t __attribute__((pure)) getPixelColor(int i); // WLEDMM attribute added // 1D support functions (some implement 2D as well) - void blur(uint8_t); + void blur(uint8_t, bool smear = false); void fill(uint32_t c); void fade_out(uint8_t r); void fadeToBlackBy(uint8_t fadeBy); @@ -658,12 +658,15 @@ typedef struct Segment { return (x%width) + (y%height) * width; } void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color - void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline - void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } // automatically inline - void setPixelColorXY(float x, float y, uint32_t c, bool aa = true, bool fast = true); - void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); } - void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); } - uint32_t __attribute__((pure)) getPixelColorXY(uint16_t x, uint16_t y); // WLEDMM attribute pure + inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColorXY(int(x), int(y), c); } + inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } + inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } + #ifdef WLED_USE_AA_PIXELS + void setPixelColorXY(float x, float y, uint32_t c, bool aa = true); + inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); } + inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); } + #endif + uint32_t __attribute__((pure)) getPixelColorXY(int x, int y); // 2D support functions void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend); void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); } @@ -672,8 +675,8 @@ typedef struct Segment { void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), fast); } void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade); void box_blur(uint16_t i, bool vertical, fract8 blur_amount); // 1D box blur (with weight) - void blurRow(uint16_t row, fract8 blur_amount); - void blurCol(uint16_t col, fract8 blur_amount); + void blurRow(uint32_t row, fract8 blur_amount, bool smear = false); + void blurCol(uint32_t col, fract8 blur_amount, bool smear = false); void moveX(int8_t delta, bool wrap = false); void moveY(int8_t delta, bool wrap = false); void move(uint8_t dir, uint8_t delta, bool wrap = false); @@ -692,32 +695,36 @@ typedef struct Segment { void nscale8(uint8_t scale); bool jsonToPixels(char *name, uint8_t fileNr); //WLEDMM for artifx #else - uint16_t XY(uint16_t x, uint16_t y) { return x; } - void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(x, c); } - void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); } - void setPixelColorXY(int x, int y, CRGB c) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0)); } - void setPixelColorXY(float x, float y, uint32_t c, bool aa = true) { setPixelColor(x, c, aa); } - void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColor(x, RGBW32(r,g,b,w), aa); } - void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0), aa); } - uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(x); } - void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t c, uint8_t blend) { blendPixelColor(x, c, blend); } - void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColor(x, RGBW32(c.r,c.g,c.b,0), blend); } - void addPixelColorXY(int x, int y, uint32_t color, bool fast = false) { addPixelColor(x, color, fast); } - void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(x, RGBW32(r,g,b,w), fast); } - void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0), fast); } - void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); } - void box_blur(uint16_t i, bool vertical, fract8 blur_amount) {} - void blurRow(uint16_t row, fract8 blur_amount) {} - void blurCol(uint16_t col, fract8 blur_amount) {} - void moveX(int8_t delta, bool wrap = false) {} - void moveY(int8_t delta, bool wrap = false) {} - void move(uint8_t dir, uint8_t delta, bool wrap = false) {} - void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c) {} - void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) {} - void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) {} - void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color) {} - void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color) {} - void wu_pixel(uint32_t x, uint32_t y, CRGB c) {} + inline uint16_t XY(uint16_t x, uint16_t y) { return x; } + inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(x, c); } + inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColor(int(x), c); } + inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); } + inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0)); } + #ifdef WLED_USE_AA_PIXELS + inline void setPixelColorXY(float x, float y, uint32_t c, bool aa = true) { setPixelColor(x, c, aa); } + inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColor(x, RGBW32(r,g,b,w), aa); } + inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0), aa); } + #endif + inline uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(x); } + inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t c, uint8_t blend) { blendPixelColor(x, c, blend); } + inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColor(x, RGBW32(c.r,c.g,c.b,0), blend); } + inline void addPixelColorXY(int x, int y, uint32_t color, bool fast = false) { addPixelColor(x, color, fast); } + inline void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(x, RGBW32(r,g,b,w), fast); } + inline void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0), fast); } + inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); } + inline void box_blur(uint16_t i, bool vertical, fract8 blur_amount) {} + inline void blurRow(uint32_t row, fract8 blur_amount, bool smear = false) {} + inline void blurCol(uint32_t col, fract8 blur_amount, bool smear = false) {} + inline void moveX(int8_t delta, bool wrap = false) {} + inline void moveY(int8_t delta, bool wrap = false) {} + inline void move(uint8_t dir, uint8_t delta, bool wrap = false) {} + inline void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c) {} + inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) {} + inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) {} + inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t = 0, int8_t = 0) {} + inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color) {} + inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2, int8_t rotate = 0) {} + inline void wu_pixel(uint32_t x, uint32_t y, CRGB c) {} #endif uint8_t * getAudioPalette(int pal); //WLEDMM netmindz ar palette } segment; diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 2844d492..3a5ac231 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -221,11 +221,7 @@ void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col) //WLEDMM: uint8_t _bri_t = currentBri(on ? opacity : 0); if (!_bri_t && !transitional) return; if (_bri_t < 255) { - byte r = scale8(R(col), _bri_t); - byte g = scale8(G(col), _bri_t); - byte b = scale8(B(col), _bri_t); - byte w = scale8(W(col), _bri_t); - col = RGBW32(r, g, b, w); + col = color_fade(col, _bri_t); } if (reverse ) x = virtualWidth() - x - 1; @@ -310,7 +306,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa, bool fast } // returns RGBW values of pixel -uint32_t Segment::getPixelColorXY(uint16_t x, uint16_t y) { +uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) { if (!isActive()) return 0; // not active int i = XY(x,y); if (ledsrgb) return RGBW32(ledsrgb[i].r, ledsrgb[i].g, ledsrgb[i].b, 0); @@ -356,59 +352,71 @@ void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { } // blurRow: perform a blur on a row of a rectangular matrix -void Segment::blurRow(uint16_t row, fract8 blur_amount) { - if (!isActive()) return; // not active +void Segment::blurRow(uint32_t row, fract8 blur_amount, bool smear){ + if (!isActive() || blur_amount == 0) return; // not active const uint_fast16_t cols = virtualWidth(); const uint_fast16_t rows = virtualHeight(); if (row >= rows) return; // blur one row - uint8_t keep = 255 - blur_amount; + uint8_t keep = smear ? 255 : 255 - blur_amount; uint8_t seep = blur_amount >> 1; - CRGB carryover = CRGB::Black; - for (uint_fast16_t x = 0; x < cols; x++) { - CRGB cur = getPixelColorXY(x, row); - uint32_t before = uint32_t(cur); // remember color before blur - CRGB part = cur; - part.nscale8(seep); - cur.nscale8(keep); - cur += carryover; - if (x>0) { - CRGB prev = CRGB(getPixelColorXY(x-1, row)) + part; - setPixelColorXY(x-1, row, prev); + uint32_t carryover = BLACK; + uint32_t lastnew; + uint32_t last; + uint32_t curnew; + for (unsigned x = 0; x < cols; x++) { + uint32_t cur = getPixelColorXY(x, row); + uint32_t part = color_fade(cur, seep); + curnew = color_fade(cur, keep); + if (x > 0) { + if (carryover) + curnew = color_add(curnew, carryover, true); + uint32_t prev = color_add(lastnew, part, true); + if (last != prev) // optimization: only set pixel if color has changed + setPixelColorXY(x - 1, row, prev); } - if (before != uint32_t(cur)) // optimization: only set pixel if color has changed - setPixelColorXY(x, row, cur); + else // first pixel + setPixelColorXY(x, row, curnew); + lastnew = curnew; + last = cur; // save original value for comparison on next iteration carryover = part; } + setPixelColorXY(cols-1, row, curnew); // set last pixel } // blurCol: perform a blur on a column of a rectangular matrix -void Segment::blurCol(uint16_t col, fract8 blur_amount) { - if (!isActive()) return; // not active +void Segment::blurCol(uint32_t col, fract8 blur_amount, bool smear) { + if (!isActive() || blur_amount == 0) return; // not active const uint_fast16_t cols = virtualWidth(); const uint_fast16_t rows = virtualHeight(); if (col >= cols) return; // blur one column - uint8_t keep = 255 - blur_amount; + uint8_t keep = smear ? 255 : 255 - blur_amount; uint8_t seep = blur_amount >> 1; - CRGB carryover = CRGB::Black; - for (uint_fast16_t y = 0; y < rows; y++) { - CRGB cur = getPixelColorXY(col, y); - CRGB part = cur; - uint32_t before = uint32_t(cur); // remember color before blur - part.nscale8(seep); - cur.nscale8(keep); - cur += carryover; - if (y>0) { - CRGB prev = CRGB(getPixelColorXY(col, y-1)) + part; - setPixelColorXY(col, y-1, prev); + uint32_t carryover = BLACK; + uint32_t lastnew; + uint32_t last; + uint32_t curnew; + for (unsigned y = 0; y < rows; y++) { + uint32_t cur = getPixelColorXY(col, y); + uint32_t part = color_fade(cur, seep); + curnew = color_fade(cur, keep); + if (y > 0) { + if (carryover) + curnew = color_add(curnew, carryover, true); + uint32_t prev = color_add(lastnew, part, true); + if (last != prev) // optimization: only set pixel if color has changed + setPixelColorXY(col, y - 1, prev); } - if (before != uint32_t(cur)) // optimization: only set pixel if color has changed - setPixelColorXY(col, y, cur); - carryover = part; + else // first pixel + setPixelColorXY(col, y, curnew); + lastnew = curnew; + last = cur; //save original value for comparison on next iteration + carryover = part; } + setPixelColorXY(col, rows - 1, curnew); } // 1D Box blur (with added weight - blur_amount: [0=no blur, 255=max blur]) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 0bf310dc..4c56b0ea 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1030,11 +1030,7 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col) //WLEDMM: IRAM_ATT uint8_t _bri_t = currentBri(on ? opacity : 0); if (!_bri_t && !transitional && fadeTransition) return; // if _bri_t == 0 && segment is not transitioning && transitions are enabled then save a few CPU cycles if (_bri_t < 255) { - byte r = scale8(R(col), _bri_t); - byte g = scale8(G(col), _bri_t); - byte b = scale8(B(col), _bri_t); - byte w = scale8(W(col), _bri_t); - col = RGBW32(r, g, b, w); + col = color_fade(col, _bri_t); } // expand pixel (taking into account start, grouping, spacing [and offset]) @@ -1357,42 +1353,43 @@ void Segment::fadeToBlackBy(uint8_t fadeBy) { /* * blurs segment content, source: FastLED colorutils.cpp */ -void Segment::blur(uint8_t blur_amount) -{ +void Segment::blur(uint8_t blur_amount, bool smear) { if (!isActive() || blur_amount == 0) return; // optimization: 0 means "don't blur" #ifndef WLED_DISABLE_2D if (is2D()) { // compatibility with 2D - const uint_fast16_t cols = virtualWidth(); - const uint_fast16_t rows = virtualHeight(); - for (uint_fast16_t i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows - for (uint_fast16_t k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns + const unsigned cols = virtualWidth(); + const unsigned rows = virtualHeight(); + for (unsigned i = 0; i < rows; i++) blurRow(i, blur_amount, smear); // blur all rows + for (unsigned k = 0; k < cols; k++) blurCol(k, blur_amount, smear); // blur all columns return; } #endif - uint8_t keep = 255 - blur_amount; + uint8_t keep = smear ? 255 : 255 - blur_amount; uint8_t seep = blur_amount >> 1; - CRGB carryover = CRGB::Black; - uint_fast16_t vlength = virtualLength(); - for(uint_fast16_t i = 0; i < vlength; i++) - { - CRGB cur = CRGB(getPixelColor(i)); - CRGB part = cur; - uint32_t before = uint32_t(cur); // remember color before blur - part.nscale8(seep); - cur.nscale8(keep); - cur += carryover; - if(i > 0) { - uint32_t c = getPixelColor(i-1); - uint8_t r = R(c); - uint8_t g = G(c); - uint8_t b = B(c); - setPixelColor((uint16_t)(i-1), qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue)); + unsigned vlength = virtualLength(); + uint32_t carryover = BLACK; + uint32_t lastnew; + uint32_t last; + uint32_t curnew; + for (unsigned i = 0; i < vlength; i++) { + uint32_t cur = getPixelColor(i); + uint32_t part = color_fade(cur, seep); + curnew = color_fade(cur, keep); + if (i > 0) { + if (carryover) + curnew = color_add(curnew, carryover, true); + uint32_t prev = color_add(lastnew, part, true); + if (last != prev) // optimization: only set pixel if color has changed + setPixelColor(i - 1, prev); } - if (before != uint32_t(cur)) // optimization: only set pixel if color has changed - setPixelColor((uint16_t)i,cur.red, cur.green, cur.blue); + else // first pixel + setPixelColor(i, curnew); + lastnew = curnew; + last = cur; // save original value for comparison on next iteration carryover = part; } + setPixelColor(vlength - 1, curnew); } /* diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 30d31927..53e99d2d 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -37,16 +37,58 @@ IRAM_ATTR_YN uint32_t color_blend(uint32_t color1, uint32_t color2, uint_fast16_ */ IRAM_ATTR_YN uint32_t color_add(uint32_t c1, uint32_t c2) // WLEDMM added IRAM_ATTR_YN { - uint32_t r = R(c1) + R(c2); - uint32_t g = G(c1) + G(c2); - uint32_t b = B(c1) + B(c2); - uint32_t w = W(c1) + W(c2); - uint_fast16_t max = r; - if (g > max) max = g; - if (b > max) max = b; - if (w > max) max = w; - if (max < 256) return RGBW32(r, g, b, w); - else return RGBW32(r * 255 / max, g * 255 / max, b * 255 / max, w * 255 / max); + if (fast) { + uint8_t r = R(c1); + uint8_t g = G(c1); + uint8_t b = B(c1); + uint8_t w = W(c1); + r = qadd8(r, R(c2)); + g = qadd8(g, G(c2)); + b = qadd8(b, B(c2)); + w = qadd8(w, W(c2)); + return RGBW32(r,g,b,w); + } else { + uint32_t r = R(c1) + R(c2); + uint32_t g = G(c1) + G(c2); + uint32_t b = B(c1) + B(c2); + uint32_t w = W(c1) + W(c2); + uint_fast16_t max = r; + if (g > max) max = g; + if (b > max) max = b; + if (w > max) max = w; + if (max < 256) return RGBW32(r, g, b, w); + else return RGBW32(r * 255 / max, g * 255 / max, b * 255 / max, w * 255 / max); + } +} + +/* + * fades color toward black + * if using "video" method the resulting color will never become black unless it is already black + */ + +uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) +{ + uint32_t scaledcolor; // color order is: W R G B from MSB to LSB + uint32_t r = R(c1); + uint32_t g = G(c1); + uint32_t b = B(c1); + uint32_t w = W(c1); + if (video) { + uint32_t scale = amount; // 32bit for faster calculation + scaledcolor = (((r * scale) >> 8) << 16) + ((r && scale) ? 1 : 0); + scaledcolor |= (((g * scale) >> 8) << 8) + ((g && scale) ? 1 : 0); + scaledcolor |= ((b * scale) >> 8) + ((b && scale) ? 1 : 0); + scaledcolor |= (((w * scale) >> 8) << 24) + ((w && scale) ? 1 : 0); + return scaledcolor; + } + else { + uint32_t scale = 1 + amount; + scaledcolor = ((r * scale) >> 8) << 16; + scaledcolor |= ((g * scale) >> 8) << 8; + scaledcolor |= (b * scale) >> 8; + scaledcolor |= ((w * scale) >> 8) << 24; + return scaledcolor; + } } void setRandomColor(byte* rgb) From 93b8c63e2b98e170177844ada717dce0d3b3ee6f Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 18 Apr 2024 21:09:14 +0200 Subject: [PATCH 4/9] post PR3904 fixes and improvements * fix compiler warnings (uninitialized vars, ambiguous functions calls) * restore some lost function prototypes * avoid negative pixel indices * only use "fast" color_add when there is no risk of "overshooting" results * minor optimizations --- wled00/FX.cpp | 2 +- wled00/FX.h | 10 +++++----- wled00/FX_2Dfcn.cpp | 32 ++++++++++++++++---------------- wled00/FX_fcn.cpp | 20 ++++++++++---------- wled00/colors.cpp | 15 ++++++++++----- wled00/fcn_declare.h | 3 ++- wled00/wled.h | 2 +- 7 files changed, 45 insertions(+), 39 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 5fa0a0fe..e18517f4 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5627,7 +5627,7 @@ uint16_t mode_2DPlasmaball(void) { // By: Stepko https://edito (rows - 1 - cy == 0)) ? ColorFromPalette(SEGPALETTE, beat8(5), thisVal, LINEARBLEND) : CRGB::Black); } } - SEGMENT.blur(SEGMENT.custom2>>5); + SEGMENT.blur(SEGMENT.custom2>>5, (SEGMENT.custom2 > 132)); // WLEDMM return FRAMETIME; } // mode_2DPlasmaball() diff --git a/wled00/FX.h b/wled00/FX.h index 2bceeb5f..037ef181 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -661,11 +661,11 @@ typedef struct Segment { inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColorXY(int(x), int(y), c); } inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } - #ifdef WLED_USE_AA_PIXELS - void setPixelColorXY(float x, float y, uint32_t c, bool aa = true); + //#ifdef WLED_USE_AA_PIXELS + void setPixelColorXY(float x, float y, uint32_t c, bool aa = true, bool fast=true); inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); } inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); } - #endif + //#endif uint32_t __attribute__((pure)) getPixelColorXY(int x, int y); // 2D support functions void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend); @@ -700,11 +700,11 @@ typedef struct Segment { inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColor(int(x), c); } inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); } inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0)); } - #ifdef WLED_USE_AA_PIXELS + //#ifdef WLED_USE_AA_PIXELS inline void setPixelColorXY(float x, float y, uint32_t c, bool aa = true) { setPixelColor(x, c, aa); } inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColor(x, RGBW32(r,g,b,w), aa); } inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0), aa); } - #endif + //#endif inline uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(x); } inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t c, uint8_t blend) { blendPixelColor(x, c, blend); } inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColor(x, RGBW32(c.r,c.g,c.b,0), blend); } diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 3a5ac231..45e37598 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -214,7 +214,7 @@ uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) { void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col) //WLEDMM: IRAM_ATTR conditionally { if (Segment::maxHeight==1) return; // not a matrix set-up - if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit + if (x<0 || y<0 || x >= virtualWidth() || y >= virtualHeight()) return; // if pixel would fall out of virtual segment just exit if (ledsrgb) ledsrgb[XY(x,y)] = col; @@ -307,7 +307,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa, bool fast // returns RGBW values of pixel uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) { - if (!isActive()) return 0; // not active + if (x<0 || y<0 || !isActive()) return 0; // not active or out-of range int i = XY(x,y); if (ledsrgb) return RGBW32(ledsrgb[i].r, ledsrgb[i].g, ledsrgb[i].b, 0); if (reverse ) x = virtualWidth() - x - 1; @@ -353,7 +353,7 @@ void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { // blurRow: perform a blur on a row of a rectangular matrix void Segment::blurRow(uint32_t row, fract8 blur_amount, bool smear){ - if (!isActive() || blur_amount == 0) return; // not active + if (!isActive()) return; // not active const uint_fast16_t cols = virtualWidth(); const uint_fast16_t rows = virtualHeight(); @@ -364,30 +364,30 @@ void Segment::blurRow(uint32_t row, fract8 blur_amount, bool smear){ uint32_t carryover = BLACK; uint32_t lastnew; uint32_t last; - uint32_t curnew; + uint32_t curnew = 0; for (unsigned x = 0; x < cols; x++) { uint32_t cur = getPixelColorXY(x, row); uint32_t part = color_fade(cur, seep); curnew = color_fade(cur, keep); if (x > 0) { if (carryover) - curnew = color_add(curnew, carryover, true); - uint32_t prev = color_add(lastnew, part, true); + curnew = color_add(curnew, carryover, !smear); // WLEDMM don't use "fast" when smear==true (better handling of bright colors) + uint32_t prev = color_add(lastnew, part, !smear);// WLEDMM if (last != prev) // optimization: only set pixel if color has changed - setPixelColorXY(x - 1, row, prev); + setPixelColorXY(int(x - 1), int(row), prev); } else // first pixel - setPixelColorXY(x, row, curnew); + setPixelColorXY(int(x), int(row), curnew); lastnew = curnew; last = cur; // save original value for comparison on next iteration carryover = part; } - setPixelColorXY(cols-1, row, curnew); // set last pixel + setPixelColorXY(int(cols-1), int(row), curnew); // set last pixel } // blurCol: perform a blur on a column of a rectangular matrix void Segment::blurCol(uint32_t col, fract8 blur_amount, bool smear) { - if (!isActive() || blur_amount == 0) return; // not active + if (!isActive()) return; // not active const uint_fast16_t cols = virtualWidth(); const uint_fast16_t rows = virtualHeight(); @@ -398,25 +398,25 @@ void Segment::blurCol(uint32_t col, fract8 blur_amount, bool smear) { uint32_t carryover = BLACK; uint32_t lastnew; uint32_t last; - uint32_t curnew; + uint32_t curnew = 0; for (unsigned y = 0; y < rows; y++) { uint32_t cur = getPixelColorXY(col, y); uint32_t part = color_fade(cur, seep); curnew = color_fade(cur, keep); if (y > 0) { if (carryover) - curnew = color_add(curnew, carryover, true); - uint32_t prev = color_add(lastnew, part, true); + curnew = color_add(curnew, carryover, !smear); // WLEDMM don't use "fast" when smear==true (better handling of bright colors) + uint32_t prev = color_add(lastnew, part, !smear); // WLEDMM if (last != prev) // optimization: only set pixel if color has changed - setPixelColorXY(col, y - 1, prev); + setPixelColorXY(int(col), int(y - 1), prev); } else // first pixel - setPixelColorXY(col, y, curnew); + setPixelColorXY(int(col), int(y), curnew); lastnew = curnew; last = cur; //save original value for comparison on next iteration carryover = part; } - setPixelColorXY(col, rows - 1, curnew); + setPixelColorXY(int(col), int(rows - 1), curnew); } // 1D Box blur (with added weight - blur_amount: [0=no blur, 255=max blur]) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 4c56b0ea..537dc662 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1358,10 +1358,10 @@ void Segment::blur(uint8_t blur_amount, bool smear) { #ifndef WLED_DISABLE_2D if (is2D()) { // compatibility with 2D - const unsigned cols = virtualWidth(); - const unsigned rows = virtualHeight(); - for (unsigned i = 0; i < rows; i++) blurRow(i, blur_amount, smear); // blur all rows - for (unsigned k = 0; k < cols; k++) blurCol(k, blur_amount, smear); // blur all columns + const uint_fast32_t cols = virtualWidth(); + const uint_fast32_t rows = virtualHeight(); + for (uint_fast32_t i = 0; i < rows; i++) blurRow(i, blur_amount, smear); // blur all rows + for (uint_fast32_t k = 0; k < cols; k++) blurCol(k, blur_amount, smear); // blur all columns return; } #endif @@ -1371,25 +1371,25 @@ void Segment::blur(uint8_t blur_amount, bool smear) { uint32_t carryover = BLACK; uint32_t lastnew; uint32_t last; - uint32_t curnew; + uint32_t curnew = 0; for (unsigned i = 0; i < vlength; i++) { uint32_t cur = getPixelColor(i); uint32_t part = color_fade(cur, seep); curnew = color_fade(cur, keep); if (i > 0) { if (carryover) - curnew = color_add(curnew, carryover, true); - uint32_t prev = color_add(lastnew, part, true); + curnew = color_add(curnew, carryover, !smear); // WLEDMM + uint32_t prev = color_add(lastnew, part, !smear); // WLEDMM if (last != prev) // optimization: only set pixel if color has changed - setPixelColor(i - 1, prev); + setPixelColor(int(i - 1), prev); } else // first pixel - setPixelColor(i, curnew); + setPixelColor(int(i), curnew); lastnew = curnew; last = cur; // save original value for comparison on next iteration carryover = part; } - setPixelColor(vlength - 1, curnew); + setPixelColor(int(vlength - 1), curnew); } /* diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 53e99d2d..6546043b 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -35,8 +35,11 @@ IRAM_ATTR_YN uint32_t color_blend(uint32_t color1, uint32_t color2, uint_fast16_ * color add function that preserves ratio * idea: https://github.com/Aircoookie/WLED/pull/2465 by https://github.com/Proto-molecule */ -IRAM_ATTR_YN uint32_t color_add(uint32_t c1, uint32_t c2) // WLEDMM added IRAM_ATTR_YN +IRAM_ATTR_YN uint32_t color_add(uint32_t c1, uint32_t c2, bool fast) // WLEDMM added IRAM_ATTR_YN { + if (c2 == 0) return c1; // WLEDMM shortcut + if (c1 == 0) return c2; // WLEDMM shortcut + if (fast) { uint8_t r = R(c1); uint8_t g = G(c1); @@ -52,7 +55,7 @@ IRAM_ATTR_YN uint32_t color_add(uint32_t c1, uint32_t c2) // WLEDMM added IRAM uint32_t g = G(c1) + G(c2); uint32_t b = B(c1) + B(c2); uint32_t w = W(c1) + W(c2); - uint_fast16_t max = r; + uint32_t max = r; if (g > max) max = g; if (b > max) max = b; if (w > max) max = w; @@ -66,8 +69,10 @@ IRAM_ATTR_YN uint32_t color_add(uint32_t c1, uint32_t c2) // WLEDMM added IRAM * if using "video" method the resulting color will never become black unless it is already black */ -uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) +IRAM_ATTR_YN uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) { + if (amount == 0) return 0; // WLEDMM shortcut + uint32_t scaledcolor; // color order is: W R G B from MSB to LSB uint32_t r = R(c1); uint32_t g = G(c1); @@ -78,7 +83,7 @@ uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) scaledcolor = (((r * scale) >> 8) << 16) + ((r && scale) ? 1 : 0); scaledcolor |= (((g * scale) >> 8) << 8) + ((g && scale) ? 1 : 0); scaledcolor |= ((b * scale) >> 8) + ((b && scale) ? 1 : 0); - scaledcolor |= (((w * scale) >> 8) << 24) + ((w && scale) ? 1 : 0); + if (w>0) scaledcolor |= (((w * scale) >> 8) << 24) + ((scale) ? 1 : 0); // WLEDMM small speedup when no white channel return scaledcolor; } else { @@ -86,7 +91,7 @@ uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) scaledcolor = ((r * scale) >> 8) << 16; scaledcolor |= ((g * scale) >> 8) << 8; scaledcolor |= (b * scale) >> 8; - scaledcolor |= ((w * scale) >> 8) << 24; + if (w>0) scaledcolor |= ((w * scale) >> 8) << 24; // WLEDMM small speedup when no white channel return scaledcolor; } } diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index e3473043..ff44bbd9 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -51,7 +51,8 @@ bool getJsonValue(const JsonVariant& element, DestType& destination, const Defau //colors.cpp uint32_t __attribute__((const)) color_blend(uint32_t,uint32_t,uint_fast16_t,bool b16=false); // WLEDMM: added attribute const -uint32_t __attribute__((const)) color_add(uint32_t,uint32_t); // WLEDMM: added attribute const +uint32_t __attribute__((const)) color_add(uint32_t,uint32_t, bool fast=false); // WLEDMM: added attribute const +uint32_t __attribute__((const)) color_fade(uint32_t c1, uint8_t amount, bool video=false); inline uint32_t colorFromRgbw(byte* rgbw) { return uint32_t((byte(rgbw[3]) << 24) | (byte(rgbw[0]) << 16) | (byte(rgbw[1]) << 8) | (byte(rgbw[2]))); } void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb void colorKtoRGB(uint16_t kelvin, byte* rgb); diff --git a/wled00/wled.h b/wled00/wled.h index 23321384..647bfb9c 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2404161 +#define VERSION 2404181 // WLEDMM - you can check for this define in usermods, to only enabled WLEDMM specific code in the "right" fork. Its not defined in AC WLED. #define _MoonModules_WLED_ From 0f677c35f58437e9fe000581c7e7aed8d98f024c Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 18 Apr 2024 21:09:28 +0200 Subject: [PATCH 5/9] typo --- usermods/audioreactive/audio_reactive.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index c3efd367..c67299e8 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -564,7 +564,7 @@ void FFTcode(void * parameter) newZeroCrossingCount++; } } - newZeroCrossingCount = (newZeroCrossingCount*2)/3; // reduce value so it typicially stays below 256 + newZeroCrossingCount = (newZeroCrossingCount*2)/3; // reduce value so it typically stays below 256 zeroCrossingCount = newZeroCrossingCount; // update only once, to avoid that effects pick up an intermediate value // release highest sample to volume reactive effects early - not strictly necessary here - could also be done at the end of the function From a5b07bc06d5c384b7ac343ce72db5b22f982a611 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 18 Apr 2024 22:36:50 +0200 Subject: [PATCH 6/9] bugfix for 2D Polar Lights on large setups (bigger than 32x32) the effect would only show a small horizontal line. --- wled00/FX.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index e18517f4..f241a457 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5645,6 +5645,8 @@ uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); + const float maxRows = (rows <= 32) ? 32.0f : (rows <= 64) ? 64.0f : 128.0f; // WLEDMM safe up to 128x128 + const float minScale = (rows <= 32) ? 12.0f : (rows <= 64) ? 4.6f : 2.1f; // WLEDMM const CRGBPalette16 auroraPalette = {0x000000, 0x003300, 0x006600, 0x009900, 0x00cc00, 0x00ff00, 0x33ff00, 0x66ff00, 0x99ff00, 0xccff00, 0xffff00, 0xffcc00, 0xff9900, 0xff6600, 0xff3300, 0xff0000}; @@ -5653,8 +5655,11 @@ uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https SEGMENT.fill(BLACK); } - float adjustHeight = mapf(rows, 8, 32, 28, 12); // maybe use mapf() ??? // WLEDMM yes! + float adjustHeight = mapf(rows, 8, maxRows, 28, minScale); // maybe use mapf() ??? // WLEDMM yes! uint16_t adjScale = map(cols, 8, 64, 310, 63); + + adjustHeight = max(min(adjustHeight, 28.0f), minScale); // WLEDMM bugfix for larger fixtures + adjScale = max(min(adjScale, uint16_t(310)), uint16_t(63)); // WLEDMM /* if (SEGENV.aux1 != SEGMENT.custom1/12) { // Hacky palette rotation. We need that black. SEGENV.aux1 = SEGMENT.custom1/12; From 34f4905e0b941c22f631d33dac95cd1f87987f71 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 18 Apr 2024 23:23:52 +0200 Subject: [PATCH 7/9] bugfix for 2D Sun Radiation size of the sun was very small on larger fixtures --- wled00/FX.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index f241a457..075a2ba9 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5818,6 +5818,8 @@ uint16_t mode_2DSunradiation(void) { // By: ldirko https://edi const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); + const int minSize = min(cols, rows); // WLEDMM + const int magnify = (minSize <= 32) ? 8 : 46; // WLEDMM if (!SEGENV.allocateData(sizeof(byte)*(cols+2)*(rows+2))) return mode_static(); //allocation failed byte *bump = reinterpret_cast(SEGENV.data); @@ -5846,10 +5848,10 @@ uint16_t mode_2DSunradiation(void) { // By: ldirko https://edi ++vlx; int8_t nx = bump[x + yindex + 1] - bump[x + yindex - 1]; int8_t ny = bump[x + yindex + (cols + 2)] - bump[x + yindex - (cols + 2)]; - byte difx = abs8(vlx * 7 - nx); - byte dify = abs8(vly * 7 - ny); + byte difx = min(abs(vlx * 7 - nx), 255); // WLEDMM replaced abs8 as it does not work for numbers >127 + byte dify = min(abs(vly * 7 - ny), 255); // WLEDMM int temp = difx * difx + dify * dify; - int col = 255 - temp / 8; //8 its a size of effect + int col = 255 - temp / magnify; //8 its a size of effect // WLEDMM size adjusts to matrix dimensions if (col < 0) col = 0; SEGMENT.setPixelColorXY(x, y, HeatColor(col / (3.0f-(float)(SEGMENT.intensity)/128.f))); } From 56cdfac0075ff2c8d32e9759a6126120d2b65cb4 Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:58:35 -0400 Subject: [PATCH 8/9] Added WMEDMM_SLOWPATH to force RMT for stability --- wled00/bus_wrapper.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index 5e41f263..fd7e7407 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -1179,14 +1179,22 @@ class PolyBus { #else // standard ESP32 has 8 RMT and 2 I2S channels #ifndef WLEDMM_FASTPATH - if (num > 9) return I_NONE; - if (num == 8) offset = 2; // first use I2S#1 (so #0 stays available for audio) - if (num == 9) offset = 1; // use I2S#0 as the last driver + #ifdef WLEDMM_SLOWPATH // I2S flickers on large installs. Favor stability over framerate. + if (num > 7) return I_NONE; + #else + if (num == 8) offset = 2; // first use I2S#1 (so #0 stays available for audio) + if (num == 9) offset = 1; // use I2S#0 as the last driver + if (num > 9) return I_NONE; + #endif #else // ESP32 "audio_fastpath" - 8 RMT and 1 I2S channels. RMT 5-8 have sending delays, so use I2S#1 before going for RMT 5-8 - if (num > 8) return I_NONE; - if (num == 1) offset = 2; // use I2S#1 as 2nd bus - seems to be a good compromise for performance, and reduces flickering for some users - //if (num == 0) offset = 2; // un-comment to use I2S#1 as 1st bus - sometimes helps, if you experience flickering during Wifi or filesystem activity. + #ifdef WLEDMM_SLOWPATH // I2S flickers on large installs. Favor stability over framerate. + if (num > 7) return I_NONE; + #else + if (num > 8) return I_NONE; + if (num == 1) offset = 2; // use I2S#1 as 2nd bus - seems to be a good compromise for performance, and reduces flickering for some users + // if (num == 0) offset = 2; // un-comment to use I2S#1 as 1st bus - sometimes helps, if you experience flickering during Wifi or filesystem activity. + #endif #endif #endif switch (busType) { From 4cbe92f55b04ab3810dea4bd415ead3fb0440edb Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:20:32 -0400 Subject: [PATCH 9/9] minor indent --- wled00/bus_wrapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index fd7e7407..ada486d5 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -1187,7 +1187,7 @@ class PolyBus { if (num > 9) return I_NONE; #endif #else - // ESP32 "audio_fastpath" - 8 RMT and 1 I2S channels. RMT 5-8 have sending delays, so use I2S#1 before going for RMT 5-8 + // ESP32 "audio_fastpath" - 8 RMT and 1 I2S channels. RMT 5-8 have sending delays, so use I2S#1 before going for RMT 5-8 #ifdef WLEDMM_SLOWPATH // I2S flickers on large installs. Favor stability over framerate. if (num > 7) return I_NONE; #else