34#define NUM_LEDS (WIDTH * HEIGHT)
36#define LED_TYPE WS2812B
37#define COLOR_ORDER GRB
40#define SAMPLE_RATE 44100
50 {
"Spectrum Bars",
"Radial Spectrum",
"Waveform",
"VU Meter",
"Matrix Rain",
"Fire Effect",
"Plasma Wave"});
61 {
"Rainbow",
"Heat",
"Ocean",
"Forest",
"Party",
"Lava",
"Cloud"});
111 case 0:
return fl::CRGBPalette16(fl::RainbowColors_p);
112 case 1:
return fl::CRGBPalette16(fl::HeatColors_p);
113 case 2:
return fl::CRGBPalette16(fl::OceanColors_p);
114 case 3:
return fl::CRGBPalette16(fl::ForestColors_p);
115 case 4:
return fl::CRGBPalette16(fl::PartyColors_p);
116 case 5:
return fl::CRGBPalette16(fl::LavaColors_p);
117 case 6:
return fl::CRGBPalette16(fl::CloudColors_p);
118 default:
return fl::CRGBPalette16(fl::RainbowColors_p);
129 for (
int i = 0; i < 20; i++) {
136 for (
int i = 0; i < 20; i++) {
144 uint32_t currentTime = millis();
146 if (energy > threshold && (currentTime -
lastBeatTime) > 80) {
160 static float targetLevel = 0.7f;
161 static float avgLevel = 0.0f;
163 avgLevel = avgLevel * 0.95f + level * 0.05f;
165 if (avgLevel > 0.01f) {
166 float gainAdjust = targetLevel / avgLevel;
167 gainAdjust =
fl::clamp(gainAdjust, 0.5f, 2.0f);
188 auto bands =
fft->db();
190 for (
size_t band = 0; band <
NUM_BANDS && band < bands.size(); band++) {
191 float magnitude = bands[band];
194 magnitude = magnitude / 100.0f;
203 magnitude =
fl::clamp(magnitude, 0.0f, 1.0f);
205 int barHeight = magnitude *
HEIGHT;
206 int xStart = band * barWidth;
208 for (
int x = 0;
x <
fl::max(barWidth, 1);
x++) {
209 for (
int y = 0;
y < barHeight;
y++) {
211 float(
y) /
HEIGHT, 0, 1, 0, 255
215 int ledIndex =
xyMap(xStart +
x,
y);
216 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
217 leds[ledIndex] = color;
222 if (mirrorIndex >= 0 && mirrorIndex <
NUM_LEDS) {
223 leds[mirrorIndex] = color;
236 int centerX =
WIDTH / 2;
239 auto bands =
fft->db();
241 for (
size_t angle = 0; angle < 360; angle += 6) {
243 if (band >= bands.size())
continue;
245 float magnitude = bands[band] / 100.0f;
248 magnitude =
fl::clamp(magnitude, 0.0f, 1.0f);
252 for (
int r = 0; r < radius; r++) {
259 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
272 int samplesPerPixel = pcm.
size() /
WIDTH;
275 for (
size_t x = 0;
x <
WIDTH;
x++) {
276 size_t sampleIndex =
x * samplesPerPixel;
277 if (sampleIndex >= pcm.
size())
break;
280 float sample = float(pcm[sampleIndex]) / 32768.0f;
284 float logAmplitude = 0.0f;
286 if (absSample > 0.001f) {
293 logAmplitude =
fl::powf(logAmplitude, 0.7f);
296 int amplitude = int(logAmplitude * (
HEIGHT / 2));
300 if (sample < 0) amplitude = -amplitude;
312 if (amplitude == 0) {
314 int ledIndex =
xyMap(
x, centerY);
315 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
320 int startY = (amplitude > 0) ? centerY : centerY + amplitude;
321 int endY = (amplitude > 0) ? centerY + amplitude : centerY;
323 for (
int y = startY;
y <= endY;
y++) {
326 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
329 if (
y == startY ||
y == endY) {
332 leds[ledIndex] = pixelColor;
349 for (
int x = 0;
x < rmsWidth;
x++) {
353 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
364 int ledIndex =
xyMap(peakX,
y);
365 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
373 int ledIndex1 =
xyMap(
x, 0);
386 int currentIndex =
xyMap(
x,
y);
387 int aboveIndex =
xyMap(
x,
y - 1);
388 if (currentIndex >= 0 && currentIndex <
NUM_LEDS &&
389 aboveIndex >= 0 && aboveIndex <
NUM_LEDS) {
390 leds[currentIndex] =
leds[aboveIndex];
391 leds[currentIndex].fadeToBlackBy(40);
398 for (
int i = 0; i < numDrops; i++) {
400 int ledIndex =
xyMap(
x, 0);
401 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
402 leds[ledIndex] =
CHSV(96, 255, 255);
420 heatLevel = heatLevel * random(80, 120) / 100;
421 heatLevel =
fl::min(heatLevel, 255);
424 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
433 static float time = 0;
434 time += 0.05f + (peak * 0.2f);
440 float value =
fl::sinf(
x * 0.1f + time) +
445 value = (value + 4) / 8;
448 uint8_t colorIndex = value * 255;
450 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
461 Serial.println(
"Audio Reactive Visualizations");
462 Serial.println(
"Initializing...");
463 Serial.print(
"Display size: ");
482 pitchEngine->onNoteOn = [](uint8_t note, uint8_t velocity) {
486 Serial.print(
"Note ON: ");
494 Serial.print(
"Note OFF: ");
498 Serial.println(
"Setup complete!");
513 if (sample.isValid()) {
519 for (
size_t i = 0; i < numSamples; i++) {
520 floatBuffer[i] = sample.pcm()[i] / 32768.0f;
522 pitchEngine->processFrame(floatBuffer, numSamples);
529 float rms = sample.rms() / 32768.0f;
532 int32_t maxSample = 0;
533 for (
size_t i = 0; i < sample.pcm().size(); i++) {
534 int32_t absSample =
fl::fabsf(sample.pcm()[i]);
535 if (absSample > maxSample) {
536 maxSample = absSample;
539 float peak = float(maxSample) / 32768.0f;
552 sample.fft(&fftBins);
559 for (
int i = 0; i <
NUM_LEDS; i++) {
560 leds[i].fadeLightBy(-50);
602 notePos =
fl::clamp(notePos, 0.0f, 1.0f);
603 int noteX = notePos * (
WIDTH - 1);
611 for (
int dx = -2; dx <= 2; dx++) {
614 int ledIndex =
xyMap(
x, noteY);
615 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
616 leds[ledIndex] = pitchColor;
620 for (
int dy = -2; dy <= 2; dy++) {
623 int ledIndex =
xyMap(noteX,
y);
624 if (ledIndex >= 0 && ledIndex <
NUM_LEDS) {
625 leds[ledIndex] = pitchColor;
635 #ifdef __EMSCRIPTEN__
fl::UIAudio audio("Audio Input")
fl::UIDescription description("Demo of the Animatrix effects. @author of fx is StefanPetrick")
fl::UITitle title("Animartrix")
fl::UISlider brightness("Brightness", BRIGHTNESS, 0, 255)
float rms(fl::span< const int16_t > data)
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
constexpr enable_if< is_fixed_point< T >::value, T >::type abs(T x) FL_NOEXCEPT
UINumberField palette("Palette", 0, 0, 2)
fl::UIDropdown visualMode("Visualization Mode", {"Spectrum Bars", "Radial Spectrum", "Waveform", "VU Meter", "Matrix Rain", "Fire Effect", "Plasma Wave"})
void drawRadialSpectrum(fl::audio::fft::Bins *fft, float)
void drawMatrixRain(float peak)
bool detectBeat(float energy)
fl::CRGBPalette16 getCurrentPalette()
static const int NUM_BANDS
float fftSmooth[NUM_BANDS]
void drawVUMeter(float rms, float peak)
fl::UISlider fadeSpeed("Fade Speed", 20, 0, 255, 1)
fl::SoundToMIDI pitchConfig
uint8_t fireBuffer[WIDTH][HEIGHT]
void drawFireEffect(float peak)
void updateAutoGain(float level)
fl::UICheckbox beatDetect("Beat Detection", true)
fl::UICheckbox pitchDetectEnable("Pitch Detection", false)
fl::UISlider noiseFloor("Noise Floor", 0.1f, 0.0f, 1.0f, 0.01f)
fl::UICheckbox pitchVisualizer("Show Pitch Visualizer", false)
fl::UIDropdown colorPalette("Color Palette", {"Rainbow", "Heat", "Ocean", "Forest", "Party", "Lava", "Cloud"})
fl::UICheckbox autoGain("Auto Gain", true)
fl::UICheckbox enableAudio("Enable Audio", true)
fl::UICheckbox mirrorMode("Mirror Mode", false)
fl::UISlider audioGain("Audio Gain", 1.0f, 0.1f, 5.0f, 0.1f)
fl::UICheckbox beatFlash("Beat Flash", true)
void drawSpectrumBars(fl::audio::fft::Bins *fft, float)
void drawWaveform(const fl::span< const int16_t > &pcm, float)
float plasma[WIDTH][HEIGHT]
void drawPlasmaWave(float peak)
fl::audio::SoundLevelMeter soundMeter(0.0, 0.0)
fl::UISlider beatSensitivity("Beat Sensitivity", 1.5f, 0.5f, 3.0f, 0.1f)
fl::SoundToMIDIEngine * pitchEngine
constexpr fl::size size() const FL_NOEXCEPT
void fadeToBlackBy(CRGB *leds, fl::u16 num_leds, fl::u8 fadeBy)
CRGB ColorFromPalette(const CRGBPalette16 &pal, fl::u8 index, fl::u8 brightness, TBlendType blendType)
void fill_rainbow(CRGB *targetArray, int numToFill, fl::u8 initialhue, fl::u8 deltahue=5) FL_NOEXCEPT
Fill a range of LEDs with a rainbow of colors.
CRGB HeatColor(fl::u8 temperature)
void fill_solid(CRGB *targetArray, int numToFill, const CRGB &color) FL_NOEXCEPT
Fill a range of LEDs with a solid color.
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NOEXCEPT
float sqrtf(float value) FL_NOEXCEPT
constexpr common_type_t< T, U > max(T a, U b) FL_NOEXCEPT
float powf(float base, float exponent) FL_NOEXCEPT
FASTLED_FORCE_INLINE U map_range(T value, T in_min, T in_max, U out_min, U out_max) FL_NOEXCEPT
constexpr enable_if< is_fixed_point< T >::value, T >::type sqrt(T x) FL_NOEXCEPT
float sinf(float value) FL_NOEXCEPT
float log10f(float value) FL_NOEXCEPT
float fabsf(float value) FL_NOEXCEPT
float cosf(float value) FL_NOEXCEPT
constexpr enable_if< is_fixed_point< T >::value, T >::type clamp(T x, T lo, T hi) FL_NOEXCEPT
#define FL_DISABLE_WARNING(warning)
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_POP
CRGB & fadeToBlackBy(u8 fadefactor) FL_NOEXCEPT
fadeToBlackBy is a synonym for nscale8(), as a fade instead of a scale
@ White
<div style='background:#FFFFFF;width:4em;height:4em;'></div>
@ Black
<div style='background:#000000;width:4em;height:4em;'></div>
Representation of an 8-bit RGB pixel (Red, Green, Blue)
Aggregator header for the fl/ui/ family of per-element UI types.