FastLED 3.9.15
Loading...
Searching...
No Matches
energy_analyzer.cpp.hpp
Go to the documentation of this file.
3#include "fl/math/math.h"
4#include "fl/stl/noexcept.h"
5
6namespace fl {
7namespace audio {
8namespace detector {
9
11 : mCurrentRMS(0.0f)
12 , mPeak(0.0f)
13 , mAverageEnergy(0.0f)
14 , mMinEnergy(1e6f)
15 , mMaxEnergy(0.0f)
16 , mPeakDecay(0.95f)
17 , mLastPeakTime(0)
18{
19}
20
22
24 // Get RMS directly from Sample (no fft::FFT needed)
25 mCurrentRMS = context->getRMS();
26 u32 timestamp = context->getTimestamp();
27
28 // Update peak tracking
29 updatePeak(mCurrentRMS, timestamp);
30
31 // Update average and history
33
34 // Update min/max
35 if (mCurrentRMS > 0.001f) { // Ignore near-silence
38 }
39
40 // Compute normalized 0-1 RMS using adaptive range tracking.
41 // AttackDecayFilter: instant attack (0.001s), slow decay (2.0s).
42 const float dt = computeAudioDt(context->getPCM().size(), context->getSampleRate());
43 float runningMax = mRunningMaxFilter.update(mCurrentRMS, dt);
44 // Ensure running max doesn't decay below a minimum threshold
45 if (runningMax < 1.0f) {
46 runningMax = 1.0f;
47 }
48 mNormalizedRMS = fl::min(1.0f, mCurrentRMS / runningMax);
49}
50
65
67 mCurrentRMS = 0.0f;
68 mPeak = 0.0f;
69 mAverageEnergy = 0.0f;
70 mMinEnergy = 1e6f;
71 mMaxEnergy = 0.0f;
72 mNormalizedRMS = 0.0f;
73 mRunningMaxFilter.reset(1.0f);
74 mLastPeakTime = 0;
75 mEnergyAvg.reset();
76}
77
79 mEnergyAvg.resize(static_cast<fl::size>(size));
80}
81
82void EnergyAnalyzer::updatePeak(float energy, u32 timestamp) {
83 // Check if we should decay the peak
84 u32 timeSincePeak = timestamp - mLastPeakTime;
85
86 if (energy > mPeak) {
87 // New peak
88 mPeak = energy;
89 mLastPeakTime = timestamp;
90 } else if (timeSincePeak > PEAK_HOLD_MS) {
91 // Decay the peak
93
94 // Ensure peak doesn't go below current energy
95 if (mPeak < energy) {
96 mPeak = energy;
97 mLastPeakTime = timestamp;
98 }
99 }
100}
101
103 mEnergyAvg.update(energy);
104 mAverageEnergy = mEnergyAvg.value();
105}
106
107} // namespace detector
108} // namespace audio
109} // namespace fl
MovingAverage< float, 0 > mEnergyAvg
~EnergyAnalyzer() FL_NOEXCEPT override
AttackDecayFilter< float > mRunningMaxFilter
function_list< void(float avgEnergy)> onAverageEnergy
function_list< void(float rms)> onEnergy
function_list< void(float peak)> onPeak
void updatePeak(float energy, u32 timestamp)
void update(shared_ptr< Context > context) override
function_list< void(float normalizedRms)> onNormalizedEnergy
float computeAudioDt(fl::size pcmSize, int sampleRate) FL_NOEXCEPT
Compute the time delta (in seconds) for an audio buffer.
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NOEXCEPT
Definition math.h:71
constexpr common_type_t< T, U > max(T a, U b) FL_NOEXCEPT
Definition math.h:75
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT