FastLED 3.9.15
Loading...
Searching...
No Matches
audio.cpp
Go to the documentation of this file.
1
2#include "audio.h"
3#include "fl/thread_local.h"
4#include "fl/int.h"
5#include "fl/mutex.h"
6
7namespace fl {
8
9namespace {
10
12 static ThreadLocal<FFT> gFlexFFT;
13 return gFlexFFT.access();
14}
15
16// Object pool implementation
17
20 static AudioSamplePool s_pool;
21 return s_pool;
22 }
23 void put(AudioSampleImplPtr&& impl) {
24 if (impl.unique()) {
25 // There is no more shared_ptr to this object, so we can recycle it.
27 if (impl && pool.size() < MAX_POOL_SIZE) {
28 // Reset the impl for reuse (clear internal state)
29 impl->reset();
30 pool.push_back(impl);
31 return;
32 }
33 }
34 // Pool is full, discard the impl
35 impl.reset();
36 }
37 AudioSampleImplPtr getOrCreate() {
38 {
40 if (!pool.empty()) {
41 AudioSampleImplPtr impl = pool.back();
42 pool.pop_back();
43 return impl;
44 }
45 }
47 }
48
50 static constexpr fl::size MAX_POOL_SIZE = 8;
52};
53
54} // namespace
55
57 if (mImpl) {
58 AudioSamplePool::instance().put(fl::move(mImpl));
59 }
60}
61
63 if (isValid()) {
64 return mImpl->pcm();
65 }
66 static VectorPCM empty;
67 return empty;
68}
69
71 mImpl = other.mImpl;
72 return *this;
73}
74
75fl::size AudioSample::size() const {
76 if (isValid()) {
77 return mImpl->pcm().size();
78 }
79 return 0;
80}
81
82const fl::i16 &AudioSample::at(fl::size i) const {
83 if (i < size()) {
84 return pcm()[i];
85 }
86 return empty()[0];
87}
88
89const fl::i16 &AudioSample::operator[](fl::size i) const { return at(i); }
90
91bool AudioSample::operator==(const AudioSample &other) const {
92 if (mImpl == other.mImpl) {
93 return true;
94 }
95 if (mImpl == nullptr || other.mImpl == nullptr) {
96 return false;
97 }
98 if (mImpl->pcm().size() != other.mImpl->pcm().size()) {
99 return false;
100 }
101 for (fl::size i = 0; i < mImpl->pcm().size(); ++i) {
102 if (mImpl->pcm()[i] != other.mImpl->pcm()[i]) {
103 return false;
104 }
105 }
106 return true;
107}
108
109bool AudioSample::operator!=(const AudioSample &other) const {
110 return !(*this == other);
111}
112
114 static fl::i16 empty_data[1] = {0};
115 static VectorPCM empty(empty_data);
116 return empty;
117}
118
119float AudioSample::zcf() const { return mImpl->zcf(); }
120
121fl::u32 AudioSample::timestamp() const {
122 if (isValid()) {
123 return mImpl->timestamp();
124 }
125 return 0;
126}
127
128float AudioSample::rms() const {
129 if (!isValid()) {
130 return 0.0f;
131 }
132 fl::u64 sum_sq = 0;
133 const int N = size();
134 for (int i = 0; i < N; ++i) {
135 fl::i32 x32 = fl::i32(pcm()[i]);
136 sum_sq += x32 * x32;
137 }
138 float rms = sqrtf(float(sum_sq) / N);
139 return rms;
140}
141
142SoundLevelMeter::SoundLevelMeter(double spl_floor, double smoothing_alpha)
143 : spl_floor_(spl_floor), smoothing_alpha_(smoothing_alpha),
145 current_spl_(spl_floor) {}
146
147void SoundLevelMeter::processBlock(const fl::i16 *samples, fl::size count) {
148 // 1) compute block power → dBFS
149 double sum_sq = 0.0;
150 for (fl::size i = 0; i < count; ++i) {
151 double s = samples[i] / 32768.0; // normalize to ±1
152 sum_sq += s * s;
153 }
154 double p = sum_sq / count; // mean power
155 double dbfs = 10.0 * log10(p + 1e-12);
156 current_dbfs_ = dbfs;
157
158 // 2) update global floor (with optional smoothing)
159 if (dbfs < dbfs_floor_global_) {
160 if (smoothing_alpha_ <= 0.0) {
161 dbfs_floor_global_ = dbfs;
162 } else {
165 }
167 }
168
169 // 3) estimate SPL
170 current_spl_ = dbfs + offset_;
171}
172
173void AudioSample::fft(FFTBins *out) const {
174 fl::span<const fl::i16> sample = pcm();
176 args.samples = sample.size();
177 args.bands = out->size();
180 args.sample_rate =
181 FFT_Args::DefaultSampleRate(); // TODO: get sample rate from AudioSample
182 get_flex_fft().run(sample, out, args);
183}
184
185
187 mImpl = AudioSamplePool::instance().getOrCreate();
188 auto begin = span.data();
189 auto end = begin + span.size();
190 mImpl->assign(begin, end, timestamp);
191}
192
193
194} // namespace fl
const VectorPCM & pcm() const
Definition audio.cpp:62
AudioSampleImplPtr mImpl
Definition audio.h:59
fl::vector< fl::i16 > VectorPCM
Definition audio.h:24
float zcf() const
Definition audio.cpp:119
fl::size size() const
Definition audio.cpp:75
bool operator!=(const AudioSample &other) const
Definition audio.cpp:109
bool isValid() const
Definition audio.h:36
bool operator==(const AudioSample &other) const
Definition audio.cpp:91
const fl::i16 & operator[](fl::size i) const
Definition audio.cpp:89
void fft(FFTBins *out) const
Definition audio.cpp:173
float rms() const
Definition audio.cpp:128
const fl::i16 & at(fl::size i) const
Definition audio.cpp:82
fl::u32 timestamp() const
Definition audio.cpp:121
const_iterator begin() const
Definition audio.h:49
const_iterator end() const
Definition audio.h:50
AudioSample & operator=(const AudioSample &other)
Definition audio.cpp:70
static const VectorPCM & empty()
Definition audio.cpp:113
void run(const span< const i16 > &sample, FFTBins *out, const FFT_Args &args=FFT_Args())
Definition fft.h:98
fl::size size() const
Definition slice.h:142
SoundLevelMeter(double spl_floor=33.0, double smoothing_alpha=0.0)
Definition audio.cpp:142
double dbfs_floor_global_
Definition audio.h:102
double current_dbfs_
Definition audio.h:104
double smoothing_alpha_
Definition audio.h:101
void processBlock(const fl::i16 *samples, fl::size count)
Process a block of int16 PCM samples.
Definition audio.cpp:147
double spl_floor_
Definition audio.h:100
double current_spl_
Definition audio.h:105
#define INFINITY_DOUBLE
Definition math_macros.h:85
constexpr remove_reference< T >::type && move(T &&t) noexcept
Definition move.h:27
MutexFake< void > mutex
Definition mutex.h:18
Slice< T > span
Definition span.h:8
ThreadLocalFake< T > ThreadLocal
shared_ptr< T > make_shared(Args &&... args)
Definition shared_ptr.h:348
HeapVector< T, Allocator > vector
Definition vector.h:1214
IMPORTANT!
Definition crgb.h:20
corkscrew_args args
Definition old.h:150
static int DefaultSampleRate()
Definition fft.h:66
static float DefaultMinFrequency()
Definition fft.h:64
static float DefaultMaxFrequency()
Definition fft.h:65
fl::size size() const
Definition fft.h:50
void put(AudioSampleImplPtr &&impl)
Definition audio.cpp:23
fl::vector< AudioSampleImplPtr > pool
Definition audio.cpp:49