diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 5e43430aef..da7b0c4ba5 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -642,11 +642,12 @@ static const char _data_FX_MODE_TWINKLE[] PROGMEM = "Twinkle@!,!;!,!;!;;m12=0"; * Dissolve function */ uint16_t dissolve(uint32_t color) { - unsigned dataSize = (SEGLEN+7) >> 3; //1 bit per LED + unsigned dataSize = sizeof(uint32_t) * SEGLEN; if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + uint32_t* pixels = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - memset(SEGMENT.data, 0xFF, dataSize); // start by fading pixels up + for (unsigned i = 0; i < SEGLEN; i++) pixels[i] = SEGCOLOR(1); SEGENV.aux0 = 1; } @@ -654,33 +655,26 @@ uint16_t dissolve(uint32_t color) { if (hw_random8() <= SEGMENT.intensity) { for (size_t times = 0; times < 10; times++) { //attempt to spawn a new pixel 10 times unsigned i = hw_random16(SEGLEN); - unsigned index = i >> 3; - unsigned bitNum = i & 0x07; - bool fadeUp = bitRead(SEGENV.data[index], bitNum); if (SEGENV.aux0) { //dissolve to primary/palette - if (fadeUp) { - if (color == SEGCOLOR(0)) { - SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); - } else { - SEGMENT.setPixelColor(i, color); - } - bitWrite(SEGENV.data[index], bitNum, false); + if (pixels[i] == SEGCOLOR(1)) { + pixels[i] = color == SEGCOLOR(0) ? SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0) : color; break; //only spawn 1 new pixel per frame per 50 LEDs } } else { //dissolve to secondary - if (!fadeUp) { - SEGMENT.setPixelColor(i, SEGCOLOR(1)); break; - bitWrite(SEGENV.data[index], bitNum, true); + if (pixels[i] != SEGCOLOR(1)) { + pixels[i] = SEGCOLOR(1); + break; } } } } } + // fix for #4401 + for (unsigned i = 0; i < SEGLEN; i++) SEGMENT.setPixelColor(i, pixels[i]); if (SEGENV.step > (255 - SEGMENT.speed) + 15U) { SEGENV.aux0 = !SEGENV.aux0; SEGENV.step = 0; - memset(SEGMENT.data, (SEGENV.aux0 ? 0xFF : 0), dataSize); // switch fading } else { SEGENV.step++; } @@ -6568,23 +6562,31 @@ static const char _data_FX_MODE_JUGGLES[] PROGMEM = "Juggles@!,# of balls;!,!;!; // * MATRIPIX // ////////////////////// uint16_t mode_matripix(void) { // Matripix. By Andrew Tuline. - if (SEGLEN == 1) return mode_static(); - // even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment + // effect can work on single pixels, we just lose the shifting effect + unsigned dataSize = sizeof(uint32_t) * SEGLEN; + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + uint32_t* pixels = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); int volumeRaw = *(int16_t*)um_data->u_data[1]; if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); + for (unsigned i = 0; i < SEGLEN; i++) pixels[i] = BLACK; // may not be needed as resetIfRequired() clears buffer } uint8_t secondHand = micros()/(256-SEGMENT.speed)/500 % 16; if(SEGENV.aux0 != secondHand) { SEGENV.aux0 = secondHand; - uint8_t pixBri = volumeRaw * SEGMENT.intensity / 64; - for (unsigned i = 0; i < SEGLEN-1; i++) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // shift left - SEGMENT.setPixelColor(SEGLEN-1, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(strip.now, false, PALETTE_SOLID_WRAP, 0), pixBri)); + int pixBri = volumeRaw * SEGMENT.intensity / 64; + unsigned k = SEGLEN-1; + // loop will not execute if SEGLEN equals 1 + for (unsigned i = 0; i < k; i++) { + pixels[i] = pixels[i+1]; // shift left + SEGMENT.setPixelColor(i, pixels[i]); + } + pixels[k] = color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(strip.now, false, PALETTE_SOLID_WRAP, 0), pixBri); + SEGMENT.setPixelColor(k, pixels[k]); } return FRAMETIME; @@ -7139,8 +7141,11 @@ static const char _data_FX_MODE_ROCKTAVES[] PROGMEM = "Rocktaves@;!,!;!;01f;m12= // Combines peak detection with FFT_MajorPeak and FFT_Magnitude. uint16_t mode_waterfall(void) { // Waterfall. By: Andrew Tuline // effect can work on single pixels, we just lose the shifting effect - - um_data_t *um_data = getAudioData(); + unsigned dataSize = sizeof(uint32_t) * SEGLEN; + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + uint32_t* pixels = reinterpret_cast(SEGENV.data); + + um_data_t *um_data = getAudioData(); uint8_t samplePeak = *(uint8_t*)um_data->u_data[3]; float FFT_MajorPeak = *(float*) um_data->u_data[4]; uint8_t *maxVol = (uint8_t*)um_data->u_data[6]; @@ -7150,7 +7155,7 @@ uint16_t mode_waterfall(void) { // Waterfall. By: Andrew Tulin if (FFT_MajorPeak < 1) FFT_MajorPeak = 1; // log10(0) is "forbidden" (throws exception) if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); + for (unsigned i = 0; i < SEGLEN; i++) pixels[i] = BLACK; // may not be needed as resetIfRequired() clears buffer SEGENV.aux0 = 255; SEGMENT.custom1 = *binNum; SEGMENT.custom2 = *maxVol * 2; @@ -7167,13 +7172,18 @@ uint16_t mode_waterfall(void) { // Waterfall. By: Andrew Tulin uint8_t pixCol = (log10f(FFT_MajorPeak) - 2.26f) * 150; // 22Khz sampling - log10 frequency range is from 2.26 (182hz) to 3.967 (9260hz). Let's scale accordingly. if (FFT_MajorPeak < 182.0f) pixCol = 0; // handle underflow + unsigned k = SEGLEN-1; if (samplePeak) { - SEGMENT.setPixelColor(SEGLEN-1, CHSV(92,92,92)); + pixels[k] = (uint32_t)CRGB(CHSV(92,92,92)); } else { - SEGMENT.setPixelColor(SEGLEN-1, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(pixCol+SEGMENT.intensity, false, PALETTE_SOLID_WRAP, 0), (uint8_t)my_magnitude)); + pixels[k] = color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(pixCol+SEGMENT.intensity, false, PALETTE_SOLID_WRAP, 0), (uint8_t)my_magnitude); } + SEGMENT.setPixelColor(k, pixels[k]); // loop will not execute if SEGLEN equals 1 - for (unsigned i = 0; i < SEGLEN-1; i++) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // shift left + for (unsigned i = 0; i < k; i++) { + pixels[i] = pixels[i+1]; // shift left + SEGMENT.setPixelColor(i, pixels[i]); + } } return FRAMETIME; diff --git a/wled00/led.cpp b/wled00/led.cpp index 68169509da..8b34bbf0ca 100644 --- a/wled00/led.cpp +++ b/wled00/led.cpp @@ -73,8 +73,7 @@ byte scaledBri(byte in) //applies global brightness void applyBri() { - if (!realtimeMode || !arlsForceMaxBri) - { + if (!(realtimeMode && arlsForceMaxBri)) { //DEBUG_PRINTF_P(PSTR("Applying strip brightness: %d (%d,%d)\n"), (int)briT, (int)bri, (int)briOld); strip.setBrightness(scaledBri(briT)); } @@ -86,6 +85,7 @@ void applyFinalBri() { briOld = bri; briT = bri; applyBri(); + strip.trigger(); } @@ -146,7 +146,6 @@ void stateUpdated(byte callMode) { transitionStartTime = millis(); } else { applyFinalBri(); - strip.trigger(); } }