arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
LEDOutput.h
1#pragma once
2#include <FastLED.h>
3
4#include "AudioTools/CoreAudio/AudioBasic/Collections/Vector.h"
5#include "AudioTools/AudioLibs/AudioFFT.h"
6#include "FFTDisplay.h"
7
8namespace audio_tools {
9
10class LEDOutput;
11struct LEDOutputConfig;
12
13// default callback function which implements led update
14void fftLEDOutput(LEDOutputConfig *cfg, LEDOutput *matrix);
15// led update for volume
16void volumeLEDOutput(LEDOutputConfig *cfg, LEDOutput *matrix);
17// default color
18CHSV getDefaultColor(int x, int y, int magnitude);
19
27 int x = 0;
29 int y = 1;
32 CHSV (*color_callback)(int x, int y, int magnitude) = getDefaultColor;
37 int update_frequency = 1; // update every call
38 bool is_serpentine_layout = true;
39 bool is_matrix_vertical = true;
41 int max_magnitude = 700;
42};
43
48class LEDOutput {
49 public:
51 LEDOutput() = default;
52
56 p_fft = &fft;
58 }
59
66
69
72 cfg = config;
73 if (ledCount() == 0) {
74 LOGE("x or y == 0");
75 return false;
76 }
77
78 // allocate leds
79 leds.resize(ledCount());
80 for (int j = 0; j < ledCount(); j++) {
81 led(j) = CRGB::Black;
82 }
83
84 // clear LED
85 FastLED.clear(); // clear all pixel data
86
87 if (p_fft != nullptr) {
88 p_fft->begin();
89 }
90
91 max_column = -1;
92
93 return true;
94 }
95
97 int ledCount() {
98 int num_leds = cfg.x * cfg.y;
99 return num_leds;
100 }
101
104 if (ledCount() == 0) {
105 LOGE("x or y == 0");
106 return nullptr;
107 }
108 // leds.resize(ledCount());
109 return leds.data();
110 }
111
113 virtual void update() {
114 if (cfg.update_callback != nullptr && count++ % cfg.update_frequency == 0) {
115 // use custom update logic defined in config
116 cfg.update_callback(&cfg, this);
117 } else {
118 display();
119 }
120 }
121
124 if (x > cfg.x) x = cfg.x - 1;
125 if (x < 0) x = 0;
126 if (y > cfg.y) y = cfg.y - 1;
127 if (y < 0) y = 0;
128 int index = xy(x, y);
129 return leds[index];
130 }
131
133 CRGB &led(uint8_t index) {
134 if (index > cfg.x * cfg.y) return not_valid;
135 return leds[index];
136 }
137
139 void setColumnBar(int x, int currY) {
140 // update vertical bar
141 for (uint8_t y = 0; y < currY; y++) {
142 // determine color
143 CHSV color = cfg.color_callback(x, y, currY);
144 // update LED
145 ledXY(x, y) = color;
146 }
147 for (uint8_t y = currY; y < cfg.y; y++) {
148 ledXY(x, y) = CRGB::Black;
149 }
150 if (x > max_column) max_column = x;
151 }
152
154 void setColumnBar(int currY) { setColumnBar(cfg.x - 1, currY); }
155
157 void addColumnBar(int currY) {
158 max_column++;
159 if (max_column >= cfg.x) {
161 }
162 if (max_column > cfg.x - 1) {
163 max_column = cfg.x - 1;
164 }
165 setColumnBar(max_column, currY);
166 }
167
169 LEDOutputConfig &config() { return cfg; }
170
172 virtual float getMaxMagnitude() {
173 // get magnitude from
174 if (p_vol != nullptr) {
175 return p_vol->volume();
176 }
177 float max = 0;
178 if (p_fft != nullptr) {
179 for (int j = 0; j < cfg.x; j++) {
180 float value = p_fft->getMagnitude(j);
181 if (value > max) {
182 max = value;
183 }
184 }
185 }
186 return max;
187 }
188
190 void display() {
191 FastLED.show();
192 }
193
195 FFTDisplay &fftDisplay() { return *p_fft; }
196
197 protected:
198 friend class AudioFFTBase;
199 CRGB not_valid;
200 Vector<CRGB> leds{0};
201 LEDOutputConfig cfg;
202 VolumeMeter *p_vol = nullptr;
203 FFTDisplay *p_fft = nullptr;
204 uint64_t count = 0;
205 int max_column = -1;
206
209 for (int x = 1; x < cfg.x; x++) {
210 for (int y = 0; y < cfg.y; y++) {
211 ledXY(x - 1, y) = ledXY(x, y);
212 }
213 }
214 for (int y = 0; y < cfg.y; y++) {
215 ledXY(cfg.x - 1, y) = CRGB::Black;
216 }
217 }
218
219 uint16_t xy(uint8_t x, uint8_t y) {
220 uint16_t i;
221
222 if (cfg.is_serpentine_layout == false) {
223 if (cfg.is_matrix_vertical == false) {
224 i = (y * cfg.x) + x;
225 } else {
226 i = cfg.y * (cfg.x - (x + 1)) + y;
227 }
228 }
229
230 if (cfg.is_serpentine_layout == true) {
231 if (cfg.is_matrix_vertical == false) {
232 if (y & 0x01) {
233 // Odd rows run backwards
234 uint8_t reverseX = (cfg.x - 1) - x;
235 i = (y * cfg.x) + reverseX;
236 } else {
237 // Even rows run forwards
238 i = (y * cfg.x) + x;
239 }
240 } else { // vertical positioning
241 if (x & 0x01) {
242 i = cfg.y * (cfg.x - (x + 1)) + y;
243 } else {
244 i = cfg.y * (cfg.x - x) - (y + 1);
245 }
246 }
247 }
248
249 return i;
250 }
251};
252
255 // process horizontal
256 LockGuard guard(fft_mux);
257 for (int x = 0; x < cfg->x; x++) {
258 // max y determined by magnitude
259 int currY = matrix->fftDisplay().getMagnitudeScaled(x, cfg->y);
260 LOGD("x: %d, y: %d", x, currY);
261 matrix->setColumnBar(x, currY);
262 }
263 FastLED.show();
264}
265
268 float vol = matrix->getMaxMagnitude();
269 int currY = mapT<float>(vol, 0,
270 cfg->max_magnitude, 0.0f,
271 static_cast<float>(cfg->y));
272 matrix->addColumnBar(currY);
273 FastLED.show();
274}
275
277CHSV getDefaultColor(int x, int y, int magnitude) {
278 int color = map(magnitude, 0, 7, 255, 0);
279 return CHSV(color, 255, 100); // blue CHSV(160, 255, 255
280}
281
282} // namespace audio_tools
Executes FFT using audio data privded by write() and/or an inverse FFT where the samples are made ava...
Definition AudioFFT.h:191
Definition FFTDisplay.h:18
float getMagnitude(int x)
Definition FFTDisplay.h:46
LED output using the FastLED library.
Definition LEDOutput.h:48
void setColumnBar(int x, int currY)
Update the indicated column with the indicated bar.
Definition LEDOutput.h:139
void display()
Update the led_matrix (calling FastLED.show();.
Definition LEDOutput.h:190
CRGB * ledData()
Provides the address fo the CRGB array: call begin() first!
Definition LEDOutput.h:103
void addColumnBar(int currY)
Update the last column with the indicated bar.
Definition LEDOutput.h:157
FFTDisplay & fftDisplay()
Provides acces to the FFTDisplay object.
Definition LEDOutput.h:195
LEDOutput()=default
Default Constructor.
LEDOutputConfig & config()
Provides access to the actual config object. E.g. to change the update logic.
Definition LEDOutput.h:169
virtual float getMaxMagnitude()
Provodes the max magnitude for both the.
Definition LEDOutput.h:172
void addEmptyColumn()
Adds an empty column to the end shifting the content to the left.
Definition LEDOutput.h:208
LEDOutput(VolumeMeter &vol)
Constructor for VolumeMeter scenario.
Definition LEDOutput.h:62
int ledCount()
Provides the number of LEDs: call begin() first!
Definition LEDOutput.h:97
bool begin(LEDOutputConfig config)
Setup Led matrix.
Definition LEDOutput.h:71
LEDOutputConfig defaultConfig()
Provides the default config object.
Definition LEDOutput.h:68
CRGB & ledXY(uint8_t x, uint8_t y)
Determine the led with the help of the x and y pos.
Definition LEDOutput.h:123
virtual void update()
Updates the display: call this method in your loop.
Definition LEDOutput.h:113
LEDOutput(FFTDisplay &fft)
Constructor for FFT scenario.
Definition LEDOutput.h:55
CRGB & led(uint8_t index)
Determine the led with the help of the index pos.
Definition LEDOutput.h:133
void setColumnBar(int currY)
Update the last column with the indicated bar.
Definition LEDOutput.h:154
RAII implementaion using a Mutex: Only a few microcontrollers provide lock guards,...
Definition LockGuard.h:17
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
A simple class to determine the volume. You can use it as final output or as output or input in your ...
Definition AudioStreams.h:1676
float volume()
Definition AudioStreams.h:1729
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioConfig.h:885
CHSV getDefaultColor(int x, int y, int magnitude)
Default logic to update the color for the indicated x,y position.
Definition LEDOutput.h:277
void volumeLEDOutput(LEDOutputConfig *cfg, LEDOutput *matrix)
Default update implementation which provides the fft result as "barchart".
Definition LEDOutput.h:267
void fftLEDOutput(LEDOutputConfig *cfg, LEDOutput *matrix)
Default update implementation which provides the fft result as "barchart".
Definition LEDOutput.h:254
long map(long x, long in_min, long in_max, long out_min, long out_max)
Maps input to output values.
Definition NoArduino.h:186
Definition LEDOutput.h:25
int y
Number of leds in y direction.
Definition LEDOutput.h:29
int max_magnitude
Influences the senitivity.
Definition LEDOutput.h:41
void(* update_callback)(LEDOutputConfig *cfg, LEDOutput *matrix)
Definition LEDOutput.h:35
int x
Number of leds in x direction.
Definition LEDOutput.h:27
int update_frequency
Update the leds only ever nth call.
Definition LEDOutput.h:37
CHSV(* color_callback)(int x, int y, int magnitude)
Definition LEDOutput.h:32