From a75b3a53aadbcba8fe431e423059f0dfe0134238 Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Sun, 26 Jun 2022 23:01:22 +0200 Subject: [PATCH] Use getModeCount() instead of MODE_COUNT Clear strip if spacing changes. Rewrite 2DGEQ. --- wled00/FX.cpp | 279 +++++----------------------------------------- wled00/FX.h | 9 +- wled00/FX_fcn.cpp | 12 +- wled00/e131.cpp | 2 +- wled00/ir.cpp | 10 +- wled00/json.cpp | 6 +- wled00/util.cpp | 4 +- wled00/wled.h | 2 +- 8 files changed, 48 insertions(+), 276 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index bbf0f05f..4b506756 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -7392,31 +7392,26 @@ static const char *_data_FX_MODE_WATERFALL PROGMEM = " ♫ Waterfall@!,Adjust co ///////////////////////// // ** 2D GEQ // ///////////////////////// -//NOTE: centering is obsolete by using mirroring on the segment level -uint16_t WS2812FX::GEQ_base(bool centered_horizontal, bool centered_vertical, bool color_vertical) { // By Will Tatam. Refactor by Ewoud Wijma. +uint16_t WS2812FX::mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. if (!isMatrix) return mode_static(); // not a 2D set-up + const int NUM_BANDS = map(SEGMENT.custom1, 0, 255, 1, 16); const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - const uint16_t dataSize = sizeof(CRGB) * SEGMENT.width() * SEGMENT.height(); // using width*height prevents reallocation if mirroring is enabled - if (!SEGENV.allocateData(dataSize + cols*sizeof(uint16_t))) return mode_static(); //allocation failed - CRGB *leds = reinterpret_cast(SEGENV.data); - uint16_t *previousBarHeight = reinterpret_cast(SEGENV.data + dataSize); + if (!SEGENV.allocateData(cols*sizeof(uint16_t))) return mode_static(); //allocation failed + uint16_t *previousBarHeight = reinterpret_cast(SEGENV.data); //array of previous bar heights per frequency band - uint8_t *fftResult = nullptr; + uint8_t *fftResult = nullptr; um_data_t *um_data; if (usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { - fftResult = (uint8_t*)um_data->u_data[8]; + fftResult = (uint8_t*)um_data->u_data[8]; } else { // add support for no audio data } if (!fftResult) return mode_static(); - //static int previousBarHeight[64]; //array of previous bar heights per frequency band - if (SEGENV.call == 0) for (uint16_t i=0; i>2)); + if (SEGENV.call == 0) for (int i=0; i= (256 - SEGMENT.intensity)) { @@ -7424,59 +7419,31 @@ uint16_t WS2812FX::GEQ_base(bool centered_horizontal, bool centered_vertical, bo rippleTime = true; } - uint16_t xCount = cols; - if (centered_vertical) xCount /= 2; + fadeToBlackBy(nullptr, 128+(SEGMENT.speed>>2)); - for (uint16_t x=0; x < xCount; x++) { - uint8_t band = map(x, 0, xCount-1, 0, 15); - uint16_t barHeight = map(fftResult[band], 0, 255, 0, rows-1); + for (int x=0; x < cols; x++) { + uint8_t band = map(x, 0, cols-1, 0, NUM_BANDS - 1); + uint16_t colorIndex = band * 17; + uint16_t barHeight = map(fftResult[band], 0, 255, 0, rows); // do not subtract -1 from rows here if (barHeight > previousBarHeight[x]) previousBarHeight[x] = barHeight; //drive the peak up - if (centered_horizontal) barHeight += barHeight%2; //get an even barHeight if centered_horizontal - uint16_t yStartBar = centered_horizontal ? (rows - barHeight - 1) / 2 : 0; //lift up the bar if centered_horizontal - uint16_t yStartPeak = centered_horizontal ? (rows - previousBarHeight[x] - 1) / 2 : 0; //lift up the peaks if centered_horizontal + uint32_t ledColor = BLACK; + for (int y=0; y < barHeight; y++) { + if (SEGMENT.custom2 > 128) //color_vertical / color bars toggle + colorIndex = map(y, 0, rows-1, 0, 255); - for (uint16_t y=0; y < rows; y++) { - uint16_t colorIndex; - if (color_vertical) { - if (centered_horizontal) - colorIndex = map(abs(y - (rows - 1)/2), 0, (rows-1)/2, 0, 255); - else - colorIndex = map(y, 0, rows - 1, 0, 255); - } else - colorIndex = band * 17; - - CRGB heightColor = color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0); - CRGB ledColor = CRGB::Black; //if not part of bars or peak, make black (not fade to black) - - //bar - if (y >= yStartBar && y < yStartBar + barHeight) - ledColor = heightColor; - - //low and high peak (must exist && on peak position && only below if centered_horizontal effect) - //bool isYPeak = (centered_horizontal && y==yStartPeak) || y==(yStartPeak + previousBarHeight[x]); - bool isYPeak = (y==yStartPeak || y==yStartPeak + previousBarHeight[x]-1) && (centered_horizontal || y!=yStartPeak); - if ((previousBarHeight[x] > 0) && isYPeak) - ledColor = SEGCOLOR(2)==CRGB::Black ? heightColor : CRGB(SEGCOLOR(2)); //low peak - - if (centered_vertical) { - leds[XY(cols / 2 + x, rows - 1 - y)] += ledColor; - leds[XY(cols / 2 - 1 - x, rows - 1 - y)] += ledColor; - } else - leds[XY(x, rows - 1 - y)] += ledColor; + ledColor = color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0); + setPixelColorXY(x, rows-1 - y, ledColor); } + if (previousBarHeight[x] > 0) + setPixelColorXY(x, rows - previousBarHeight[x], (SEGCOLOR(2) != BLACK) ? SEGCOLOR(2) : ledColor); - if (rippleTime && previousBarHeight[x]>centered_horizontal) previousBarHeight[x] -= centered_horizontal + 1; //delay/ripple effect + if (rippleTime && previousBarHeight[x]>0) previousBarHeight[x]--; //delay/ripple effect } - setPixels(leds); return FRAMETIME; -} //GEQ_base - -uint16_t WS2812FX::mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. - return GEQ_base(false, false, SEGMENT.custom3 > 128); } // mode_2DGEQ() -static const char *_data_FX_MODE_2DGEQ PROGMEM = " ♫ 2D GEQ@Bar speed,Ripple decay,,Color bars=0;!,,Peak Color;!=11"; +static const char *_data_FX_MODE_2DGEQ PROGMEM = " ♫ 2D GEQ@Fade speed,Ripple decay,# of bands=255,Color bars=64;!,,Peak Color;!=11"; ///////////////////////// @@ -7484,9 +7451,9 @@ static const char *_data_FX_MODE_2DGEQ PROGMEM = " ♫ 2D GEQ@Bar speed,Ripple d ///////////////////////// // NOTE: obsolete! uint16_t WS2812FX::mode_2DCenterBars(void) { // Written by Scott Marley Adapted by Spiro-C.. - return GEQ_base(SEGMENT.custom1 > 128, SEGMENT.custom2 > 128, SEGMENT.custom3 > 128); + return mode_2DGEQ(); } // mode_2DCenterBars() -static const char *_data_FX_MODE_2DCENTERBARS PROGMEM = " ♫ 2D CenterBars@Bar speed=250,Ripple decay=250,Center ↔ ☑=192,Center ↕ ☑=192, Color ↕ ☑=192;!,,Peak Color;!=11"; +static const char *_data_FX_MODE_2DCENTERBARS PROGMEM = " ♫ 2D CenterBars@Bar speed,Ripple decay,# of bands=255,Color bars=64;!,,Peak Color;!=11"; ///////////////////////// @@ -7663,7 +7630,7 @@ static const char *_data_FX_MODE_2DAKEMI PROGMEM = "2D Akemi@Color speed,Dance;H static const char *_data_RESERVED PROGMEM = "Reserved"; void WS2812FX::setupEffectData() { // fill reserved word in case there will be any gaps in the array - for (byte i=0; i= MAX_NUM_SEGMENTS) return; - if (m >= MODE_COUNT) m = MODE_COUNT - 1; + if (m >= getModeCount()) m = getModeCount() - 1; if (_segments[segid].mode != m) { @@ -420,11 +420,6 @@ void WS2812FX::setMode(uint8_t segid, uint8_t m) { } } -uint8_t WS2812FX::getModeCount() -{ - return MODE_COUNT; -} - uint8_t WS2812FX::getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; @@ -937,13 +932,16 @@ uint32_t WS2812FX::color_add(uint32_t c1, uint32_t c2) /* * Fills segment with color */ -void WS2812FX::fill(uint32_t c) { +void WS2812FX::fill(uint32_t c, uint8_t seg) { + uint8_t oldSeg; + if (seg != 255) oldSeg = setPixelSegment(seg); const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); const uint16_t rows = SEGMENT.virtualHeight(); // will be 1 for 1D for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { if (isMatrix) setPixelColorXY(x, y, c); else setPixelColor(x, c); } + if (seg != 255) setPixelSegment(oldSeg); } /* diff --git a/wled00/e131.cpp b/wled00/e131.cpp index 08193946..73589dc4 100644 --- a/wled00/e131.cpp +++ b/wled00/e131.cpp @@ -154,7 +154,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol){ DMXOldDimmer = e131_data[dataOffset+0]; bri = e131_data[dataOffset+0]; } - if (e131_data[dataOffset+1] < MODE_COUNT) + if (e131_data[dataOffset+1] < strip.getModeCount()) effectCurrent = e131_data[dataOffset+ 1]; effectSpeed = e131_data[dataOffset+ 2]; // flickers effectIntensity = e131_data[dataOffset+ 3]; diff --git a/wled00/ir.cpp b/wled00/ir.cpp index 9222845b..7937bee2 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -502,8 +502,8 @@ void decodeIR44(uint32_t code) case IR44_WARMWHITE : changeColor(COLOR_WARMWHITE, 63); changeEffect(FX_MODE_STATIC); break; case IR44_COLDWHITE : changeColor(COLOR_COLDWHITE, 191); changeEffect(FX_MODE_STATIC); break; case IR44_COLDWHITE2 : changeColor(COLOR_COLDWHITE2, 255); changeEffect(FX_MODE_STATIC); break; - case IR44_REDPLUS : changeEffect(relativeChange(effectCurrent, 1, 0, MODE_COUNT -1)); break; - case IR44_REDMINUS : changeEffect(relativeChange(effectCurrent, -1, 0, MODE_COUNT -1)); break; + case IR44_REDPLUS : changeEffect(relativeChange(effectCurrent, 1, 0, strip.getModeCount() -1)); break; + case IR44_REDMINUS : changeEffect(relativeChange(effectCurrent, -1, 0, strip.getModeCount() -1)); break; case IR44_GREENPLUS : changePalette(relativeChange(effectPalette, 1, 0, strip.getPaletteCount() -1)); break; case IR44_GREENMINUS : changePalette(relativeChange(effectPalette, -1, 0, strip.getPaletteCount() -1)); break; case IR44_BLUEPLUS : changeEffectIntensity( 16); break; @@ -562,7 +562,7 @@ void decodeIR6(uint32_t code) case IR6_POWER: toggleOnOff(); break; case IR6_CHANNEL_UP: incBrightness(); break; case IR6_CHANNEL_DOWN: decBrightness(); break; - case IR6_VOLUME_UP: changeEffect(relativeChange(effectCurrent, 1, 0, MODE_COUNT -1)); break; + case IR6_VOLUME_UP: changeEffect(relativeChange(effectCurrent, 1, 0, strip.getModeCount() -1)); break; case IR6_VOLUME_DOWN: changePalette(relativeChange(effectPalette, 1, 0, strip.getPaletteCount() -1)); switch(lastIR6ColourIdx) { case 0: changeColor(COLOR_RED); break; @@ -600,7 +600,7 @@ void decodeIR9(uint32_t code) case IR9_DOWN : decBrightness(); break; case IR9_LEFT : changeEffectSpeed(-16); break; case IR9_RIGHT : changeEffectSpeed(16); break; - case IR9_SELECT : changeEffect(relativeChange(effectCurrent, 1, 0, MODE_COUNT -1)); break; + case IR9_SELECT : changeEffect(relativeChange(effectCurrent, 1, 0, strip.getModeCount() -1)); break; default: return; } lastValidCode = code; @@ -670,7 +670,7 @@ void decodeIRJson(uint32_t code) decBrightness(); } else if (cmdStr.startsWith(F("!presetF"))) { //!presetFallback uint8_t p1 = fdo["PL"] | 1; - uint8_t p2 = fdo["FX"] | random8(MODE_COUNT -1); + uint8_t p2 = fdo["FX"] | random8(strip.getModeCount() -1); uint8_t p3 = fdo["FP"] | 0; presetFallback(p1, p2, p3); } diff --git a/wled00/json.cpp b/wled00/json.cpp index 725a6f81..9ce83b38 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -72,6 +72,8 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) uint16_t spc = elem[F("spc")] | seg.spacing; uint16_t of = seg.offset; + if (spc>0 && spc!=seg.spacing) strip.fill(BLACK, id); // clear spacing gaps + uint16_t len = 1; if (stop > start) len = stop - start; int offset = elem[F("of")] | INT32_MAX; @@ -829,7 +831,7 @@ void serializeNodes(JsonObject root) void serializeModeData(JsonArray fxdata) { - for (size_t i = 0; i < MODE_COUNT; i++) { + for (size_t i = 0; i < strip.getModeCount(); i++) { //String lineBuffer = (const char*)pgm_read_dword(&(WS2812FX::_modeData[i])); String lineBuffer = strip.getModeData(i); if (lineBuffer.length() > 0) { @@ -843,7 +845,7 @@ void serializeModeData(JsonArray fxdata) // deserializes mode names string into JsonArray // also removes WLED-SR extensions (@...) from deserialised names void serializeModeNames(JsonArray arr) { - for (size_t i = 0; i < MODE_COUNT; i++) { + for (size_t i = 0; i < strip.getModeCount(); i++) { //String lineBuffer = (const char*)pgm_read_dword(&(WS2812FX::_modeData[i])); String lineBuffer = strip.getModeData(i); if (lineBuffer.length() > 0) { diff --git a/wled00/util.cpp b/wled00/util.cpp index 80ca9267..6900c88c 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -234,7 +234,7 @@ void releaseJSONBufferLock() uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLen) { if (src == JSON_mode_names || src == nullptr) { - if (mode < MODE_COUNT) { + if (mode < strip.getModeCount()) { char lineBuffer[256]; //strcpy_P(lineBuffer, (const char*)pgm_read_dword(&(WS2812FX::_modeData[mode]))); strcpy_P(lineBuffer, strip.getModeData(mode)); @@ -286,7 +286,7 @@ uint8_t extractModeSlider(uint8_t mode, uint8_t slider, char *dest, uint8_t maxL { dest[0] = '\0'; // start by clearing buffer - if (mode < MODE_COUNT) { + if (mode < strip.getModeCount()) { String lineBuffer = strip.getModeData(mode); if (lineBuffer.length() > 0) { int16_t start = lineBuffer.indexOf('@'); diff --git a/wled00/wled.h b/wled00/wled.h index e712c12d..1f77ca57 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2206232 +#define VERSION 2206261 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG