Skip to content

Full fastled replacement #4615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ upload_speed = 115200
# ------------------------------------------------------------------------------
lib_compat_mode = strict
lib_deps =
fastled/FastLED @ 3.6.0
IRremoteESP8266 @ 2.8.2
makuna/NeoPixelBus @ 2.8.3
#https://github.com./makuna/NeoPixelBus.git#CoreShaderBeta
Expand Down Expand Up @@ -225,7 +224,6 @@ lib_deps_compat =
ESPAsyncTCP @ 1.2.2
ESPAsyncUDP
ESP8266PWM
fastled/FastLED @ 3.6.0
IRremoteESP8266 @ 2.8.2
makuna/NeoPixelBus @ 2.7.9
https://github.com./blazoncek/QuickESPNow.git#optional-debug
Expand Down
2 changes: 1 addition & 1 deletion usermods/Analog_Clock/Analog_Clock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class AnalogClockUsermod : public Usermod {
);
}

static inline uint32_t scale32(uint32_t c, fract8 scale) {
static inline uint32_t scale32(uint32_t c, uint8_t scale) {
return RGBW32(
scale8(R(c), scale),
scale8(G(c), scale),
Expand Down
4 changes: 2 additions & 2 deletions usermods/audioreactive/audio_reactive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1994,12 +1994,12 @@ CRGB AudioReactive::getCRGBForBand(int x, int pal) {
case 2:
b = map(x, 0, 255, 0, NUM_GEQ_CHANNELS/2); // convert palette position to lower half of freq band
hsv = CHSV(fftResult[b], 255, x);
hsv2rgb_rainbow(hsv, value); // convert to R,G,B
value = hsv; // convert to R,G,B
break;
case 1:
b = map(x, 1, 255, 0, 10); // convert palette position to lower half of freq band
hsv = CHSV(fftResult[b], 255, map(fftResult[b], 0, 255, 30, 255)); // pick hue
hsv2rgb_rainbow(hsv, value); // convert to R,G,B
value = hsv; // convert to R,G,B
break;
default:
if (x == 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ class RotaryEncoderBrightnessColor : public Usermod
fastled_col.red = colPri[0];
fastled_col.green = colPri[1];
fastled_col.blue = colPri[2];
prim_hsv = rgb2hsv_approximate(fastled_col);
prim_hsv = rgb2hsv(fastled_col);
new_val = (int16_t)prim_hsv.h + fadeAmount;
if (new_val > 255)
new_val -= 255; // roll-over if bigger than 255
if (new_val < 0)
new_val += 255; // roll-over if smaller than 0
prim_hsv.h = (byte)new_val;
hsv2rgb_rainbow(prim_hsv, fastled_col);
fastled_col = prim_hsv ;
colPri[0] = fastled_col.red;
colPri[1] = fastled_col.green;
colPri[2] = fastled_col.blue;
Expand All @@ -121,14 +121,14 @@ class RotaryEncoderBrightnessColor : public Usermod
fastled_col.red = colPri[0];
fastled_col.green = colPri[1];
fastled_col.blue = colPri[2];
prim_hsv = rgb2hsv_approximate(fastled_col);
prim_hsv = rgb2hsv(fastled_col);
new_val = (int16_t)prim_hsv.h - fadeAmount;
if (new_val > 255)
new_val -= 255; // roll-over if bigger than 255
if (new_val < 0)
new_val += 255; // roll-over if smaller than 0
prim_hsv.h = (byte)new_val;
hsv2rgb_rainbow(prim_hsv, fastled_col);
fastled_col = prim_hsv;
colPri[0] = fastled_col.red;
colPri[1] = fastled_col.green;
colPri[2] = fastled_col.blue;
Expand Down
90 changes: 45 additions & 45 deletions wled00/FX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "wled.h"
#include "FX.h"
#include "fcn_declare.h"
#include "colors.h"
#include "prng.h"

#if !(defined(WLED_DISABLE_PARTICLESYSTEM2D) && defined(WLED_DISABLE_PARTICLESYSTEM1D))
#include "FXparticleSystem.h"
Expand Down Expand Up @@ -68,17 +70,14 @@
//#define MAX_FREQUENCY 5120
//#define MAX_FREQ_LOG10 3.71f

static PRNG prng(hw_random()); // pseudo-random number generator class, seed = hardware random number

// effect utility functions
uint8_t sin_gap(uint16_t in) {
if (in & 0x100) return 0;
return sin8_t(in + 192); // correct phase shift of sine so that it starts and stops at 0
}

uint16_t triwave16(uint16_t in) {
if (in < 0x8000) return in *2;
return 0xFFFF - (in - 0x8000)*2;
}

/*
* Generates a tristate square wave w/ attac & decay
* @param x input value 0-255
Expand Down Expand Up @@ -1759,30 +1758,30 @@ static const char _data_FX_MODE_MULTI_COMET[] PROGMEM = "Multi Comet@!,Fade;!,!;
*/
uint16_t mode_random_chase(void) {
if (SEGENV.call == 0) {
SEGENV.step = RGBW32(random8(), random8(), random8(), 0);
SEGENV.aux0 = random16();
SEGENV.step = RGBW32(prng.random8(), prng.random8(), prng.random8(), 0);
SEGENV.aux0 = prng.random16();
}
unsigned prevSeed = random16_get_seed(); // save seed so we can restore it at the end of the function
unsigned prevSeed = prng.getSeed(); // save seed so we can restore it at the end of the function
uint32_t cycleTime = 25 + (3 * (uint32_t)(255 - SEGMENT.speed));
uint32_t it = strip.now / cycleTime;
uint32_t color = SEGENV.step;
random16_set_seed(SEGENV.aux0);
prng.setSeed(SEGENV.aux0);

for (int i = SEGLEN -1; i >= 0; i--) {
uint8_t r = random8(6) != 0 ? (color >> 16 & 0xFF) : random8();
uint8_t g = random8(6) != 0 ? (color >> 8 & 0xFF) : random8();
uint8_t b = random8(6) != 0 ? (color & 0xFF) : random8();
uint8_t r = prng.random8(6) != 0 ? (color >> 16 & 0xFF) : prng.random8();
uint8_t g = prng.random8(6) != 0 ? (color >> 8 & 0xFF) : prng.random8();
uint8_t b = prng.random8(6) != 0 ? (color & 0xFF) : prng.random8();
color = RGBW32(r, g, b, 0);
SEGMENT.setPixelColor(i, color);
if (i == SEGLEN -1U && SEGENV.aux1 != (it & 0xFFFFU)) { //new first color in next frame
SEGENV.step = color;
SEGENV.aux0 = random16_get_seed();
SEGENV.aux0 = prng.getSeed();
}
}

SEGENV.aux1 = it & 0xFFFF;

random16_set_seed(prevSeed); // restore original seed so other effects can use "random" PRNG
prng.setSeed(prevSeed); // restore original seed so other effects can use "random" PRNG
return FRAMETIME;
}
static const char _data_FX_MODE_RANDOM_CHASE[] PROGMEM = "Stream 2@!;;";
Expand Down Expand Up @@ -2270,8 +2269,8 @@ uint16_t mode_colortwinkle() {
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed

CRGBW col, prev;
fract8 fadeUpAmount = strip.getBrightness()>28 ? 8 + (SEGMENT.speed>>2) : 68-strip.getBrightness();
fract8 fadeDownAmount = strip.getBrightness()>28 ? 8 + (SEGMENT.speed>>3) : 68-strip.getBrightness();
uint8_t fadeUpAmount = strip.getBrightness()>28 ? 8 + (SEGMENT.speed>>2) : 68-strip.getBrightness();
uint8_t fadeDownAmount = strip.getBrightness()>28 ? 8 + (SEGMENT.speed>>3) : 68-strip.getBrightness();
for (unsigned i = 0; i < SEGLEN; i++) {
CRGBW cur = SEGMENT.getPixelColor(i);
prev = cur;
Expand Down Expand Up @@ -2545,7 +2544,7 @@ static const char _data_FX_MODE_RIPPLE_RAINBOW[] PROGMEM = "Ripple Rainbow@!,Wav
//
// TwinkleFOX: Twinkling 'holiday' lights that fade in and out.
// Colors are chosen from a palette. Read more about this effect using the link above!
static CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
static CRGBW twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
{
// Overall twinkle speed (changed)
unsigned ticks = ms / SEGENV.aux0;
Expand Down Expand Up @@ -2580,7 +2579,7 @@ static CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
}

unsigned hue = slowcycle8 - salt;
CRGB c;
CRGBW c;
if (bright > 0) {
c = ColorFromPalette(SEGPALETTE, hue, bright, NOBLEND);
if (!SEGMENT.check1) {
Expand All @@ -2595,7 +2594,7 @@ static CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
}
}
} else {
c = CRGB::Black;
c = 0; // black
}
return c;
}
Expand All @@ -2618,14 +2617,14 @@ static uint16_t twinklefox_base(bool cat)
else SEGENV.aux0 = 22 + ((100 - SEGMENT.speed) >> 1);

// Set up the background color, "bg".
CRGB bg = CRGB(SEGCOLOR(1));
CRGBW bg = SEGCOLOR(1);
unsigned bglight = bg.getAverageLight();
if (bglight > 64) {
bg.nscale8_video(16); // very bright, so scale to 1/16th
bg = color_fade(bg, 16, true); // very bright, so scale to 1/16th
} else if (bglight > 16) {
bg.nscale8_video(64); // not that bright, so scale to 1/4th
bg = color_fade(bg, 64, true); // not that bright, so scale to 1/4th
} else {
bg.nscale8_video(86); // dim, scale to 1/3rd.
bg = color_fade(bg, 86, true); // dim, scale to 1/3rd.
}

unsigned backgroundBrightness = bg.getAverageLight();
Expand All @@ -2643,18 +2642,18 @@ static uint16_t twinklefox_base(bool cat)
// We now have the adjusted 'clock' for this pixel, now we call
// the function that computes what color the pixel should be based
// on the "brightness = f( time )" idea.
CRGB c = twinklefox_one_twinkle(myclock30, myunique8, cat);
CRGBW c = twinklefox_one_twinkle(myclock30, myunique8, cat);

unsigned cbright = c.getAverageLight();
int deltabright = cbright - backgroundBrightness;
if (deltabright >= 32 || (!bg)) {
if (deltabright >= 32 || (bg==0)) {
// If the new pixel is significantly brighter than the background color,
// use the new color.
SEGMENT.setPixelColor(i, c);
} else if (deltabright > 0) {
// If the new pixel is just slightly brighter than the background color,
// mix a blend of the new color and the background color
SEGMENT.setPixelColor(i, color_blend(RGBW32(bg.r,bg.g,bg.b,0), RGBW32(c.r,c.g,c.b,0), uint8_t(deltabright * 8)));
SEGMENT.setPixelColor(i, color_blend(bg, c, uint8_t(deltabright * 8)));
} else {
// if the new pixel is not at all brighter than the background color,
// just use the background color.
Expand Down Expand Up @@ -4146,17 +4145,17 @@ static const char _data_FX_MODE_PHASEDNOISE[] PROGMEM = "Phased Noise@!,!;!,!;!"


uint16_t mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline.
unsigned prevSeed = random16_get_seed(); // save seed so we can restore it at the end of the function
random16_set_seed(535); // The randomizer needs to be re-set each time through the loop in order for the same 'random' numbers to be the same each time through.
unsigned prevSeed = prng.getSeed(); // save seed so we can restore it at the end of the function
prng.setSeed(535); // The randomizer needs to be re-set each time through the loop in order for the same 'random' numbers to be the same each time through.

for (unsigned i = 0; i < SEGLEN; i++) {
unsigned ranstart = random8(); // The starting value (aka brightness) for each pixel. Must be consistent each time through the loop for this to work.
unsigned ranstart = prng.random8(); // The starting value (aka brightness) for each pixel. Must be consistent each time through the loop for this to work.
unsigned pixBri = sin8_t(ranstart + 16 * strip.now/(256-SEGMENT.speed));
if (random8() > SEGMENT.intensity) pixBri = 0;
SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(random8()+strip.now/100, false, PALETTE_SOLID_WRAP, 0), pixBri));
if (prng.random8() > SEGMENT.intensity) pixBri = 0;
SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(prng.random8()+strip.now/100, false, PALETTE_SOLID_WRAP, 0), pixBri));
}

random16_set_seed(prevSeed); // restore original seed so other effects can use "random" PRNG
prng.setSeed(prevSeed); // restore original seed so other effects can use "random" PRNG
return FRAMETIME;
}
static const char _data_FX_MODE_TWINKLEUP[] PROGMEM = "Twinkleup@!,Intensity;!,!;!;;m12=0";
Expand All @@ -4178,6 +4177,7 @@ uint16_t mode_noisepal(void) { // Slow noise
SEGENV.step = strip.now;

unsigned baseI = hw_random8();
//palettes[1] = CRGBPalette16(CHSV(baseI+hw_random8(64), 255, hw_random8(128,255)), CHSV(baseI+128, 255, hw_random8(128,255)), CHSV(baseI+hw_random8(92), 192, hw_random8(128,255)), CHSV(baseI+hw_random8(92), 255, hw_random8(128,255)));
palettes[1] = CRGBPalette16(CHSV(baseI+hw_random8(64), 255, hw_random8(128,255)), CHSV(baseI+128, 255, hw_random8(128,255)), CHSV(baseI+hw_random8(92), 192, hw_random8(128,255)), CHSV(baseI+hw_random8(92), 255, hw_random8(128,255)));
}

Expand Down Expand Up @@ -4921,7 +4921,7 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
uint8_t rate = j * 255 / steps;
byte dx = lerp8by8(x1, y1, rate);
byte dy = lerp8by8(x2, y2, rate);
//SEGMENT.setPixelColorXY(dx, dy, grad ? color.nscale8_video(255-rate) : color); // use addPixelColorXY for different look
//SEGMENT.setPixelColorXY(dx, dy, grad ? color_fade(color, (255-rate), true) : color); // use addPixelColorXY for different look
SEGMENT.addPixelColorXY(dx, dy, color); // use setPixelColorXY for different look
if (grad) SEGMENT.fadePixelColorXY(dx, dy, rate);
}
Expand Down Expand Up @@ -5696,8 +5696,7 @@ uint16_t mode_2DSunradiation(void) { // By: ldirko https://edi
uint8_t someVal = SEGMENT.speed/4; // Was 25.
for (int j = 0; j < (rows + 2); j++) {
for (int i = 0; i < (cols + 2); i++) {
//byte col = (inoise8_raw(i * someVal, j * someVal, t)) / 2;
byte col = ((int16_t)perlin8(i * someVal, j * someVal, t) - 0x7F) / 3;
byte col = ((int16_t)perlin8(i * someVal, j * someVal, t) - 127) >> 2; // about +/- 32
bump[index++] = col;
}
}
Expand Down Expand Up @@ -5824,9 +5823,9 @@ uint16_t mode_2Dcrazybees(void) {
int8_t deltaX, deltaY, signX, signY, error;
void aimed(uint16_t w, uint16_t h) {
//random16_set_seed(millis());
aimX = random8(0, w);
aimY = random8(0, h);
hue = random8();
aimX = prng.random8(0, w);
aimY = prng.random8(0, h);
hue = prng.random8();
deltaX = abs(aimX - posX);
deltaY = abs(aimY - posY);
signX = posX < aimX ? 1 : -1;
Expand All @@ -5839,10 +5838,10 @@ uint16_t mode_2Dcrazybees(void) {
bee_t *bee = reinterpret_cast<bee_t*>(SEGENV.data);

if (SEGENV.call == 0) {
random16_set_seed(strip.now);
prng.setSeed(strip.now);
for (size_t i = 0; i < n; i++) {
bee[i].posX = random8(0, cols);
bee[i].posY = random8(0, rows);
bee[i].posX = prng.random8(0, cols);
bee[i].posY = prng.random8(0, rows);
bee[i].aimed(cols, rows);
}
}
Expand Down Expand Up @@ -6013,7 +6012,7 @@ uint16_t mode_2Dfloatingblobs(void) {

// Bounce balls around
for (size_t i = 0; i < Amount; i++) {
if (SEGENV.step < strip.now) blob->color[i] = add8(blob->color[i], 4); // slowly change color
if (SEGENV.step < strip.now) blob->color[i] += 4; // slowly change color
// change radius if needed
if (blob->grow[i]) {
// enlarge radius until it is >= 4
Expand Down Expand Up @@ -7509,7 +7508,7 @@ static void soapPixels(bool isRow, uint8_t *noise3d, CRGB *pixels) {
else PixelA = ColorFromPalette(SEGPALETTE, ~noise3d[indxA]*3);
if ((zF >= 0) && (zF < tCR)) PixelB = pixels[indxB];
else PixelB = ColorFromPalette(SEGPALETTE, ~noise3d[indxB]*3);
ledsbuff[j] = (PixelA.nscale8(ease8InOutApprox(255 - fraction))) + (PixelB.nscale8(ease8InOutApprox(fraction)));
ledsbuff[j] = (PixelA.nscale8(ease8InOutCubic(255 - fraction))) + (PixelB.nscale8(ease8InOutCubic(fraction)));
}
for (int j = 0; j < tCR; j++) {
CRGB c = ledsbuff[j];
Expand Down Expand Up @@ -7862,7 +7861,7 @@ uint16_t mode_particlefireworks(void) {
emitparticles = hw_random16(SEGMENT.intensity >> 2) + (SEGMENT.intensity >> 2) + 5; // defines the size of the explosion
#endif

if (random16() & 1) { // 50% chance for circular explosion
if (hw_random() & 1) { // 50% chance for circular explosion
circularexplosion = true;
speed = 2 + hw_random16(3) + ((SEGMENT.intensity >> 6));
currentspeed = speed;
Expand Down Expand Up @@ -9727,7 +9726,7 @@ uint16_t mode_particleBalance(void) {
if (SEGMENT.check3) // random, use perlin noise
xgravity = ((int16_t)perlin8(SEGENV.aux0) - 128);
else // sinusoidal
xgravity = (int16_t)cos8(SEGENV.aux0) - 128;//((int32_t)(SEGMENT.custom3 << 2) * cos8(SEGENV.aux0)
xgravity = (int16_t)cos8_t(SEGENV.aux0) - 128;//((int32_t)(SEGMENT.custom3 << 2) * cos8(SEGENV.aux0)
// scale the force
xgravity = (xgravity * ((SEGMENT.custom3+1) << 2)) / 128; // xgravity: -127 to +127
PartSys->applyForce(xgravity);
Expand Down Expand Up @@ -10081,6 +10080,7 @@ uint16_t mode_particle1DsonicStream(void) {
uint32_t baseBin = SEGMENT.custom3 >> 1; // 0 - 15 map(SEGMENT.custom3, 0, 31, 0, 14);

loudness = fftResult[baseBin];// + fftResult[baseBin + 1];
int mids = sqrt32_bw((int)fftResult[5] + (int)fftResult[6] + (int)fftResult[7] + (int)fftResult[8] + (int)fftResult[9] + (int)fftResult[10]); // average the mids, bin 5 is ~500Hz, bin 10 is ~2kHz (see audio_reactive.h)
if (baseBin > 12)
loudness = loudness << 2; // double loudness for high frequencies (better detecion)

Expand Down
Loading
Loading