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