Merge pull request #4181 from DedeHai/0_15_trig_math

Added integer based `sin()/cos()` functions, changed all trig functions to wled_math
This commit is contained in:
Damian Schneider
2024-11-27 22:27:56 +01:00
committed by Frank
parent 5ea9cb1907
commit e914417c74
5 changed files with 319 additions and 179 deletions

View File

@@ -102,9 +102,9 @@ private:
void secondsEffectSineFade(int16_t secondLed, Toki::Time const& time) {
uint32_t ms = time.ms % 1000;
uint8_t b0 = (cos8(ms * 64 / 1000) - 128) * 2;
uint8_t b0 = (cos8_t(ms * 64 / 1000) - 128) * 2;
setPixelColor(secondLed, gamma32(scale32(secondColor, b0)));
uint8_t b1 = (sin8(ms * 64 / 1000) - 128) * 2;
uint8_t b1 = (sin8_t(ms * 64 / 1000) - 128) * 2;
setPixelColor(inc(secondLed, 1, secondsSegment), gamma32(scale32(secondColor, b1)));
}

View File

@@ -31,7 +31,7 @@
// effect utility functions
static uint8_t sin_gap(uint16_t in) {
if (in & 0x100) return 0;
return sin8(in + 192); // correct phase shift of sine so that it starts and stops at 0
return sin8_t(in + 192); // correct phase shift of sine so that it starts and stops at 0
}
static uint16_t triwave16(uint16_t in) {
@@ -364,7 +364,7 @@ uint16_t mode_breath(void) {
counter = (counter >> 2) + (counter >> 4); //0-16384 + 0-2048
if (counter < 16384) {
if (counter > 8192) counter = 8192 - (counter - 8192);
var = sin16(counter) / 103; //close to parabolic in range 0-8192, max val. 23170
var = sin16_t(counter) / 103; //close to parabolic in range 0-8192, max val. 23170
}
uint8_t lum = 30 + var;
@@ -546,7 +546,7 @@ uint16_t running_base(bool saw, bool dual=false) {
}
a = 255 - a;
}
uint8_t s = dual ? sin_gap(a) : sin8(a);
uint8_t s = dual ? sin_gap(a) : sin8_t(a);
uint32_t ca = color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s);
if (dual) {
uint16_t b = (SEGLEN-1-i)*x_scale - counter;
@@ -1934,13 +1934,13 @@ uint16_t mode_pride_2015(void) {
uint16_t sPseudotime = SEGENV.step;
uint16_t sHue16 = SEGENV.aux0;
uint8_t sat8 = beatsin88( 87, 220, 250);
uint8_t brightdepth = beatsin88( 341, 96, 224);
uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256));
uint8_t msmultiplier = beatsin88(147, 23, 60);
uint8_t sat8 = beatsin88_t( 87, 220, 250);
uint8_t brightdepth = beatsin88_t( 341, 96, 224);
uint16_t brightnessthetainc16 = beatsin88_t( 203, (25 * 256), (40 * 256));
uint8_t msmultiplier = beatsin88_t(147, 23, 60);
uint16_t hue16 = sHue16;//gHue * 256;
uint16_t hueinc16 = beatsin88(113, 1, 3000);
uint16_t hueinc16 = beatsin88_t(113, 1, 3000);
if(SEGENV.call == 0) {
SEGMENT.setUpLeds(); // WLEDMM use lossless getPixelColor()
@@ -1948,15 +1948,14 @@ uint16_t mode_pride_2015(void) {
}
sPseudotime += duration * msmultiplier;
sHue16 += duration * beatsin88( 400, 5,9);
sHue16 += duration * beatsin88_t( 400, 5,9);
uint16_t brightnesstheta16 = sPseudotime;
for (int i = 0 ; i < SEGLEN; i++) {
hue16 += hueinc16;
uint8_t hue8 = hue16 >> 8;
brightnesstheta16 += brightnessthetainc16;
uint16_t b16 = sin16( brightnesstheta16 ) + 32768;
uint16_t b16 = sin16_t( brightnesstheta16 ) + 32768;
uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536;
uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
@@ -2047,7 +2046,7 @@ uint16_t mode_juggle(void) {
CRGB fastled_col;
byte dothue = 0;
for (int i = 0; i < 8; i++) {
uint16_t index = 0 + beatsin88((16 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1);
uint16_t index = 0 + beatsin88_t((16 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1);
fastled_col = CRGB(SEGMENT.getPixelColor(index));
fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(SEGPALETTE, dothue, 255);
SEGMENT.setPixelColor(index, fastled_col);
@@ -2174,15 +2173,15 @@ uint16_t mode_colorwaves() {
uint16_t sPseudotime = SEGENV.step;
uint16_t sHue16 = SEGENV.aux0;
uint8_t brightdepth = beatsin88(341, 96, 224);
uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256));
uint8_t msmultiplier = beatsin88(147, 23, 60);
uint8_t brightdepth = beatsin88_t(341, 96, 224);
uint16_t brightnessthetainc16 = beatsin88_t( 203, (25 * 256), (40 * 256));
uint8_t msmultiplier = beatsin88_t(147, 23, 60);
uint16_t hue16 = sHue16;//gHue * 256;
uint16_t hueinc16 = beatsin88(113, 60, 300)*SEGMENT.intensity*10/255; // Use the Intensity Slider for the hues
uint16_t hueinc16 = beatsin88_t(113, 60, 300)*SEGMENT.intensity*10/255; // Use the Intensity Slider for the hues
sPseudotime += duration * msmultiplier;
sHue16 += duration * beatsin88(400, 5, 9);
sHue16 += duration * beatsin88_t(400, 5, 9);
uint16_t brightnesstheta16 = sPseudotime;
if(SEGENV.call == 0) {
@@ -2201,7 +2200,7 @@ uint16_t mode_colorwaves() {
}
brightnesstheta16 += brightnessthetainc16;
uint16_t b16 = sin16(brightnesstheta16) + 32768;
uint16_t b16 = sin16_t(brightnesstheta16) + 32768;
uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536;
uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
@@ -2221,7 +2220,7 @@ static const char _data_FX_MODE_COLORWAVES[] PROGMEM = "Colorwaves@!,Hue;!;!";
uint16_t mode_bpm() {
//CRGB fastled_col;
uint32_t stp = (strip.now / 20) & 0xFF;
uint8_t beat = beatsin8(SEGMENT.speed, 64, 255);
uint8_t beat = beatsin8_t(SEGMENT.speed, 64, 255);
for (int i = 0; i < SEGLEN; i++) {
//fastled_col = ColorFromPalette(SEGPALETTE, stp + (i * 2), beat - stp + (i * 10));
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
@@ -2242,7 +2241,7 @@ uint16_t mode_fillnoise8() {
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0));
}
SEGENV.step += beatsin8(SEGMENT.speed, 1, 6); //10,1,4
SEGENV.step += beatsin8_t(SEGMENT.speed, 1, 6); //10,1,4
return FRAMETIME;
}
@@ -2255,13 +2254,13 @@ uint16_t mode_noise16_1() {
SEGENV.step += (1 + SEGMENT.speed/16);
for (int i = 0; i < SEGLEN; i++) {
uint16_t shift_x = beatsin8(11); // the x position of the noise field swings @ 17 bpm
uint16_t shift_x = beatsin8_t(11); // the x position of the noise field swings @ 17 bpm
uint16_t shift_y = SEGENV.step/42; // the y position becomes slowly incremented
uint16_t real_x = (i + shift_x) * scale; // the x position of the noise field swings @ 17 bpm
uint16_t real_y = (i + shift_y) * scale; // the y position becomes slowly incremented
uint32_t real_z = SEGENV.step; // the z position becomes quickly incremented
uint8_t noise = inoise16(real_x, real_y, real_z) >> 8; // get the noise data and scale it down
uint8_t index = sin8(noise * 3); // map LED color based on noise data
uint8_t index = sin8_t(noise * 3); // map LED color based on noise data
//fastled_col = ColorFromPalette(SEGPALETTE, index, 255, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
@@ -2282,7 +2281,7 @@ uint16_t mode_noise16_2() {
uint16_t shift_x = SEGENV.step >> 6; // x as a function of time
uint32_t real_x = (i + shift_x) * scale; // calculate the coordinates within the noise field
uint8_t noise = inoise16(real_x, 0, 4223) >> 8; // get the noise data and scale it down
uint8_t index = sin8(noise * 3); // map led color based on noise data
uint8_t index = sin8_t(noise * 3); // map led color based on noise data
//fastled_col = ColorFromPalette(SEGPALETTE, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
@@ -2306,7 +2305,7 @@ uint16_t mode_noise16_3() {
uint32_t real_y = (i + shift_y) * scale; // based on the precalculated positions
uint32_t real_z = SEGENV.step*8;
uint8_t noise = inoise16(real_x, real_y, real_z) >> 8; // get the noise data and scale it down
uint8_t index = sin8(noise * 3); // map led color based on noise data
uint8_t index = sin8_t(noise * 3); // map led color based on noise data
//fastled_col = ColorFromPalette(SEGPALETTE, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
@@ -2395,14 +2394,14 @@ static const char _data_FX_MODE_COLORTWINKLE[] PROGMEM = "Colortwinkles@Fade spe
//Calm effect, like a lake at night
uint16_t mode_lake() {
uint8_t sp = SEGMENT.speed/10;
int wave1 = beatsin8(sp +2, -64,64);
int wave2 = beatsin8(sp +1, -64,64);
uint8_t wave3 = beatsin8(sp +2, 0,80);
int wave1 = beatsin8_t(sp +2, -64,64);
int wave2 = beatsin8_t(sp +1, -64,64);
uint8_t wave3 = beatsin8_t(sp +2, 0,80);
//CRGB fastled_col;
for (int i = 0; i < SEGLEN; i++)
{
int index = cos8((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2;
int index = cos8_t((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2;
uint8_t lum = (index > wave3) ? index - wave3 : 0;
//fastled_col = ColorFromPalette(SEGPALETTE, map(index,0,255,0,240), lum, LINEARBLEND);
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
@@ -2569,7 +2568,7 @@ uint16_t ripple_base()
propI /= 2;
uint16_t cx = rippleorigin >> 8;
uint16_t cy = rippleorigin & 0xFF;
uint8_t mag = scale8(sin8((propF>>2)), amp);
uint8_t mag = scale8(sin8_t((propF>>2)), amp);
if (propI > 0) SEGMENT.drawCircle(cx, cy, propI, color_blend(SEGMENT.getPixelColorXY(cx + propI, cy), col, mag), true);
} else
#endif
@@ -2644,7 +2643,7 @@ CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
uint16_t ticks = ms / SEGENV.aux0;
uint8_t fastcycle8 = ticks;
uint16_t slowcycle16 = (ticks >> 8) + salt;
slowcycle16 += sin8(slowcycle16);
slowcycle16 += sin8_t(slowcycle16);
slowcycle16 = (slowcycle16 * 2053) + 1384;
uint8_t slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8);
@@ -3115,7 +3114,7 @@ uint16_t sinelon_base(bool dual, bool rainbow=false) {
if (SEGLEN == 1) return mode_static();
if (SEGENV.call == 0) { SEGENV.setUpLeds(); SEGMENT.fill(BLACK); } // WLEDMM use lossless getPixelColor()
SEGMENT.fade_out(SEGMENT.intensity);
uint16_t pos = beatsin16(SEGMENT.speed/10,0,SEGLEN-1);
uint16_t pos = beatsin16_t(SEGMENT.speed/10,0,SEGLEN-1);
if (SEGENV.call == 0) SEGENV.aux0 = pos;
uint32_t color1 = SEGMENT.color_from_palette(pos, true, false, 0);
uint32_t color2 = SEGCOLOR(2);
@@ -3941,13 +3940,13 @@ uint16_t mode_plasma(void) {
if (SEGENV.call == 0) {
SEGENV.aux0 = random8(0,2); // add a bit of randomness
}
uint8_t thisPhase = beatsin8(6+SEGENV.aux0,-64,64);
uint8_t thatPhase = beatsin8(7+SEGENV.aux0,-64,64);
uint8_t thisPhase = beatsin8_t(6+SEGENV.aux0,-64,64);
uint8_t thatPhase = beatsin8_t(7+SEGENV.aux0,-64,64);
for (int i = 0; i < SEGLEN; i++) { // For each of the LED's in the strand, set color & brightness based on a wave as follows:
uint8_t colorIndex = cubicwave8((i*(2+ 3*(SEGMENT.speed >> 5))+thisPhase) & 0xFF)/2 // factor=23 // Create a wave and add a phase change and add another wave with its own phase change.
+ cos8((i*(1+ 2*(SEGMENT.speed >> 5))+thatPhase) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish.
uint8_t thisBright = qsub8(colorIndex, beatsin8(7,0, (128 - (SEGMENT.intensity>>1))));
+ cos8_t((i*(1+ 2*(SEGMENT.speed >> 5))+thatPhase) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish.
uint8_t thisBright = qsub8(colorIndex, beatsin8_t(7,0, (128 - (SEGMENT.intensity>>1))));
//CRGB color = ColorFromPalette(SEGPALETTE, colorIndex, thisBright, LINEARBLEND);
//SEGMENT.setPixelColor(i, color.red, color.green, color.blue);
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0, thisBright));
@@ -4076,10 +4075,10 @@ CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t
uint16_t wavescale_half = (wavescale >> 1) + 20;
waveangle += ((120 + SEGMENT.intensity) * i); //original 250 * i
uint16_t s16 = sin16(waveangle) + 32768;
uint16_t s16 = sin16_t(waveangle) + 32768;
uint16_t cs = scale16(s16, wavescale_half) + wavescale_half;
ci += (cs * i);
uint16_t sindex16 = sin16(ci) + 32768;
uint16_t sindex16 = sin16_t(ci) + 32768;
uint8_t sindex8 = scale16(sindex16, 240);
return ColorFromPalette(p, sindex8, bri, LINEARBLEND);
}
@@ -4111,34 +4110,34 @@ uint16_t mode_pacifica()
uint64_t deltat = (strip.now >> 2) + ((strip.now * SEGMENT.speed) >> 7);
strip.now = deltat;
uint16_t speedfactor1 = beatsin16(3, 179, 269);
uint16_t speedfactor2 = beatsin16(4, 179, 269);
uint16_t speedfactor1 = beatsin16_t(3, 179, 269);
uint16_t speedfactor2 = beatsin16_t(4, 179, 269);
uint32_t deltams1 = (deltams * speedfactor1) / 256;
uint32_t deltams2 = (deltams * speedfactor2) / 256;
uint32_t deltams21 = (deltams1 + deltams2) / 2;
sCIStart1 += (deltams1 * beatsin88(1011,10,13));
sCIStart2 -= (deltams21 * beatsin88(777,8,11));
sCIStart3 -= (deltams1 * beatsin88(501,5,7));
sCIStart4 -= (deltams2 * beatsin88(257,4,6));
sCIStart1 += (deltams1 * beatsin88_t(1011,10,13));
sCIStart2 -= (deltams21 * beatsin88_t(777,8,11));
sCIStart3 -= (deltams1 * beatsin88_t(501,5,7));
sCIStart4 -= (deltams2 * beatsin88_t(257,4,6));
SEGENV.aux0 = sCIStart1; SEGENV.aux1 = sCIStart2;
SEGENV.step = sCIStart4; SEGENV.step = (SEGENV.step << 16) + sCIStart3;
// Clear out the LED array to a dim background blue-green
//SEGMENT.fill(132618);
uint8_t basethreshold = beatsin8( 9, 55, 65);
uint8_t basethreshold = beatsin8_t( 9, 55, 65);
uint8_t wave = beat8( 7 );
for (int i = 0; i < SEGLEN; i++) {
CRGB c = CRGB(2, 6, 10);
// Render each of four layers, with different scales and speeds, that vary over time
c += pacifica_one_layer(i, pacifica_palette_1, sCIStart1, beatsin16(3, 11 * 256, 14 * 256), beatsin8(10, 70, 130), 0-beat16(301));
c += pacifica_one_layer(i, pacifica_palette_2, sCIStart2, beatsin16(4, 6 * 256, 9 * 256), beatsin8(17, 40, 80), beat16(401));
c += pacifica_one_layer(i, pacifica_palette_3, sCIStart3, 6 * 256 , beatsin8(9, 10,38) , 0-beat16(503));
c += pacifica_one_layer(i, pacifica_palette_3, sCIStart4, 5 * 256 , beatsin8(8, 10,28) , beat16(601));
c += pacifica_one_layer(i, pacifica_palette_1, sCIStart1, beatsin16_t(3, 11 * 256, 14 * 256), beatsin8_t(10, 70, 130), 0-beat16(301));
c += pacifica_one_layer(i, pacifica_palette_2, sCIStart2, beatsin16_t(4, 6 * 256, 9 * 256), beatsin8_t(17, 40, 80), beat16(401));
c += pacifica_one_layer(i, pacifica_palette_3, sCIStart3, 6 * 256 , beatsin8_t(9, 10,38) , 0-beat16(503));
c += pacifica_one_layer(i, pacifica_palette_3, sCIStart4, 5 * 256 , beatsin8_t(8, 10,28) , beat16(601));
// Add extra 'white' to areas where the four layers of light have lined up brightly
uint8_t threshold = scale8( sin8( wave), 20) + basethreshold;
uint8_t threshold = scale8( sin8_t( wave), 20) + basethreshold;
wave += 7;
uint8_t l = c.getAverageLight();
if (l > threshold) {
@@ -4262,7 +4261,7 @@ uint16_t mode_twinkleup(void) { // A very short twinkle routine
for (int i = 0; i < SEGLEN; i++) {
uint8_t ranstart = random8(); // The starting value (aka brightness) for each pixel. Must be consistent each time through the loop for this to work.
uint8_t pixBri = sin8(ranstart + 16 * strip.now/(256-SEGMENT.speed));
uint8_t 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));
}
@@ -4305,7 +4304,7 @@ uint16_t mode_noisepal(void) { // Slow noise
SEGMENT.setPixelColor(i, color.red, color.green, color.blue);
}
SEGENV.aux0 += beatsin8(10,1,4); // Moving along the distance. Vary it a bit with a sine wave.
SEGENV.aux0 += beatsin8_t(10,1,4); // Moving along the distance. Vary it a bit with a sine wave.
return FRAMETIME;
}
@@ -4388,7 +4387,7 @@ uint16_t mode_chunchun(void)
for (int i = 0; i < numBirds; i++)
{
counter -= span;
uint16_t megumin = sin16(counter) + 0x8000;
uint16_t megumin = sin16_t(counter) + 0x8000;
uint16_t bird = uint32_t(megumin * SEGLEN) >> 16;
uint32_t c = SEGMENT.color_from_palette((i * 255)/ numBirds, false, false, 0); // no palette wrapping
bird = constrain(bird, 0, SEGLEN-1);
@@ -4558,7 +4557,7 @@ uint16_t mode_washing_machine(void) {
SEGENV.step += (speed * 2048) / (512 - SEGMENT.speed);
for (int i = 0; i < SEGLEN; i++) {
uint8_t col = sin8(((SEGMENT.intensity / 25 + 1) * 255 * i / SEGLEN) + (SEGENV.step >> 7));
uint8_t col = sin8_t(((SEGMENT.intensity / 25 + 1) * 255 * i / SEGLEN) + (SEGENV.step >> 7));
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(col, false, PALETTE_SOLID_WRAP, 3));
}
@@ -4911,12 +4910,12 @@ static const char _data_FX_MODE_PERLINMOVE[] PROGMEM = "Perlin Move@!,# of pixel
/////////////////////////
// Waveins //
/////////////////////////
// Uses beatsin8() + phase shifting. By: Andrew Tuline
// Uses beatsin8_t() + phase shifting. By: Andrew Tuline
uint16_t mode_wavesins(void) {
for (int i = 0; i < SEGLEN; i++) {
uint8_t bri = sin8(strip.now/4 + i * SEGMENT.intensity);
uint8_t index = beatsin8(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * (SEGMENT.custom3<<3));
uint8_t bri = sin8_t(strip.now/4 + i * SEGMENT.intensity);
uint8_t index = beatsin8_t(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * (SEGMENT.custom3<<3)); // custom3 is reduced resolution slider
//SEGMENT.setPixelColor(i, ColorFromPalette(SEGPALETTE, index, bri, LINEARBLEND));
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0, bri));
}
@@ -4938,9 +4937,9 @@ uint16_t mode_FlowStripe(void) {
for (int i = 0; i < SEGLEN; i++) {
int c = (abs(i - hl) / hl) * 127;
c = sin8(c);
c = sin8(c / 2 + t);
byte b = sin8(c + t/8);
c = sin8_t(c);
c = sin8_t(c / 2 + t);
byte b = sin8_t(c + t/8);
SEGMENT.setPixelColor(i, CHSV(b + hue, 255, 255));
}
@@ -4974,14 +4973,14 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma
unsigned long t = strip.now; // timebase
// outer stars
for (unsigned i = 0; i < 8; i++) {
x = beatsin8(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + (t * i)/ratio);
y = beatsin8(SEGMENT.intensity>>3, 0, rows - 1, 0, ((i % 2) ? 192 : 64) + (t * i)/ratio);
x = beatsin8_t(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + (t * i)/ratio);
y = beatsin8_t(SEGMENT.intensity>>3, 0, rows - 1, 0, ((i % 2) ? 192 : 64) + (t * i)/ratio);
SEGMENT.addPixelColorXY(x, y, CHSV(i*32, 255, 255));
}
// inner stars
for (size_t i = 0; i < 4; i++) {
x = beatsin8(SEGMENT.custom2>>3, cols/4, cols - 1 - cols/4, 0, ((i % 2) ? 128 : 0) + (t * i)/ratio);
y = beatsin8(SEGMENT.custom3 , rows/4, rows - 1 - rows/4, 0, ((i % 2) ? 192 : 64) + (t * i)/ratio);
x = beatsin8_t(SEGMENT.custom2>>3, cols/4, cols - 1 - cols/4, 0, ((i % 2) ? 128 : 0) + (t * i)/ratio);
y = beatsin8_t(SEGMENT.custom3 , rows/4, rows - 1 - rows/4, 0, ((i % 2) ? 192 : 64) + (t * i)/ratio);
SEGMENT.addPixelColorXY(x, y, CHSV(i*32, 255, 255));
}
// central white dot
@@ -5017,10 +5016,10 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
SEGENV.aux0++; // hue
SEGMENT.fadeToBlackBy(40);
for (size_t i = 0; i < numLines; i++) {
byte x1 = beatsin8(2 + SEGMENT.speed/16, 0, (cols - 1));
byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (rows - 1));
byte y1 = beatsin8(5 + SEGMENT.speed/16, 0, (cols - 1), 0, i * 24);
byte y2 = beatsin8(3 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 48 + 64);
byte x1 = beatsin8_t(2 + SEGMENT.speed/16, 0, (cols - 1));
byte x2 = beatsin8_t(1 + SEGMENT.speed/16, 0, (rows - 1));
byte y1 = beatsin8_t(5 + SEGMENT.speed/16, 0, (cols - 1), 0, i * 24);
byte y2 = beatsin8_t(3 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 48 + 64);
CRGB color = ColorFromPalette(SEGPALETTE, i * 255 / numLines + (SEGENV.aux0&0xFF), 255, LINEARBLEND);
byte xsteps = abs8(x1 - y1) + 1;
@@ -5068,14 +5067,14 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa
int lastY1 = -1;
int lastY2 = -1;
for (int i = 0; i < cols; i++) {
int posY1 = beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4 );
int posY2 = beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4+128);
int posY1 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4 );
int posY2 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4+128);
if ((i==0) || ((abs(lastY1 - posY1) < 2) && (abs(lastY2 - posY2) < 2))) { // use original code when no holes
SEGMENT.setPixelColorXY(i, posY1, ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND));
SEGMENT.setPixelColorXY(i, posY2, ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND));
SEGMENT.setPixelColorXY(i, posY1, ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10), LINEARBLEND));
SEGMENT.setPixelColorXY(i, posY2, ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10+128), LINEARBLEND));
} else { // draw line to prevent holes
SEGMENT.drawLine(i-1, lastY1, i, posY1, ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND));
SEGMENT.drawLine(i-1, lastY2, i, posY2, ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND));
SEGMENT.drawLine(i-1, lastY1, i, posY1, ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10), LINEARBLEND));
SEGMENT.drawLine(i-1, lastY2, i, posY2, ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10+128), LINEARBLEND));
}
lastY1 = posY1;
lastY2 = posY2;
@@ -5108,8 +5107,8 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma
SEGMENT.fadeToBlackBy(135);
for (int i = 0; i < rows; i++) {
uint16_t x = beatsin8(speeds, 0, cols - 1, 0, i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, i * freq + 128);
uint16_t x1 = beatsin8(speeds, 0, cols - 1, 0, 128 + i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, 128 + 64 + i * freq);
uint16_t x = beatsin8_t(speeds, 0, cols - 1, 0, i * freq) + beatsin8_t(speeds - 7, 0, cols - 1, 0, i * freq + 128);
uint16_t x1 = beatsin8_t(speeds, 0, cols - 1, 0, 128 + i * freq) + beatsin8_t(speeds - 7, 0, cols - 1, 0, 128 + 64 + i * freq);
uint8_t hue = (i * 128 / rows) + ms;
// skip every 4th row every now and then (fade it more)
if ((i + ms / 8) & 3) {
@@ -5241,9 +5240,9 @@ uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.so
SEGMENT.fadeToBlackBy(16);
for (size_t i = 8; i > 0; i--) {
SEGMENT.addPixelColorXY(beatsin8(SEGMENT.speed/8 + i, 0, cols - 1),
beatsin8(SEGMENT.intensity/8 - i, 0, rows - 1),
ColorFromPalette(SEGPALETTE, beatsin8(12, 0, 255), 255, LINEARBLEND));
SEGMENT.addPixelColorXY(beatsin8_t(SEGMENT.speed/8 + i, 0, cols - 1),
beatsin8_t(SEGMENT.intensity/8 - i, 0, rows - 1),
ColorFromPalette(SEGPALETTE, beatsin8_t(12, 0, 255), 255, LINEARBLEND));
}
SEGMENT.blur(SEGMENT.custom1>>3);
@@ -5661,7 +5660,7 @@ uint16_t mode_2DHiphotic() { // By: ldirko https://edit
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(sin8(cos8(x * SEGMENT.speed/16 + a / 3) + sin8(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0));
SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(sin8_t(cos8_t(x * SEGMENT.speed/16 + a / 3) + sin8_t(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0));
}
}
@@ -5740,8 +5739,10 @@ uint16_t mode_2DJulia(void) { // An animated Julia set
reAl = -0.94299f; // PixelBlaze example
imAg = 0.3162f;
reAl += sinf((float)strip.now/305.f)/20.f;
imAg += sinf((float)strip.now/405.f)/20.f;
//reAl += sinf((float)strip.now/305.f)/20.f;
//imAg += sinf((float)strip.now/405.f)/20.f;
reAl += (float)sin16_t(strip.now * 34) / 655340.f;
imAg += (float)sin16_t(strip.now * 26) / 655340.f;
dx = (xmax - xmin) / (cols); // Scale the delta x and y values to our matrix size.
dy = (ymax - ymin) / (rows);
@@ -5820,8 +5821,8 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline
int maxLoops = max(192, 4*(cols+rows));
maxLoops = ((maxLoops / 128) +1) * 128; // make sure whe have half or full turns => multiples of 128
for (int i=0; i < maxLoops; i ++) {
float xlocn = float(sin8(phase/2 + (i* SEGMENT.speed)/64)) / 255.0f; // WLEDMM align speed with original effect
float ylocn = float(cos8(phase/2 + i*2)) / 255.0f;
float xlocn = float(sin8_t(phase/2 + (i* SEGMENT.speed)/64)) / 255.0f; // WLEDMM align speed with original effect
float ylocn = float(cos8_t(phase/2 + i*2)) / 255.0f;
//SEGMENT.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0)); // draw pixel with anti-aliasing
unsigned palIndex = (256*ylocn) + phase/2 + (i* SEGMENT.speed)/64;
//SEGMENT.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(palIndex, false, PALETTE_SOLID_WRAP, 0)); // draw pixel with anti-aliasing - color follows rotation
@@ -5832,8 +5833,8 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline
} else
for (int i=0; i < 256; i ++) {
//WLEDMM: stick to the original calculations of xlocn and ylocn
uint_fast8_t xlocn = sin8(phase/2 + (i*SEGMENT.speed)/64);
uint_fast8_t ylocn = cos8(phase/2 + i*2);
uint_fast8_t xlocn = sin8_t(phase/2 + (i*SEGMENT.speed)/64);
uint_fast8_t ylocn = cos8_t(phase/2 + i*2);
xlocn = (cols < 2) ? 1 : (map(2*xlocn, 0,511, 0,2*(cols-1)) +1) /2; // softhack007: "*2 +1" for proper rounding
ylocn = (rows < 2) ? 1 : (map(2*ylocn, 0,511, 0,2*(rows-1)) +1) /2; // "rows > 2" is needed to avoid div/0 in map()
SEGMENT.setPixelColorXY((uint8_t)xlocn, (uint8_t)ylocn, SEGMENT.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0));
@@ -5939,8 +5940,8 @@ uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have
uint8_t y3 = map(inoise8(strip.now * speed, 25355, 22685), 0, 255, 0, rows-1);
// and one Lissajou function
uint8_t x1 = beatsin8(23 * speed, 0, cols-1);
uint8_t y1 = beatsin8(28 * speed, 0, rows-1);
uint8_t x1 = beatsin8_t(23 * speed, 0, cols-1);
uint8_t y1 = beatsin8_t(28 * speed, 0, rows-1);
for (int y = 0; y < rows; y++) {
for (int x = 0; x < cols; x++) {
@@ -6142,7 +6143,7 @@ uint16_t mode_2DPulser(void) { // By: ldirko https://edi
uint32_t a = strip.now / (18 - SEGMENT.speed / 16);
uint16_t x = (a / 14) % cols;
uint16_t y = map((sin8(a * 5) + sin8(a * 4) + sin8(a * 2)), 0, 765, rows-1, 0);
uint16_t y = map((sin8_t(a * 5) + sin8_t(a * 4) + sin8_t(a * 2)), 0, 765, rows-1, 0);
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, map(y, 0, rows-1, 0, 255), 255, LINEARBLEND));
SEGMENT.blur(1 + (SEGMENT.intensity>>4));
@@ -6169,10 +6170,10 @@ uint16_t mode_2DSindots(void) { // By: ldirko http
SEGMENT.fadeToBlackBy(SEGMENT.custom1>>3);
byte t1 = strip.now / (257 - SEGMENT.speed); // 20;
byte t2 = sin8(t1) / 4 * 2;
byte t2 = sin8_t(t1) / 4 * 2;
for (int i = 0; i < 13; i++) {
byte x = sin8(t1 + i * SEGMENT.intensity/8)*(cols-1)/255; // max index now 255x15/255=15!
byte y = sin8(t2 + i * SEGMENT.intensity/8)*(rows-1)/255; // max index now 255x15/255=15!
byte x = sin8_t(t1 + i * SEGMENT.intensity/8)*(cols-1)/255; // max index now 255x15/255=15!
byte y = sin8_t(t2 + i * SEGMENT.intensity/8)*(rows-1)/255; // max index now 255x15/255=15!
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, i * 255 / 13, 255, LINEARBLEND));
}
SEGMENT.blur(SEGMENT.custom2>>3);
@@ -6206,12 +6207,12 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g
SEGMENT.blur(blurAmount);
// Use two out-of-sync sine waves
uint8_t i = beatsin8(19, kBorderWidth, cols-kBorderWidth);
uint8_t j = beatsin8(22, kBorderWidth, cols-kBorderWidth);
uint8_t k = beatsin8(17, kBorderWidth, cols-kBorderWidth);
uint8_t m = beatsin8(18, kBorderWidth, rows-kBorderWidth);
uint8_t n = beatsin8(15, kBorderWidth, rows-kBorderWidth);
uint8_t p = beatsin8(20, kBorderWidth, rows-kBorderWidth);
uint8_t i = beatsin8_t(19, kBorderWidth, cols-kBorderWidth);
uint8_t j = beatsin8_t(22, kBorderWidth, cols-kBorderWidth);
uint8_t k = beatsin8_t(17, kBorderWidth, cols-kBorderWidth);
uint8_t m = beatsin8_t(18, kBorderWidth, rows-kBorderWidth);
uint8_t n = beatsin8_t(15, kBorderWidth, rows-kBorderWidth);
uint8_t p = beatsin8_t(20, kBorderWidth, rows-kBorderWidth);
uint16_t ms = strip.now;
@@ -6293,19 +6294,19 @@ uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.so
uint8_t hue, bri;
size_t intensity;
int offsetX = beatsin16(3, -360, 360);
int offsetY = beatsin16(2, -360, 360);
int offsetX = beatsin16_t(3, -360, 360);
int offsetY = beatsin16_t(2, -360, 360);
int sharpness = SEGMENT.custom3 / 8; // 0-3
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
hue = x * beatsin16(10, 1, 10) + offsetY;
intensity = bri = sin8(x * SEGMENT.speed/2 + offsetX);
hue = x * beatsin16_t(10, 1, 10) + offsetY;
intensity = bri = sin8_t(x * SEGMENT.speed/2 + offsetX);
for (int i=0; i<sharpness; i++) intensity *= bri;
intensity >>= 8*sharpness;
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, hue, intensity, LINEARBLEND));
hue = y * 3 + offsetX;
intensity = bri = sin8(y * SEGMENT.intensity/2 + offsetY);
intensity = bri = sin8_t(y * SEGMENT.intensity/2 + offsetY);
for (int i=0; i<sharpness; i++) intensity *= bri;
intensity >>= 8*sharpness;
SEGMENT.addPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, hue, intensity, LINEARBLEND));
@@ -6345,9 +6346,9 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht
SEGMENT.move(SEGENV.aux0, 1);
for (size_t i = 0; i < 8; i++) {
byte x = beatsin8(12 + i, 2, cols - 3);
byte y = beatsin8(15 + i, 2, rows - 3);
CRGB color = ColorFromPalette(SEGPALETTE, beatsin8(12 + i, 0, 255), 255);
byte x = beatsin8_t(12 + i, 2, cols - 3);
byte y = beatsin8_t(15 + i, 2, rows - 3);
CRGB color = ColorFromPalette(SEGPALETTE, beatsin8_t(12 + i, 0, 255), 255);
SEGMENT.addPixelColorXY(x, y, color);
if (cols > 24 || rows > 24) {
SEGMENT.addPixelColorXY(x+1, y, color);
@@ -6772,8 +6773,8 @@ uint16_t mode_2Ddriftrose(void) {
SEGMENT.fadeToBlackBy(32+(SEGMENT.speed>>3));
for (size_t i = 1; i < 37; i++) {
float angle = float(DEG_TO_RAD) * i * 10;
uint32_t x = int((CX + (sinf(angle) * (beatsin8(i, 0, L2)-L))) * 255.f);
uint32_t y = int((CY + (cosf(angle) * (beatsin8(i, 0, L2)-L))) * 255.f);
uint32_t x = int((CX + (sinf(angle) * (beatsin8_t(i, 0, L2)-L))) * 255.f);
uint32_t y = int((CY + (cosf(angle) * (beatsin8_t(i, 0, L2)-L))) * 255.f);
if ((x < wu_cols) && (y < wu_rows)) SEGMENT.wu_pixel(x, y, CHSV(i * 10, 255, 255));
}
SEGMENT.blur((SEGMENT.intensity>>4)+1);
@@ -6944,10 +6945,10 @@ uint16_t mode_2DSwirl(void) {
SEGMENT.blur(SEGMENT.custom1);
unsigned i = beatsin8( 27*SEGMENT.speed/255, borderWidth, cols - borderWidth);
unsigned j = beatsin8( 41*SEGMENT.speed/255, borderWidth, rows - borderWidth);
unsigned ni = (cols - 1) - i;
unsigned nj = (cols - 1) - j;
int i = beatsin8_t( 27*SEGMENT.speed/255, borderWidth, cols - borderWidth);
int j = beatsin8_t( 41*SEGMENT.speed/255, borderWidth, rows - borderWidth);
int ni = (cols - 1) - i;
int nj = (cols - 1) - j;
uint16_t ms = strip.now;
um_data_t *um_data = getAudioData();
@@ -7214,7 +7215,7 @@ uint16_t mode_juggles(void) { // Juggles. By Andrew Tuline.
for (size_t i=0; i<SEGMENT.intensity/32+1U; i++) {
// if SEGLEN equals 1, we will always set color to the first and only pixel, but the effect is still good looking
SEGMENT.setPixelColor(beatsin16(SEGMENT.speed/4+i*2,0,SEGLEN-1), color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(strip.now/4+i*2, false, PALETTE_SOLID_WRAP, 0), my_sampleAgc));
SEGMENT.setPixelColor(beatsin16_t(SEGMENT.speed/4+i*2,0,SEGLEN-1), color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(strip.now/4+i*2, false, PALETTE_SOLID_WRAP, 0), my_sampleAgc));
}
return FRAMETIME;
@@ -7301,8 +7302,8 @@ uint16_t mode_midnoise(void) { // Midnoise. By Andrew Tuline.
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0));
}
SEGENV.aux0=SEGENV.aux0+beatsin8(5,0,10);
SEGENV.aux1=SEGENV.aux1+beatsin8(4,0,10);
SEGENV.aux0=SEGENV.aux0+beatsin8_t(5,0,10);
SEGENV.aux1=SEGENV.aux1+beatsin8_t(4,0,10);
return FRAMETIME;
} // mode_midnoise()
@@ -7362,8 +7363,8 @@ uint16_t mode_noisemeter(void) { // Noisemeter. By Andrew Tuline.
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0));
}
SEGENV.aux0+=beatsin8(5,0,10);
SEGENV.aux1+=beatsin8(4,0,10);
SEGENV.aux0+=beatsin8_t(5,0,10);
SEGENV.aux1+=beatsin8_t(4,0,10);
return FRAMETIME;
} // mode_noisemeter()
@@ -7425,13 +7426,13 @@ uint16_t mode_plasmoid(void) { // Plasmoid. By Andrew Tuline.
//SEGMENT.fadeToBlackBy(32);
SEGMENT.fadeToBlackBy(48);
plasmoip->thisphase += beatsin8(6,-4,4); // You can change direction and speed individually.
plasmoip->thatphase += beatsin8(7,-4,4); // Two phase values to make a complex pattern. By Andrew Tuline.
plasmoip->thisphase += beatsin8_t(6,-4,4); // You can change direction and speed individually.
plasmoip->thatphase += beatsin8_t(7,-4,4); // Two phase values to make a complex pattern. By Andrew Tuline.
for (int i = 0; i < SEGLEN; i++) { // For each of the LED's in the strand, set a brightness based on a wave as follows.
// updated, similar to "plasma" effect - softhack007
uint8_t thisbright = cubicwave8(((i*(1 + (3*SEGMENT.speed/32)))+plasmoip->thisphase) & 0xFF)/2;
thisbright += cos8(((i*(97 +(5*SEGMENT.speed/32)))+plasmoip->thatphase) & 0xFF)/2; // Let's munge the brightness a bit and animate it all with the phases.
thisbright += cos8_t(((i*(97 +(5*SEGMENT.speed/32)))+plasmoip->thatphase) & 0xFF)/2; // Let's munge the brightness a bit and animate it all with the phases.
uint8_t colorIndex=thisbright;
if (volumeSmth * SEGMENT.intensity / 64 < thisbright) {thisbright = 0;}
@@ -8035,7 +8036,7 @@ uint16_t mode_rocktaves(void) { // Rocktaves. Same note from eac
frTemp -=132; // This should give us a base musical note of C3
frTemp = fabsf(frTemp * 2.1f); // Fudge factors to compress octave range starting at 0 and going to 255;
uint16_t i = map(beatsin8(8+octCount*4, 0, 255, 0, octCount*8), 0, 255, 0, SEGLEN-1);
uint16_t i = map(beatsin8_t(8+octCount*4, 0, 255, 0, octCount*8), 0, 255, 0, SEGLEN-1);
// i will be always constrained between 0 and 0 if SEGLEN equals 1
i = constrain(i, 0, SEGLEN-1);
SEGMENT.addPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette((uint8_t)frTemp, false, PALETTE_SOLID_WRAP, 0), volTemp));
@@ -8405,12 +8406,12 @@ uint16_t mode_2Ddistortionwaves() {
uint16_t a2 = a/2;
uint16_t a3 = a/3;
uint16_t cx = beatsin8(10-speed,0,cols-1)*scale;
uint16_t cy = beatsin8(12-speed,0,rows-1)*scale;
uint16_t cx1 = beatsin8(13-speed,0,cols-1)*scale;
uint16_t cy1 = beatsin8(15-speed,0,rows-1)*scale;
uint16_t cx2 = beatsin8(17-speed,0,cols-1)*scale;
uint16_t cy2 = beatsin8(14-speed,0,rows-1)*scale;
uint16_t cx = beatsin8_t(10-speed,0,cols-1)*scale;
uint16_t cy = beatsin8_t(12-speed,0,rows-1)*scale;
uint16_t cx1 = beatsin8_t(13-speed,0,cols-1)*scale;
uint16_t cy1 = beatsin8_t(15-speed,0,rows-1)*scale;
uint16_t cx2 = beatsin8_t(17-speed,0,cols-1)*scale;
uint16_t cy2 = beatsin8_t(14-speed,0,rows-1)*scale;
uint16_t xoffs = 0;
for (int x = 0; x < cols; x++) {
@@ -8420,17 +8421,17 @@ uint16_t mode_2Ddistortionwaves() {
for (int y = 0; y < rows; y++) {
yoffs += scale;
byte rdistort = cos8((cos8(((x<<3)+a )&255)+cos8(((y<<3)-a2)&255)+a3 )&255)>>1;
byte gdistort = cos8((cos8(((x<<3)-a2)&255)+cos8(((y<<3)+a3)&255)+a+32 )&255)>>1;
byte bdistort = cos8((cos8(((x<<3)+a3)&255)+cos8(((y<<3)-a) &255)+a2+64)&255)>>1;
byte rdistort = cos8_t((cos8_t(((x<<3)+a )&255)+cos8_t(((y<<3)-a2)&255)+a3 )&255)>>1;
byte gdistort = cos8_t((cos8_t(((x<<3)-a2)&255)+cos8_t(((y<<3)+a3)&255)+a+32 )&255)>>1;
byte bdistort = cos8_t((cos8_t(((x<<3)+a3)&255)+cos8_t(((y<<3)-a) &255)+a2+64)&255)>>1;
byte valueR = rdistort+ w* (a- ( ((xoffs - cx) * (xoffs - cx) + (yoffs - cy) * (yoffs - cy))>>7 ));
byte valueG = gdistort+ w* (a2-( ((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1))>>7 ));
byte valueB = bdistort+ w* (a3-( ((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2))>>7 ));
valueR = gamma8(cos8(valueR));
valueG = gamma8(cos8(valueG));
valueB = gamma8(cos8(valueB));
valueR = gamma8(cos8_t(valueR));
valueG = gamma8(cos8_t(valueG));
valueB = gamma8(cos8_t(valueB));
SEGMENT.setPixelColorXY(x, y, RGBW32(valueR, valueG, valueB, 0));
}
@@ -8622,8 +8623,11 @@ uint16_t mode_2Doctopus() {
const uint16_t C_Y = rows / 2 + (SEGMENT.custom2 - 128)*rows/255;
for (int x = xStart; x < xEnd; x++) {
for (int y = yStart; y < yEnd; y++) {
rMap[XY(x, y)].angle = int(40.7436f * atan2f((y - C_Y), (x - C_X))); // avoid 128*atan2()/PI
rMap[XY(x, y)].radius = hypotf(x - C_X, y - C_Y) * mapp; //thanks Sutaburosu
int dx = (x - C_X);
int dy = (y - C_Y);
rMap[XY(x, y)].angle = int(40.7436f * atan2f(dy, dx)); // avoid 128*atan2()/PI
//rMap[XY(x, y)].radius = hypotf(x - C_X, y - C_Y) * mapp; //thanks Sutaburosu
rMap[XY(x, y)].radius = sqrtf(dx * dx + dy * dy) * mapp; //thanks Sutaburosu
}
}
}
@@ -8641,12 +8645,12 @@ uint16_t mode_2Doctopus() {
for (int y = yStart; y < yEnd; y++) {
byte angle = rMap[XY(x,y)].angle;
byte radius = rMap[XY(x,y)].radius;
//CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1)));
//CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8_t(sin8_t((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1)));
uint16_t intensity;
if (SEGMENT.check3)
intensity = sin8(octoSpeed + sin8(octoSpeed - radius) + angle * (SEGMENT.custom3/4+1)); // RadialWave
intensity = sin8_t(octoSpeed + sin8_t(octoSpeed - radius) + angle * (SEGMENT.custom3/4+1)); // RadialWave
else
intensity = sin8(sin8((angle * 4 - radius) / 4 + octoSpeed) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1)); // Octopus
intensity = sin8_t(sin8_t((angle * 4 - radius) / 4 + octoSpeed) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1)); // Octopus
//intensity = map(intensity*intensity, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display
intensity = (intensity * intensity) / 255; // WLEDMM same as above, but faster and a bit more accurate
CRGB c = ColorFromPalette(SEGPALETTE, colorSpeed - radius, intensity);
@@ -8671,7 +8675,7 @@ uint16_t mode_2Dwavingcell() {
uint8_t aY = SEGMENT.custom2/16 + 1;
uint8_t aZ = SEGMENT.custom3 + 1;
for (int x = 0; x < cols; x++) for (int y = 0; y <rows; y++)
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, ((sin8((x*aX)+sin8((y+t)*aY))+cos8(y*aZ))+1)+t));
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, ((sin8_t((x*aX)+sin8_t((y+t)*aY))+cos8_t(y*aZ))+1)+t));
return FRAMETIME;
}
@@ -8883,10 +8887,10 @@ uint16_t mode_2DPaintbrush() {
for (size_t i = 0; i < numLines; i++) {
byte bin = map(i,0,numLines,0,15);
byte x1 = beatsin8(max(16,int(SEGMENT.speed))/16*1 + fftResult[0]/16, 0, (cols-1), fftResult[bin], SEGENV.aux1);
byte x2 = beatsin8(max(16,int(SEGMENT.speed))/16*2 + fftResult[0]/16, 0, (cols-1), fftResult[bin], SEGENV.aux1);
byte y1 = beatsin8(max(16,int(SEGMENT.speed))/16*3 + fftResult[0]/16, 0, (rows-1), fftResult[bin], SEGENV.aux1);
byte y2 = beatsin8(max(16,int(SEGMENT.speed))/16*4 + fftResult[0]/16, 0, (rows-1), fftResult[bin], SEGENV.aux1);
byte x1 = beatsin8_t(max(16,int(SEGMENT.speed))/16*1 + fftResult[0]/16, 0, (cols-1), fftResult[bin], SEGENV.aux1);
byte x2 = beatsin8_t(max(16,int(SEGMENT.speed))/16*2 + fftResult[0]/16, 0, (cols-1), fftResult[bin], SEGENV.aux1);
byte y1 = beatsin8_t(max(16,int(SEGMENT.speed))/16*3 + fftResult[0]/16, 0, (rows-1), fftResult[bin], SEGENV.aux1);
byte y2 = beatsin8_t(max(16,int(SEGMENT.speed))/16*4 + fftResult[0]/16, 0, (rows-1), fftResult[bin], SEGENV.aux1);
int length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
length = map8(fftResult[bin],0,length);

View File

@@ -379,6 +379,11 @@ uint8_t extractModeSlider(uint8_t mode, uint8_t slider, char *dest, uint8_t maxL
int16_t extractModeDefaults(uint8_t mode, const char *segVar);
void checkSettingsPIN(const char *pin);
uint16_t __attribute__((pure)) crc16(const unsigned char* data_p, size_t length); // WLEDMM: added attribute pure
uint16_t beatsin88_t(accum88 beats_per_minute_88, uint16_t lowest = 0, uint16_t highest = 65535, uint32_t timebase = 0, uint16_t phase_offset = 0);
uint16_t beatsin16_t(accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535, uint32_t timebase = 0, uint16_t phase_offset = 0);
uint8_t beatsin8_t(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, uint32_t timebase = 0, uint8_t phase_offset = 0);
um_data_t* simulateSound(uint8_t simulationId);
// WLEDMM enumerateLedmaps(); moved to FX.h
uint8_t get_random_wheel_index(uint8_t pos);
@@ -410,27 +415,39 @@ void clearEEPROM();
#endif
//wled_math.cpp
#ifndef WLED_USE_REAL_MATH
template <typename T> T atan_t(T x);
float cos_t(float phi) __attribute__((const));
float sin_t(float x) __attribute__((const));
float tan_t(float x) __attribute__((const));
float acos_t(float x);
float asin_t(float x);
float atan_t(float x) __attribute__((const));
float floor_t(float x) __attribute__((const));
float fmod_t(float num, float denom) __attribute__((const));
#else
#include <math.h> // WLEDMM use "float" variants
#define sin_t sinf
#define cos_t cosf
#define tan_t tanf
//float cos_t(float phi); // use float math
//float sin_t(float phi);
//float tan_t(float x);
int16_t sin16_t(uint16_t theta);
int16_t cos16_t(uint16_t theta);
uint8_t sin8_t(uint8_t theta);
uint8_t cos8_t(uint8_t theta);
float sin_approx(float theta); // uses integer math (converted to float), accuracy +/-0.0015 (compared to sinf())
float cos_approx(float theta);
float tan_approx(float x);
//float atan2_t(float y, float x);
//float acos_t(float x);
//float asin_t(float x);
//template <typename T> T atan_t(T x);
//float floor_t(float x);
//float fmod_t(float num, float denom);
#define sin_t sin_approx
#define cos_t cos_approx
#define tan_t tan_approx
#include <math.h> // standard math functions. use a lot of flash
#define atan2_t atan2f
#define asin_t asinf
#define acos_t acosf
#define atan_t atanf
#define fmod_t fmodf
#define floor_t floorf
#endif
/*
#define sin_t sinf
#define cos_t cosf
#define tan_t tanf
*/
//wled_serial.cpp
void handleSerial();

View File

@@ -423,6 +423,39 @@ uint16_t crc16(const unsigned char* data_p, size_t length) {
return crc;
}
// fastled beatsin: 1:1 replacements to remove the use of fastled sin16()
// Generates a 16-bit sine wave at a given BPM that oscillates within a given range. see fastled for details.
uint16_t beatsin88_t(accum88 beats_per_minute_88, uint16_t lowest, uint16_t highest, uint32_t timebase, uint16_t phase_offset)
{
uint16_t beat = beat88( beats_per_minute_88, timebase);
uint16_t beatsin (sin16_t( beat + phase_offset) + 32768);
uint16_t rangewidth = highest - lowest;
uint16_t scaledbeat = scale16( beatsin, rangewidth);
uint16_t result = lowest + scaledbeat;
return result;
}
// Generates a 16-bit sine wave at a given BPM that oscillates within a given range. see fastled for details.
uint16_t beatsin16_t(accum88 beats_per_minute, uint16_t lowest, uint16_t highest, uint32_t timebase, uint16_t phase_offset)
{
uint16_t beat = beat16( beats_per_minute, timebase);
uint16_t beatsin = (sin16_t( beat + phase_offset) + 32768);
uint16_t rangewidth = highest - lowest;
uint16_t scaledbeat = scale16( beatsin, rangewidth);
uint16_t result = lowest + scaledbeat;
return result;
}
// Generates an 8-bit sine wave at a given BPM that oscillates within a given range. see fastled for details.
uint8_t beatsin8_t(accum88 beats_per_minute, uint8_t lowest, uint8_t highest, uint32_t timebase, uint8_t phase_offset)
{
uint8_t beat = beat8( beats_per_minute, timebase);
uint8_t beatsin = sin8_t( beat + phase_offset);
uint8_t rangewidth = highest - lowest;
uint8_t scaledbeat = scale8( beatsin, rangewidth);
uint8_t result = lowest + scaledbeat;
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Begin simulateSound (to enable audio enhanced effects to display something)
@@ -487,8 +520,8 @@ um_data_t* simulateSound(uint8_t simulationId)
default:
case UMS_BeatSin:
for (int i = 0; i<16; i++)
fftResult[i] = beatsin8(120 / (i+1), 0, 255);
// fftResult[i] = (beatsin8(120, 0, 255) + (256/16 * i)) % 256;
fftResult[i] = beatsin8_t(120 / (i+1), 0, 255);
// fftResult[i] = (beatsin8_t(120, 0, 255) + (256/16 * i)) % 256;
volumeSmth = fftResult[8];
break;
case UMS_WeWillRockYou:
@@ -525,12 +558,12 @@ um_data_t* simulateSound(uint8_t simulationId)
break;
case UMS_10_13:
for (int i = 0; i<16; i++)
fftResult[i] = inoise8(beatsin8(90 / (i+1), 0, 200)*15 + (ms>>10), ms>>3);
fftResult[i] = inoise8(beatsin8_t(90 / (i+1), 0, 200)*15 + (ms>>10), ms>>3);
volumeSmth = fftResult[8];
break;
case UMS_14_3:
for (int i = 0; i<16; i++)
fftResult[i] = inoise8(beatsin8(120 / (i+1), 10, 30)*10 + (ms>>14), ms>>3);
fftResult[i] = inoise8(beatsin8_t(120 / (i+1), 10, 30)*10 + (ms>>14), ms>>3);
volumeSmth = fftResult[8];
break;
}

View File

@@ -10,16 +10,25 @@
//#define WLED_DEBUG_MATH
// Note: cos_t, sin_t and tan_t are very accurate but slow
// the math.h functions use several kB of flash and are to be avoided if possible
// sin16_t / cos16_t are faster and much more accurate than the fastled variants
// sin_approx and cos_approx are float wrappers for sin16_t/cos16_t and have an accuracy better than +/-0.0015 compared to sinf()
// sin8_t / cos8_t are fastled replacements and use sin16_t / cos16_t. Slightly slower than fastled version but very accurate
// Taylor series approximations, replaced with Bhaskara I's approximation
/*
#define modd(x, y) ((x) - (int)((x) / (y)) * (y))
float cos_t(float phi)
{
float x = modd(phi, TWO_PI);
float x = modd(phi, M_TWOPI);
if (x < 0) x = -1 * x;
int8_t sign = 1;
if (x > PI)
if (x > M_PI)
{
x -= PI;
x -= M_PI;
sign = -1;
}
float xx = x * x;
@@ -31,8 +40,8 @@ float cos_t(float phi)
return res;
}
float sin_t(float x) {
float res = cos_t(HALF_PI - x);
float sin_t(float phi) {
float res = cos_t(M_PI_2 - phi);
#ifdef WLED_DEBUG_MATH
Serial.printf("sin: %f,%f,%f,(%f)\n",x,res,sin(x),res-sin(x));
#endif
@@ -48,6 +57,81 @@ float tan_t(float x) {
#endif
return res;
}
*/
// 16-bit, integer based Bhaskara I's sine approximation: 16*x*(pi - x) / (5*pi^2 - 4*x*(pi - x))
// input is 16bit unsigned (0-65535), output is 16bit signed (-32767 to +32767)
// optimized integer implementation by @dedehai
int16_t sin16_t(uint16_t theta) {
int scale = 1;
if (theta > 0x7FFF) {
theta = 0xFFFF - theta;
scale = -1; // second half of the sine function is negative (pi - 2*pi)
}
uint32_t precal = theta * (0x7FFF - theta);
uint64_t numerator = (uint64_t)precal * (4 * 0x7FFF); // 64bit required
int32_t denominator = 1342095361 - precal; // 1342095361 is 5 * 0x7FFF^2 / 4
int16_t result = numerator / denominator;
return result * scale;
}
int16_t cos16_t(uint16_t theta) {
return sin16_t(theta + 0x4000); //cos(x) = sin(x+pi/2)
}
uint8_t sin8_t(uint8_t theta) {
int32_t sin16 = sin16_t((uint16_t)theta * 257); // 255 * 257 = 0xFFFF
sin16 += 0x7FFF + 128; //shift result to range 0-0xFFFF, +128 for rounding
return min(sin16, int32_t(0xFFFF)) >> 8; // min performs saturation, and prevents overflow
}
uint8_t cos8_t(uint8_t theta) {
return sin8_t(theta + 64); //cos(x) = sin(x+pi/2)
}
float sin_approx(float theta) {
uint16_t scaled_theta = (int)(theta * (float)(0xFFFF / M_TWOPI)); // note: do not cast negative float to uint! cast to int first (undefined on C3)
int32_t result = sin16_t(scaled_theta);
float sin = float(result) / 0x7FFF;
return sin;
}
float cos_approx(float theta) {
uint16_t scaled_theta = (int)(theta * (float)(0xFFFF / M_TWOPI)); // note: do not cast negative float to uint! cast to int first (undefined on C3)
int32_t result = sin16_t(scaled_theta + 0x4000);
float cos = float(result) / 0x7FFF;
return cos;
}
float tan_approx(float x) {
float c = cos_approx(x);
if (c==0.0f) return 0;
float res = sin_approx(x) / c;
return res;
}
#if 0 // WLEDMM we prefer libm functions that are accurate and fast.
#define ATAN2_CONST_A 0.1963f
#define ATAN2_CONST_B 0.9817f
// atan2_t approximation, with the idea from https://gist.github.com/volkansalma/2972237?permalink_comment_id=3872525#gistcomment-3872525
float atan2_t(float y, float x) {
float abs_y = fabs(y);
float abs_x = fabs(x);
float r = (abs_x - abs_y) / (abs_y + abs_x + 1e-10f); // avoid division by zero by adding a small nubmer
float angle;
if(x < 0) {
r = -r;
angle = M_PI_2 + M_PI_4;
}
else
angle = M_PI_2 - M_PI_4;
float add = (ATAN2_CONST_A * (r * r) - ATAN2_CONST_B) * r;
angle += add;
angle = y < 0 ? -angle : angle;
return angle;
}
//https://stackoverflow.com/questions/3380628
// Absolute error <= 6.7e-5
@@ -60,10 +144,10 @@ float acos_t(float x) {
ret = ret * xabs;
ret = ret - 0.2121144f;
ret = ret * xabs;
ret = ret + HALF_PI;
ret = ret + M_PI_2;
ret = ret * sqrt(1.0f-xabs);
ret = ret - 2 * negate * ret;
float res = negate * PI + ret;
float res = negate * M_PI + ret;
#ifdef WLED_DEBUG_MATH
Serial.printf("acos: %f,%f,%f,(%f)\n",x,res,acos(x),res-acos(x));
#endif
@@ -71,7 +155,7 @@ float acos_t(float x) {
}
float asin_t(float x) {
float res = HALF_PI - acos_t(x);
float res = M_PI_2 - acos_t(x);
#ifdef WLED_DEBUG_MATH
Serial.printf("asin: %f,%f,%f,(%f)\n",x,res,asin(x),res-asin(x));
#endif
@@ -87,7 +171,7 @@ float atan_t(float x) {
//For A/B/C, see https://stackoverflow.com/a/42542593
static const double A { 0.0776509570923569 };
static const double B { -0.287434475393028 };
static const double C { ((HALF_PI/2) - A - B) };
static const double C { ((M_PI_4) - A - B) };
// polynominal factors for approximation between 1 and 5
static const float C0 { 0.089494f };
static const float C1 { 0.974207f };
@@ -102,7 +186,7 @@ float atan_t(float x) {
x = std::abs(x);
float res;
if (x > 5.0f) { // atan(x) converges to pi/2 - (1/x) for large values
res = HALF_PI - (1.0f/x);
res = M_PI_2 - (1.0f/x);
} else if (x > 1.0f) { //1 < x < 5
float xx = x * x;
res = (C4*xx*xx)+(C3*xx*x)+(C2*xx)+(C1*x)+C0;
@@ -137,3 +221,5 @@ float fmod_t(float num, float denom) {
#endif
return res;
}
#endif // WLEDMM