FastLED 3.9.15
Loading...
Searching...
No Matches
Audio.ino
Go to the documentation of this file.
1
2
3/*
4This demo is best viewed using the FastLED compiler.
5
6Windows/MacOS binaries: https://github.com/FastLED/FastLED/releases
7
8Python
9
10Install: pip install fastled
11Run: fastled <this sketch directory>
12This will compile and preview the sketch in the browser, and enable
13all the UI elements you see below.
14*/
15
16#if !SKETCH_HAS_LOTS_OF_MEMORY
17// Platform does not have enough memory
18void setup() {}
19void loop() {}
20#else
21
22#include <Arduino.h>
23#include <FastLED.h>
24
25#include "fl/audio.h"
26#include "fl/downscale.h"
27#include "fl/draw_visitor.h"
28#include "fl/fft.h"
29#include "fl/math.h"
30#include "fl/math_macros.h"
31#include "fl/raster.h"
32#include "fl/time_alpha.h"
33#include "fl/ui.h"
34#include "fl/xypath.h"
35#include "fx.h"
36#include "fx/time.h"
37
38// Sketch.
39#include "fl/function.h"
40
41using namespace fl;
42
43#define HEIGHT 128
44#define WIDTH 128
45#define NUM_LEDS ((WIDTH) * (HEIGHT))
46#define IS_SERPINTINE false
47#define TIME_ANIMATION 1000 // ms
48
49UITitle title("Simple control of an xy path");
50UIDescription description("This is more of a test for new features.");
51UICheckbox enableVolumeVis("Enable volume visualization", false);
52UICheckbox enableRMS("Enable RMS visualization", false);
53UICheckbox enableFFT("Enable FFT visualization", true);
54UICheckbox freeze("Freeze frame", false);
55UIButton advanceFrame("Advance frame");
56UISlider decayTimeSeconds("Fade time Seconds", .1, 0, 4, .02);
57UISlider attackTimeSeconds("Attack time Seconds", .1, 0, 4, .02);
58UISlider outputTimeSec("outputTimeSec", .17, 0, 2, .01);
59
60UIAudio audio("Audio");
61UISlider fadeToBlack("Fade to black by", 5, 0, 20, 1);
62
63MaxFadeTracker audioFadeTracker(attackTimeSeconds.value(),
64 decayTimeSeconds.value(), outputTimeSec.value(),
65 44100);
66
67CRGB framebuffer[NUM_LEDS];
68XYMap frameBufferXY(WIDTH, HEIGHT, IS_SERPINTINE);
69
70CRGB leds[NUM_LEDS / 4]; // Downscaled buffer
71XYMap ledsXY(WIDTH / 2, HEIGHT / 2,
72 IS_SERPINTINE); // Framebuffer is regular rectangle LED matrix.
73
74FFTBins fftOut(WIDTH); // 2x width due to super sampling.
75
76// CRGB framebuffer[NUM_LEDS];
77// CRGB framebuffer[WIDTH_2X * HEIGHT_2X]; // 2x super sampling.
78// XYMap frameBufferXY(WIDTH, HEIGHT, IS_SERPINTINE); // LED output, serpentine
79// as is common for LED matrices. XYMap xyMap_2X(WIDTH_2X, HEIGHT_2X, false); //
80// Framebuffer is regular rectangle LED matrix.
81
82int x = 0;
83int y = 0;
84bool triggered = false;
85
86SoundLevelMeter soundLevelMeter(.0, 0.0);
87
88float rms(Slice<const int16_t> data) {
89 double sumSq = 0.0;
90 const int N = data.size();
91 for (int i = 0; i < N; ++i) {
92 int32_t x32 = int32_t(data[i]);
93 sumSq += x32 * x32;
94 }
95 float rms = sqrt(float(sumSq) / N);
96 return rms;
97}
98
99void setup() {
100 Serial.begin(115200);
101 // auto screenmap = frameBufferXY.toScreenMap();
102 // screenmap.setDiameter(.2);
103 // FastLED.addLeds<NEOPIXEL, 2>(framebuffer,
104 // NUM_LEDS).setScreenMap(screenmap);
105 auto screenmap = ledsXY.toScreenMap();
106 screenmap.setDiameter(.2);
107
108 decayTimeSeconds.onChanged([](float value) {
109 audioFadeTracker.setDecayTime(value);
110 FASTLED_WARN("Fade time seconds: " << value);
111 });
112 attackTimeSeconds.onChanged([](float value) {
113 audioFadeTracker.setAttackTime(value);
114 FASTLED_WARN("Attack time seconds: " << value);
115 });
116 outputTimeSec.onChanged([](float value) {
117 audioFadeTracker.setOutputTime(value);
118 FASTLED_WARN("Output time seconds: " << value);
119 });
120 FastLED.addLeds<NEOPIXEL, 2>(leds, ledsXY.getTotal())
121 .setScreenMap(screenmap);
122}
123
124void shiftUp() {
125 // fade each led by 1%
126 if (fadeToBlack.as_int()) {
127
128 for (int i = 0; i < NUM_LEDS; ++i) {
129 auto &c = framebuffer[i];
130 c.fadeToBlackBy(fadeToBlack.as_int());
131 }
132 }
133
134 for (int y = HEIGHT - 1; y > 0; --y) {
135 CRGB* row1 = &framebuffer[frameBufferXY(0, y)];
136 CRGB* row2 = &framebuffer[frameBufferXY(0, y - 1)];
137 memcpy(row1, row2, WIDTH * sizeof(CRGB));
138 }
139 CRGB* row = &framebuffer[frameBufferXY(0, 0)];
140 memset(row, 0, sizeof(CRGB) * WIDTH);
141}
142
143
144bool doFrame() {
145 if (!freeze) {
146 return true;
147 }
148 if (advanceFrame.isPressed()) {
149 return true;
150 }
151 return false;
152}
153
154void loop() {
155 if (triggered) {
156 FASTLED_WARN("Triggered");
157 }
158 // fl::clear(framebuffer);
159 // fl::clear(framebuffer);
160
161 static uint32_t frame = 0;
162
163 // x = pointX.as_int();
164 y = HEIGHT / 2;
165
166 bool do_frame = doFrame();
167
168 while (AudioSample sample = audio.next()) {
169 if (!do_frame) {
170 continue;
171 }
172 float fade = audioFadeTracker(sample.pcm().data(), sample.pcm().size());
173 shiftUp();
174 // FASTLED_WARN("Audio sample size: " << sample.pcm().size());
175 soundLevelMeter.processBlock(sample.pcm());
176 // FASTLED_WARN("")
177 auto dbfs = soundLevelMeter.getDBFS();
178 // FASTLED_WARN("getDBFS: " << dbfs);
179 int32_t max = 0;
180 for (int i = 0; i < sample.pcm().size(); ++i) {
181 int32_t x = ABS(sample.pcm()[i]);
182 if (x > max) {
183 max = x;
184 }
185 }
186 float anim =
187 fl::map_range<float, float>(max, 0.0f, 32768.0f, 0.0f, 1.0f);
188 anim = fl::clamp(anim, 0.0f, 1.0f);
189
190 x = fl::map_range<float, float>(anim, 0.0f, 1.0f, 0.0f, WIDTH - 1);
191 // FASTLED_WARN("x: " << x);
192
193 // fft.run(sample.pcm(), &fftOut);
194 sample.fft(&fftOut);
195
196 // FASTLED_ASSERT(fftOut.bins_raw.size() == WIDTH_2X,
197 // "FFT bins size mismatch");
198
199 if (enableFFT) {
200 auto max_x = fftOut.bins_raw.size() - 1;
201 for (int i = 0; i < fftOut.bins_raw.size(); ++i) {
202 auto x = i;
203 auto v = fftOut.bins_db[i];
204 // Map audio intensity to a position in the heat palette (0-255)
205 v = fl::map_range<float, float>(v, 45, 70, 0, 1.f);
206 v = fl::clamp(v, 0.0f, 1.0f);
207 uint8_t heatIndex =
208 fl::map_range<float, uint8_t>(v, 0, 1, 0, 255);
209
210 // FASTLED_WARN(v);
211
212 // Use FastLED's built-in HeatColors palette
213 auto c = ColorFromPalette(HeatColors_p, heatIndex);
214 c.fadeToBlackBy(255 - heatIndex);
215 framebuffer[frameBufferXY(x, 0)] = c;
216 // FASTLED_WARN("y: " << i << " b: " << b);
217 }
218 }
219
220 if (enableVolumeVis) {
221 framebuffer[frameBufferXY(x, HEIGHT / 2)] = CRGB(0, 255, 0);
222 }
223
224 if (enableRMS) {
225 float rms = sample.rms();
226 FASTLED_WARN("RMS: " << rms);
227 rms = fl::map_range<float, float>(rms, 0.0f, 32768.0f, 0.0f, 1.0f);
228 rms = fl::clamp(rms, 0.0f, 1.0f) * WIDTH;
229 framebuffer[frameBufferXY(rms, HEIGHT * 3 / 4)] = CRGB(0, 0, 255);
230 }
231 if (true) {
232 uint16_t fade_width = fade * (WIDTH - 1);
233 uint16_t h = HEIGHT / 4;
234 // yellow
235 int index = frameBufferXY(fade_width, h);
236 auto c = CRGB(255, 255, 0);
237 framebuffer[index] = c;
238 }
239 }
240
241 // now downscale the framebuffer to the led matrix
242 downscale(framebuffer, frameBufferXY, leds, ledsXY);
243
244 FastLED.show();
245}
246
247#endif // __AVR__
CRGB leds[NUM_LEDS]
Definition Apa102.ino:11
#define NUM_LEDS
Definition Apa102.ino:6
void setup()
Definition Audio.ino:18
void loop()
Definition Audio.ino:19
#define WIDTH
Definition Blur2d.ino:9
#define HEIGHT
Definition Blur2d.ino:10
UITitle title("Chromancer")
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
Definition FastLED.cpp:62
central include file for FastLED, defines the CFastLED class/object
uint32_t x[NUM_LAYERS]
Definition Fire2023.ino:82
uint32_t y[NUM_LAYERS]
Definition Fire2023.ino:83
#define IS_SERPINTINE
Definition FxEngine.ino:35
Tracks a smoothed peak with attack, decay, and output-inertia time-constants.
Definition fx.h:9
LED controller for WS2812 LEDs with GRB color order.
Definition FastLED.h:155
Definition ui.h:105
Definition ui.h:25
Definition xymap.h:43
size_t size() const
Definition slice.h:92
CRGB ColorFromPalette(const CRGBPalette16 &pal, uint8_t index, uint8_t brightness, TBlendType blendType)
const TProgmemRGBPalette16 HeatColors_p
Approximate "black body radiation" palette, akin to the FastLED HeatColor() function.
#define ABS(x)
Definition math_macros.h:19
void downscale(const CRGB *src, const XYMap &srcXY, CRGB *dst, const XYMap &dstXY)
FASTLED_FORCE_INLINE T clamp(T value, T min, T max)
Definition clamp.h:10
FASTLED_FORCE_INLINE U map_range(T value, T in_min, T in_max, U out_min, U out_max)
Definition map_range.h:26
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16
bool triggered
Definition simple.h:54
CRGB & fadeToBlackBy(uint8_t fadefactor)
fadeToBlackBy is a synonym for nscale8(), as a fade instead of a scale
Definition crgb.cpp:111
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:55
#define FASTLED_WARN
Definition warn.h:7
UIDescription description("Advanced layered and blended wave effects.")