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