FastLED 3.9.15
Loading...
Searching...
No Matches
audio_reactive.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/fft.h"
4#include "fl/math.h"
5#include "fl/vector.h"
6#include "fl/stdint.h"
7#include "fl/int.h"
8#include "fl/audio.h"
9#include "fl/array.h"
10#include "fl/unique_ptr.h"
11#include "fl/sketch_macros.h"
12#include "crgb.h"
13#include "fl/colorutils.h"
14
15namespace fl {
16
17// Forward declarations for enhanced beat detection
20
21// Audio data structure - matches original WLED output with extensions
22struct AudioData {
23 float volume = 0.0f; // Overall volume level (0-255)
24 float volumeRaw = 0.0f; // Raw volume without smoothing
25 float peak = 0.0f; // Peak level (0-255)
26 bool beatDetected = false; // Beat detection flag
27 float frequencyBins[16] = {0}; // 16 frequency bins (matches WLED NUM_GEQ_CHANNELS)
28 float dominantFrequency = 0.0f; // Major peak frequency (Hz)
29 float magnitude = 0.0f; // FFT magnitude of dominant frequency
30 fl::u32 timestamp = 0; // millis() when data was captured
31
32 // Enhanced beat detection fields
33 bool bassBeatDetected = false; // Bass-specific beat detection
34 bool midBeatDetected = false; // Mid-range beat detection
35 bool trebleBeatDetected = false; // Treble beat detection
36 float spectralFlux = 0.0f; // Current spectral flux value
37 float bassEnergy = 0.0f; // Energy in bass frequencies (0-1)
38 float midEnergy = 0.0f; // Energy in mid frequencies (6-7)
39 float trebleEnergy = 0.0f; // Energy in treble frequencies (14-15)
40};
41
43 fl::u8 gain = 128; // Input gain (0-255)
44 fl::u8 sensitivity = 128; // AGC sensitivity
45 bool agcEnabled = true; // Auto gain control
46 bool noiseGate = true; // Noise gate
47 fl::u8 attack = 50; // Attack time (ms) - how fast to respond to increases
48 fl::u8 decay = 200; // Decay time (ms) - how slow to respond to decreases
49 u16 sampleRate = 22050; // Sample rate (Hz)
50 fl::u8 scalingMode = 3; // 0=none, 1=log, 2=linear, 3=sqrt
51
52 // Enhanced beat detection configuration
53 bool enableSpectralFlux = true; // Enable spectral flux-based beat detection
54 bool enableMultiBand = true; // Enable multi-band beat detection
55 float spectralFluxThreshold = 0.1f; // Threshold for spectral flux detection
56 float bassThreshold = 0.15f; // Threshold for bass beat detection
57 float midThreshold = 0.12f; // Threshold for mid beat detection
58 float trebleThreshold = 0.08f; // Threshold for treble beat detection
59};
60
62public:
65
66 // Setup
69
70 // Process audio sample - this does all the work immediately
71 void processSample(const AudioSample& sample);
72
73 // Optional: update smoothing without new sample data
74 void update(fl::u32 currentTimeMs);
75
76 // Data access
77 const AudioData& getData() const;
78 const AudioData& getSmoothedData() const;
79
80 // Convenience accessors
81 float getVolume() const;
82 float getBass() const; // Average of bins 0-1
83 float getMid() const; // Average of bins 6-7
84 float getTreble() const; // Average of bins 14-15
85 bool isBeat() const;
86
87 // Enhanced beat detection accessors
88 bool isBassBeat() const;
89 bool isMidBeat() const;
90 bool isTrebleBeat() const;
91 float getSpectralFlux() const;
92 float getBassEnergy() const;
93 float getMidEnergy() const;
94 float getTrebleEnergy() const;
95
96 // Effect helpers
98 CRGB volumeToColor(const CRGBPalette16& palette) const;
99 fl::u8 frequencyToScale255(fl::u8 binIndex) const;
100
101private:
102 // Internal processing methods
103 void processFFT(const AudioSample& sample);
105 void updateVolumeAndPeak(const AudioSample& sample);
106 void detectBeat(fl::u32 currentTimeMs);
107 void smoothResults();
108 void applyScaling();
109 void applyGain();
110
111 // Enhanced beat detection methods
112 void detectEnhancedBeats(fl::u32 currentTimeMs);
114 void updateSpectralFlux();
116
117 // Helper methods
118 float mapFrequencyBin(int fromBin, int toBin);
119 float computeRMS(const fl::vector<fl::i16>& samples);
120
121 // Configuration
123
124 // FFT processing
127
128 // Audio data
131
132 // Processing state
133 fl::u32 mLastBeatTime = 0;
134 static constexpr fl::u32 BEAT_COOLDOWN = 100; // 100ms minimum between beats
135
136 // Volume tracking for beat detection
137 float mPreviousVolume = 0.0f;
138 float mVolumeThreshold = 10.0f;
139
140 // Pink noise compensation (from WLED)
141 static constexpr float PINK_NOISE_COMPENSATION[16] = {
142 1.70f, 1.71f, 1.73f, 1.78f, 1.68f, 1.56f, 1.55f, 1.63f,
143 1.79f, 1.62f, 1.80f, 2.06f, 2.47f, 3.35f, 6.83f, 9.55f
144 };
145
146 // AGC state
147 float mAGCMultiplier = 1.0f;
148 float mMaxSample = 0.0f;
149 float mAverageLevel = 0.0f;
150
151 // Enhanced beat detection components
154
155 // Enhanced beat detection state
157};
158
159// Spectral flux-based onset detection for enhanced beat detection
161public:
164
165 void reset();
166 bool detectOnset(const float* currentBins, const float* previousBins);
167 float calculateSpectralFlux(const float* currentBins, const float* previousBins);
168 void setThreshold(float threshold);
169 float getThreshold() const;
170
171private:
174
175#if SKETCH_HAS_LOTS_OF_MEMORY
176 fl::array<float, 32> mFluxHistory; // For advanced smoothing
177 fl::size mHistoryIndex;
178 float calculateAdaptiveThreshold();
179#endif
180};
181
182// Multi-band beat detection for different frequency ranges
186
187 void reset();
188 void detectBeats(const float* frequencyBins, AudioData& audioData);
189 void setThresholds(float bassThresh, float midThresh, float trebleThresh);
190
191private:
192#if SKETCH_HAS_LOTS_OF_MEMORY
193 SpectralFluxDetector bass; // 20-200 Hz (bins 0-1)
194 SpectralFluxDetector mid; // 200-2000 Hz (bins 6-7)
195 SpectralFluxDetector treble; // 2000-20000 Hz (bins 14-15)
196#else
197 SpectralFluxDetector combined; // Single detector for memory-constrained
198#endif
199
200 // Energy tracking for band-specific thresholds
207};
208
209// Perceptual audio weighting for psychoacoustic processing
211public:
214
215 void applyAWeighting(AudioData& data) const;
216 void applyLoudnessCompensation(AudioData& data, float referenceLevel) const;
217
218private:
219 // A-weighting coefficients for 16-bin frequency analysis
220 static constexpr float A_WEIGHTING_COEFFS[16] = {
221 0.5f, 0.6f, 0.8f, 1.0f, 1.2f, 1.3f, 1.4f, 1.4f,
222 1.3f, 1.2f, 1.0f, 0.8f, 0.6f, 0.4f, 0.2f, 0.1f
223 };
224
225#if SKETCH_HAS_LOTS_OF_MEMORY
226 fl::array<float, 16> mLoudnessHistory; // For dynamic compensation
227 fl::size mHistoryIndex;
228#endif
229};
230
231} // namespace fl
fl::AudioConfig config
Definition AudioInput.h:27
UINumberField palette("Palette", 0, 0, 2)
fl::array< float, 16 > mPreviousMagnitudes
bool isTrebleBeat() const
CRGB volumeToColor(const CRGBPalette16 &palette) const
const AudioData & getData() const
void update(fl::u32 currentTimeMs)
void processFFT(const AudioSample &sample)
fl::u8 volumeToScale255() const
void detectBeat(fl::u32 currentTimeMs)
AudioReactiveConfig mConfig
void mapFFTBinsToFrequencyChannels()
float getSpectralFlux() const
float getBass() const
float getMidEnergy() const
float computeRMS(const fl::vector< fl::i16 > &samples)
static constexpr float PINK_NOISE_COMPENSATION[16]
void updateVolumeAndPeak(const AudioSample &sample)
float getTrebleEnergy() const
fl::unique_ptr< SpectralFluxDetector > mSpectralFluxDetector
static constexpr fl::u32 BEAT_COOLDOWN
bool isBassBeat() const
float getVolume() const
float getTreble() const
float mapFrequencyBin(int fromBin, int toBin)
void detectEnhancedBeats(fl::u32 currentTimeMs)
const AudioData & getSmoothedData() const
void begin(const AudioReactiveConfig &config=AudioReactiveConfig{})
void setConfig(const AudioReactiveConfig &config)
fl::u8 frequencyToScale255(fl::u8 binIndex) const
float getBassEnergy() const
void processSample(const AudioSample &sample)
fl::unique_ptr< PerceptualWeighting > mPerceptualWeighting
Definition fft.h:98
void applyLoudnessCompensation(AudioData &data, float referenceLevel) const
static constexpr float A_WEIGHTING_COEFFS[16]
void applyAWeighting(AudioData &data) const
void setThreshold(float threshold)
float calculateSpectralFlux(const float *currentBins, const float *previousBins)
bool detectOnset(const float *currentBins, const float *previousBins)
fl::array< float, 16 > mPreviousMagnitudes
A fixed-size array implementation similar to std::array.
Definition array.h:28
Defines the red, green, and blue (RGB) pixel struct.
Utility functions for color fill, palettes, blending, and more.
unsigned char u8
Definition int.h:17
HeapVector< T, Allocator > vector
Definition vector.h:1214
IMPORTANT!
Definition crgb.h:20
float frequencyBins[16]
float dominantFrequency
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:86
void detectBeats(const float *frequencyBins, AudioData &audioData)
void setThresholds(float bassThresh, float midThresh, float trebleThresh)
SpectralFluxDetector combined