diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 4a364ea654..2de19ad54a 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -7248,6 +7248,91 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. } // mode_2DGEQ() static const char _data_FX_MODE_2DGEQ[] PROGMEM = "GEQ@Fade speed,Ripple decay,# of bands,,,Color bars;!,,Peaks;!;2f;c1=255,c2=64,pal=11,si=0"; // Beatsin +///////////////////////// +// Single EQ Bar // +///////////////////////// +uint16_t mode_single_eqbar(void) { + if (!SEGENV.allocateData(sizeof(uint16_t))) return mode_static(); + uint16_t *prevBarHeight = (uint16_t*)SEGENV.data; + if (SEGENV.call == 0) *prevBarHeight = 0; + + // Grab audio data - we only need the fftResult here, as we want the frequency data + um_data_t *um_data = getAudioData(); + uint8_t *fftResult = (uint8_t*)um_data->u_data[2]; + if (!fftResult) return mode_static(); + bool is2d = (strip.isMatrix || SEGMENT.is2D()); + + // User controls. Speed is referenced directly instead of creating a new varible. + uint8_t freqBin = map(SEGMENT.custom1, 0, 255, 0, 15); // 0-15 (or up to available bins) + uint8_t peakDecay = SEGMENT.intensity; + if (peakDecay > 0){ + // Grab the intensity value for peak decay speed, bound it between 1 and 32, invert for ease of use. + peakDecay = map(255 - SEGMENT.intensity, 1, 255, 1, 32); + } + int barHeight = 0; + if (strip.isMatrix || SEGMENT.is2D()){ + barHeight = map(fftResult[freqBin], 0, 255, 0, SEG_H); // Grab new bar height + } else { + barHeight = map(fftResult[freqBin], 0, 255, 0, SEGLEN); // Grab new bar height + } + if (barHeight > *prevBarHeight) *prevBarHeight = barHeight; // Update the previous bar height if the new height is greater + + SEGMENT.fade_out(SEGMENT.speed); // Always fade out existing bars according to speed slider. + + // Draw the main bar (but not peak pixel) + for (int i = 0; i < barHeight; i++) { + if (is2d){ + // If we are in a matrix or 2D segment, draw the bar vertically + for (int j = 0; j < SEG_W; j++) { + SEGMENT.setPixelColorXY(j, i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + } + } else { + // Otherwise draw the bar horizontally + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + } + } + + if (peakDecay == 0){ + // No peak pixel if decay is set to zero, just draw the peak pixel of the bar. + if (barHeight > 0) { + if (is2d) { + for (int j = 0; j < SEG_W; j++) { + SEGMENT.setPixelColorXY(j, barHeight, SEGMENT.color_from_palette(barHeight, true, PALETTE_SOLID_WRAP, 0)); + } + } else { + SEGMENT.setPixelColor(barHeight, SEGMENT.color_from_palette(barHeight, true, PALETTE_SOLID_WRAP, 0)); + } + } + } else { + // Decrement prevBarHeight according to peakDecay + if (*prevBarHeight > 0 && (SEGENV.call % (peakDecay > 1 ? peakDecay : 1)) == 0) (*prevBarHeight)--; + + // Set peak pixel and clear pixels over peak (otherwise they would fadewith value from speed slider) + if (*prevBarHeight > 0) { + + if (is2d) { + for (int j = 0; j < SEG_W; j++) { + SEGMENT.setPixelColorXY(j, *prevBarHeight, SEGCOLOR(2)); + } + } else { + SEGMENT.setPixelColor(*prevBarHeight, SEGCOLOR(2)); + } + } + if (*prevBarHeight < SEGLEN) { + + if (is2d) { + for (int j = 0; j < SEG_W; j++) { + SEGMENT.setPixelColorXY(j, *prevBarHeight + 1, BLACK); // clear next pixel immediately. + } + } else { + SEGMENT.setPixelColor(*prevBarHeight + 1, BLACK); // clear next pixel immediately. + } + } + } + + return FRAMETIME; +} +static const char _data_FX_MODE_SINGLE_EQBAR[] PROGMEM = "Single EQ Bar@Fade speed,Peak decay,Frequency bin;!,,Peaks;!;!;12vf;sx=128,ix=170,c1=128,si=0"; ///////////////////////// // ** 2D Funky plank // @@ -10818,5 +10903,6 @@ addEffect(FX_MODE_PS1DSONICSTREAM, &mode_particle1DsonicStream, _data_FX_MODE_PS addEffect(FX_MODE_PS1DSONICBOOM, &mode_particle1DsonicBoom, _data_FX_MODE_PS_SONICBOOM); addEffect(FX_MODE_PS1DSPRINGY, &mode_particleSpringy, _data_FX_MODE_PS_SPRINGY); #endif // WLED_DISABLE_PARTICLESYSTEM1D +addEffect(FX_MODE_SINGLE_EQBAR, &mode_single_eqbar, _data_FX_MODE_SINGLE_EQBAR); } diff --git a/wled00/FX.h b/wled00/FX.h index 82213179bd..0db5eeddd2 100755 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -374,6 +374,7 @@ extern byte realtimeMode; // used in getMappedPixelIndex() #define FX_MODE_PS1DSPRINGY 216 #define FX_MODE_PARTICLEGALAXY 217 #define MODE_COUNT 218 +#define FX_MODE_SINGLE_EQBAR 219 #define BLEND_STYLE_FADE 0x00 // universal