Skip to content

Commit

Permalink
added rotating GEQ, work in progress
Browse files Browse the repository at this point in the history
-animation works but sliders are too sensitive. need to adjust the ranges
  • Loading branch information
DedeHai committed Mar 20, 2024
1 parent 7991776 commit a56d888
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 2 deletions.
141 changes: 140 additions & 1 deletion wled00/FX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9377,7 +9377,7 @@ uint16_t mode_particleGEQ(void)
for (bin = 0; bin < 16; bin++)
{
uint32_t xposition = binwidth*bin + (binwidth>>1); // emit position according to frequency band
uint8_t emitspeed = 5+((uint32_t)fftResult[bin]*(uint32_t)SEGMENT.speed)>>9; // emit speed according to loudness of band
uint8_t emitspeed = 5 + (((uint32_t)fftResult[bin]*(uint32_t)SEGMENT.speed)>>9); // emit speed according to loudness of band
emitparticles = 0;

if (fftResult[bin] > threshold)
Expand Down Expand Up @@ -9432,6 +9432,144 @@ uint16_t mode_particleGEQ(void)
}
static const char _data_FX_MODE_PARTICLEGEQ[] PROGMEM = "Particle GEQ@Speed,Intensity,Randomness,Collision hardness,Gravity,Wrap X,Side bounce,Ground bounce;;!;012;pal=54,sx=100,ix=200,c1=0,c2=0,c3=0,o1=0,o2=0,o3=0";

/*
* Particle rotating spray
* Particles sprayed from center with a rotating spray
* Uses palette for particle color
* by DedeHai (Damian Schneider)
*/

uint16_t mode_particlecenterGEQ(void)
{

if (SEGLEN == 1)
return mode_static();

const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1;
const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength();

#ifdef ESP8266
const uint32_t numParticles = 50; // maximum number of particles
#else
const uint32_t numParticles = 500; // maximum number of particles
#endif

const uint8_t numSprays = 16; // maximum number of sprays

PSparticle *particles;
PSpointsource *spray;

// allocate memory and divide it into proper pointers, max is 32kB for all segments, 100 particles use 1200bytes
uint32_t dataSize = sizeof(PSparticle) * numParticles;
dataSize += sizeof(PSpointsource) * (numSprays);
if (!SEGENV.allocateData(dataSize))
return mode_static(); // allocation failed; //allocation failed

spray = reinterpret_cast<PSpointsource *>(SEGENV.data);
// calculate the end of the spray data and assign it as the data pointer for the particles:
particles = reinterpret_cast<PSparticle *>(spray + numSprays); // cast the data array into a particle pointer

uint32_t i = 0;
uint32_t j = 0;
uint8_t spraycount = 1 + (SEGMENT.custom2 >> 5); // number of sprays to display, 1-8

if (SEGMENT.call == 0) // initialization
{
SEGMENT.aux0 = 0; // starting angle
SEGMENT.aux1 = 0xFF; // user check
for (i = 0; i < numParticles; i++)
{
particles[i].ttl = 0;
}
for (i = 0; i < numSprays; i++)
{
spray[i].source.hue = i*16; //even color distribution
spray[i].source.sat = 255; // set saturation
spray[i].source.x = (cols * PS_P_RADIUS) / 2; // center
spray[i].source.y = (rows * PS_P_RADIUS) / 2; // center
spray[i].source.vx = 0;
spray[i].source.vy = 0;
spray[i].maxLife = 400;
spray[i].minLife = 200;
spray[i].vx = 0; // emitting speed
spray[i].vy = 0; // emitting speed
spray[i].var = 0; // emitting variation
}
}

um_data_t *um_data;
if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE))
{
// add support for no audio
um_data = simulateSound(SEGMENT.soundSim);
}

uint8_t *fftResult = (uint8_t *)um_data->u_data[2]; // 16 bins with FFT data, log mapped already, each band contains frequency amplitude 0-255

i = 0;

uint32_t threshold = 300 - SEGMENT.intensity;


uint8_t percycle = numSprays; // maximum number of particles emitted per cycle
i = 0;
j = random(numSprays); // start with random spray so all get a chance to emit a particle if maximum number of particles alive is reached.
if (SEGMENT.check2)
SEGMENT.aux0 += SEGMENT.custom1;
else
SEGMENT.aux0 -= SEGMENT.custom1;

uint32_t angleoffset = SEGMENT.aux0 >> 4;

while (i < numParticles)
{
if (particles[i].ttl == 0) // find a dead particle
{
uint8_t emitspeed = 5 + (((uint32_t)fftResult[j] * ((uint32_t)SEGMENT.speed+10)) >> 9); // emit speed according to loudness of band
uint8_t emitangle = j * 16 + random(SEGMENT.custom3 >> 1) + angleoffset;

uint32_t emitparticles = 0;
if (fftResult[j] > threshold)
{
emitparticles = 1; // + (fftResult[bin]>>6);
}
else if (fftResult[j] > 0) // band has low volue
{
uint32_t restvolume = ((threshold - fftResult[j]) >> 2) + 2;
if (random8() % restvolume == 0)
{
emitparticles = 1;
}
}
if (emitparticles)
Emitter_Angle_emit(&spray[j], &particles[i], emitangle, emitspeed);
j = (j + 1) % numSprays;
}
i++;
//todo: could add a break if all 16 sprays have been checked, would speed it up
}

/*
if (SEGMENT.check2)
SEGMENT.aux0 += SEGMENT.custom1 << 2;
else
SEGMENT.aux0 -= SEGMENT.custom1 << 2;
*/ //TODO: add rotation

for (i = 0; i < numParticles; i++)
{
Particle_Move_update(&particles[i], true); // move the particles, kill out of bounds particles
}

SEGMENT.fill(BLACK); // clear the matrix

// render the particles
ParticleSys_render(particles, numParticles, false, false);

return FRAMETIME;
}
static const char _data_FX_MODE_PARTICLECCIRCULARGEQ[] PROGMEM = "PS Center GEQ@Speed,Color Change,Particle Speed,Spray Count,Nozzle Size,Random Color, Direction;;!;012;pal=56,sx=0,ix=222,c1=190,c2=200,c3=0,o1=0,o2=0";

#endif // WLED_DISABLE_2D


Expand Down Expand Up @@ -9686,6 +9824,7 @@ void WS2812FX::setupEffectData() {
addEffect(FX_MODE_PARTICLEATTRACTOR, &mode_particleattractor, _data_FX_MODE_PARTICLEATTRACTOR);
addEffect(FX_MODE_PARTICLESPRAY, &mode_particlespray, _data_FX_MODE_PARTICLESPRAY);
addEffect(FX_MODE_PARTICLESGEQ, &mode_particleGEQ, _data_FX_MODE_PARTICLEGEQ);
addEffect(FX_MODE_PARTICLECENTERGEQ, &mode_particlecenterGEQ, _data_FX_MODE_PARTICLECCIRCULARGEQ);

#endif // WLED_DISABLE_2D

Expand Down
3 changes: 2 additions & 1 deletion wled00/FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,8 @@
#define FX_MODE_PARTICLEWATERFALL 196
#define FX_MODE_PARTICLESPRAY 197
#define FX_MODE_PARTICLESGEQ 198
#define MODE_COUNT 199
#define FX_MODE_PARTICLECENTERGEQ 199
#define MODE_COUNT 200

typedef enum mapping1D2D {
M12_Pixels = 0,
Expand Down

0 comments on commit a56d888

Please sign in to comment.