Skip to content

Commit

Permalink
added particle GEQ effect (untested)
Browse files Browse the repository at this point in the history
  • Loading branch information
DedeHai committed Mar 15, 2024
1 parent bdfb1a9 commit 87adbed
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 5 deletions.
119 changes: 115 additions & 4 deletions wled00/FX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8551,8 +8551,7 @@ uint16_t mode_particlefall(void)
particles[i].vy = -(SEGMENT.speed >> 1);
particles[i].hue = random8(); // set random color
particles[i].sat = ((SEGMENT.custom3) << 3) + 7; // set saturation
particles[i].collide = true; // particle will collide
break; // quit loop if all particles of this round emitted
particles[i].collide = true; // particle will collide
}
i++;
}
Expand Down Expand Up @@ -9316,6 +9315,119 @@ uint16_t mode_particlespray(void)
}
static const char _data_FX_MODE_PARTICLESPRAY[] PROGMEM = "Particle Spray@Particle Speed,Intensity,X Position,Y Position,Angle,Gravity,WrapX/Bounce,Collisions;;!;012;pal=0,sx=180,ix=200,c1=220,c2=30,c3=12,o1=1,o2=0,o3=1";

/*
Particle base Graphical Equalizer
Uses palette for particle color
by DedeHai (Damian Schneider)
*/

uint16_t mode_particleGEQ(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 = 150; // maximum number of particles
#else
const uint32_t numParticles = 500; // maximum number of particles
#endif

PSparticle *particles;

// allocate memory and divide it into proper pointers, max is 32k for all segments.
uint32_t dataSize = sizeof(PSparticle) * numParticles;
if (!SEGENV.allocateData(dataSize))
return mode_static(); // allocation failed; //allocation failed

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

if (SEGMENT.call == 0) // initialization
{
for (i = 0; i < numParticles; i++)
{
particles[i].ttl = 0;
particles[i].sat = 255; //full color
}
}

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

//map the bands into 16 positions on x axis, emit some particles according to frequency loudness
//Idea: emit 20 particles at full loudness, can use a shift for that, for example shift by 4 or 5
//in order to also emit particles for not so loud bands, get a bunch of particles based on frame counter and current loudness?
//implement it simply first, then add complexity... need to check what looks good
uint32_t i = 0;
uint32_t bin; //current bin
uint8_t binwidth = (cols * PS_P_RADIUS - 1)>>4; //emit poisition variation for one bin (+/-)

for (bin = 0; bin < 16; bin++)
{
uint32_t xposition = map(fftResult[band], 0, 255, cols * PS_P_RADIUS - 1); //emit position according to frequency band
uint8_t emitspeed = fftResult[band] >> 2; // emit speed according to loudness of band TODO: SEGMENT.speed?
uint8_t emitparticles = 0;
//wie sollen die emitted werden? man könnte anzahl berechnen, dann einen emit loop machen
if (fftResult[band] > 10)
{
emitparticles = fftResult[band]/10;
}
else if(fftResult[band] > 0)// band has low volue
{
uint32_t restvolume = 12 - fftResult[band];
if (random8() % restvolume == 0)
{
emitparticles = 1;
}
}
while (i < numParticles && emitparticles) // emit particles if there are any left, low frequencies take priority
{
if (particles[i].ttl == 0) // find a dead particle
{
//set particle properties
particles[i].ttl = emitspeed; // set particle alive, particle lifespan is in number of frames
particles[i].x = xposition + random8(binwidth) - binwidth>>1; //position randomly, deviating half a bin width
particles[i].y = 0; //start at the bottom
particles[i].vx = rand(9)-4; //x-speed variation
particles[i].vy = emitspeed;
particles[i].hue = bin<<4 + random8(binwidth) - binwidth>>1; // color from palette according to bin
//particles[i].sat = ((SEGMENT.custom3) << 3) + 7; // set saturation
}
emitparticles--;
i++;
}
}


uint8_t hardness = SEGMENT.custom2; // how hard the collisions are, 255 = full hard.
// detectCollisions(particles, numParticles, hardness);

// now move the particles
for (i = 0; i < numParticles; i++)
{
//Particle_Gravity_update(&particles[i], SEGMENT.check1, SEGMENT.check2, SEGMENT.check3, min(hardness, (uint8_t)150)); // surface hardness max is 150
Particle_Gravity_update(&particles[i], SEGMENT.check1, SEGMENT.check2, SEGMENT.check3, min(hardness, (uint8_t)150)); // surface hardness max is 150
}

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

// render the particles
ParticleSys_render(particles, numParticles, SEGMENT.check1, false); // custom3 slider is saturation, from 7 to 255, 7 is close enough to white (for snow for example)

return FRAMETIME;
}
static const char _data_FX_MODE_PARTICLEGEQ[] PROGMEM = "Particle GEQ@Speed,Intensity,Randomness,Collision hardness,Saturation,Wrap X,Side bounce,Ground bounce;;!;012;pal=11,sx=100,ix=200,c1=31,c2=0,c3=20,o1=0,o2=0,o3=1";

#endif // WLED_DISABLE_2D


Expand Down Expand Up @@ -9565,12 +9677,11 @@ void WS2812FX::setupEffectData() {
addEffect(FX_MODE_PARTICLEPERLIN, &mode_particleperlin, _data_FX_MODE_PARTICLEPERLIN);
addEffect(FX_MODE_PARTICLEFALL, &mode_particlefall, _data_FX_MODE_PARTICLEFALL);
addEffect(FX_MODE_PARTICLEBOX, &mode_particlebox, _data_FX_MODE_PARTICLEBOX);

//experimental
addEffect(FX_MODE_PARTICLEWATERFALL, &mode_particlewaterfall, _data_FX_MODE_PARTICLEWATERFALL);
addEffect(FX_MODE_PARTICLEIMPACT, &mode_particleimpact, _data_FX_MODE_PARTICLEIMPACT);
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);

#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 @@ -329,7 +329,8 @@
#define FX_MODE_PARTICLEIMPACT 195
#define FX_MODE_PARTICLEWATERFALL 196
#define FX_MODE_PARTICLESPRAY 197
#define MODE_COUNT 198
#define FX_MODE_PARTICLESGEQ 198
#define MODE_COUNT 199

typedef enum mapping1D2D {
M12_Pixels = 0,
Expand Down

0 comments on commit 87adbed

Please sign in to comment.