FastLED 3.9.15
Loading...
Searching...
No Matches
audio_context.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/audio/audio.h"
4#include "fl/audio/fft/fft.h"
5#include "fl/stl/vector.h"
6#include "fl/stl/shared_ptr.h"
7#include "fl/stl/span.h"
8#include "fl/stl/flat_map.h"
9#include "fl/stl/noexcept.h"
10
11namespace fl {
12namespace audio {
13
14struct BandEnergy {
15 float bass = 0.0f;
16 float mid = 0.0f;
17 float treb = 0.0f;
18};
19
20class Context {
21public:
22 explicit Context(const Sample& sample) FL_NOEXCEPT;
24
25 // ----- Basic Sample Access -----
26 const Sample& getSample() const FL_NOEXCEPT { return mSample; }
27 span<const i16> getPCM() const FL_NOEXCEPT { return mSample.pcm(); }
28 float getRMS() const FL_NOEXCEPT { return mSample.rms(); }
29 float getZCF() const FL_NOEXCEPT { return mSample.zcf(); }
30 u32 getTimestamp() const FL_NOEXCEPT { return mSample.timestamp(); }
31
32 // ----- Lazy fft::FFT Computation (with shared_ptr caching + recycling) -----
34 int bands = 16,
35 float fmin = fft::Args::DefaultMinFrequency(),
36 float fmax = fft::Args::DefaultMaxFrequency(),
40 bool hasFFT() const FL_NOEXCEPT { return !mFFTCache.empty(); }
41
42 // 3-band energy from 3 linear bins (20-11025 Hz).
43 // bass: 20-3688 Hz, mid: 3688-7356 Hz, treb: 7356-11025 Hz.
45
46 // Standard 16-bin fft::FFT (90-14080 Hz).
47 // Detectors that need 16 bins should use this to share a single cached fft::FFT.
48 shared_ptr<const fft::Bins> getFFT16(fft::Mode mode = fft::Mode::LOG_REBIN,
49 fft::Window window = fft::Window::BLACKMAN_HARRIS) FL_NOEXCEPT;
50
51 // ----- fft::FFT History (for temporal analysis) -----
52 void setFFTHistoryDepth(int depth) FL_NOEXCEPT;
53 const vector<fft::Bins>& getFFTHistory() const FL_NOEXCEPT { return mFFTHistory; }
54 bool hasFFTHistory() const FL_NOEXCEPT { return mFFTHistoryDepth > 0; }
55 const fft::Bins* getHistoricalFFT(int framesBack) const FL_NOEXCEPT;
56
57 // ----- Sample Rate -----
58 void setSampleRate(int sampleRate) FL_NOEXCEPT { mSampleRate = sampleRate; }
59 int getSampleRate() const FL_NOEXCEPT { return mSampleRate; }
60
61 // ----- Silence Flag -----
62 // Populated per-frame by the pipeline owner (Processor / Reactive) from
63 // NoiseFloorTracker::isAboveFloor(). Detectors read this to gate their
64 // outputs during silence. Default false — detectors that check this flag
65 // simply won't gate if the pipeline hasn't enabled noise-floor tracking.
66 // Reset to false on each setSample(); callers must re-populate after their
67 // NoiseFloorTracker.update() call.
68 void setSilent(bool silent) FL_NOEXCEPT { mIsSilent = silent; }
69 bool isSilent() const FL_NOEXCEPT { return mIsSilent; }
70
71 // ----- Update & Reset -----
74
75private:
77
82
83 // Create cache key hash from fft::Args for O(1) lookup
84 static fl::size hashFFTArgs(const fft::Args& args) FL_NOEXCEPT;
85
86 int mSampleRate = 44100;
88 fft::FFT mFFT; // fft::FFT engine (has its own kernel cache)
89 vector<FFTCacheEntry> mFFTCache; // Strong cache: co-owned with callers
90 flat_map<fl::size, int> mFFTCacheMap; // Maps args hash to index in mFFTCache
91 vector<shared_ptr<fft::Bins>> mRecyclePool; // Recycled bins for zero-alloc reuse
95 bool mIsSilent = false;
96};
97
101inline float computeAudioDt(fl::size pcmSize, int sampleRate) FL_NOEXCEPT {
102 if (sampleRate <= 0 || pcmSize == 0) return 0.0f;
103 return static_cast<float>(pcmSize) / static_cast<float>(sampleRate);
104}
105
106} // namespace audio
107} // namespace fl
vector< fft::Bins > mFFTHistory
void setFFTHistoryDepth(int depth) FL_NOEXCEPT
flat_map< fl::size, int > mFFTCacheMap
bool hasFFT() const FL_NOEXCEPT
int getSampleRate() const FL_NOEXCEPT
vector< FFTCacheEntry > mFFTCache
~Context() FL_NOEXCEPT
span< const i16 > getPCM() const FL_NOEXCEPT
shared_ptr< const fft::Bins > getFFT(int bands=16, float fmin=fft::Args::DefaultMinFrequency(), float fmax=fft::Args::DefaultMaxFrequency(), fft::Mode mode=fft::Mode::AUTO, fft::Window window=fft::Window::BLACKMAN_HARRIS) FL_NOEXCEPT
void setSample(const Sample &sample) FL_NOEXCEPT
const Sample & getSample() const FL_NOEXCEPT
shared_ptr< const fft::Bins > getFFT16(fft::Mode mode=fft::Mode::LOG_REBIN, fft::Window window=fft::Window::BLACKMAN_HARRIS) FL_NOEXCEPT
void clearCache() FL_NOEXCEPT
bool hasFFTHistory() const FL_NOEXCEPT
bool isSilent() const FL_NOEXCEPT
u32 getTimestamp() const FL_NOEXCEPT
const fft::Bins * getHistoricalFFT(int framesBack) const FL_NOEXCEPT
const vector< fft::Bins > & getFFTHistory() const FL_NOEXCEPT
static constexpr int MAX_FFT_CACHE_ENTRIES
vector< shared_ptr< fft::Bins > > mRecyclePool
void setSilent(bool silent) FL_NOEXCEPT
BandEnergy getBandEnergy() FL_NOEXCEPT
float getZCF() const FL_NOEXCEPT
float getRMS() const FL_NOEXCEPT
void setSampleRate(int sampleRate) FL_NOEXCEPT
Context(const Sample &sample) FL_NOEXCEPT
static fl::size hashFFTArgs(const fft::Args &args) FL_NOEXCEPT
shared_ptr< fft::Bins > bins
#define constexpr
Declares that it is possible to evaluate a value at compile time, introduced in C++11.
Definition cpp_compat.h:15
float computeAudioDt(fl::size pcmSize, int sampleRate) FL_NOEXCEPT
Compute the time delta (in seconds) for an audio buffer.
CRGB sample(const CRGB *grid, const XYMap &xyMap, float x, float y, SampleMode mode)
Sample a pixel from a 2D CRGB grid at floating-point coordinates.
Definition sample.cpp.hpp:9
Base definition for an LED controller.
Definition crgb.hpp:179
corkscrew_args args
Definition old.h:149
#define FL_NOEXCEPT
static float DefaultMaxFrequency() FL_NOEXCEPT
Definition fft.h:128
static float DefaultMinFrequency() FL_NOEXCEPT
Definition fft.h:127