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
6namespace fl {
7
8namespace {
9
11 static ThreadLocal<FFT> gFlexFFT;
12 return gFlexFFT.access();
13}
14
15} // namespace
16
18 if (isValid()) {
19 return mImpl->pcm();
20 }
21 static VectorPCM empty;
22 return empty;
23}
24
26 mImpl = other.mImpl;
27 return *this;
28}
29
30fl::size AudioSample::size() const {
31 if (isValid()) {
32 return mImpl->pcm().size();
33 }
34 return 0;
35}
36
37const fl::i16 &AudioSample::at(fl::size i) const {
38 if (i < size()) {
39 return pcm()[i];
40 }
41 return empty()[0];
42}
43
44const fl::i16 &AudioSample::operator[](fl::size i) const { return at(i); }
45
46bool AudioSample::operator==(const AudioSample &other) const {
47 if (mImpl == other.mImpl) {
48 return true;
49 }
50 if (mImpl == nullptr || other.mImpl == nullptr) {
51 return false;
52 }
53 if (mImpl->pcm().size() != other.mImpl->pcm().size()) {
54 return false;
55 }
56 for (fl::size i = 0; i < mImpl->pcm().size(); ++i) {
57 if (mImpl->pcm()[i] != other.mImpl->pcm()[i]) {
58 return false;
59 }
60 }
61 return true;
62}
63
64bool AudioSample::operator!=(const AudioSample &other) const {
65 return !(*this == other);
66}
67
69 static fl::i16 empty_data[1] = {0};
70 static VectorPCM empty(empty_data);
71 return empty;
72}
73
74float AudioSample::zcf() const { return mImpl->zcf(); }
75
76fl::u32 AudioSample::timestamp() const {
77 if (isValid()) {
78 return mImpl->timestamp();
79 }
80 return 0;
81}
82
83float AudioSample::rms() const {
84 if (!isValid()) {
85 return 0.0f;
86 }
87 fl::u64 sum_sq = 0;
88 const int N = size();
89 for (int i = 0; i < N; ++i) {
90 fl::i32 x32 = fl::i32(pcm()[i]);
91 sum_sq += x32 * x32;
92 }
93 float rms = sqrtf(float(sum_sq) / N);
94 return rms;
95}
96
97SoundLevelMeter::SoundLevelMeter(double spl_floor, double smoothing_alpha)
98 : spl_floor_(spl_floor), smoothing_alpha_(smoothing_alpha),
100 current_spl_(spl_floor) {}
101
102void SoundLevelMeter::processBlock(const fl::i16 *samples, fl::size count) {
103 // 1) compute block power → dBFS
104 double sum_sq = 0.0;
105 for (fl::size i = 0; i < count; ++i) {
106 double s = samples[i] / 32768.0; // normalize to ±1
107 sum_sq += s * s;
108 }
109 double p = sum_sq / count; // mean power
110 double dbfs = 10.0 * log10(p + 1e-12);
111 current_dbfs_ = dbfs;
112
113 // 2) update global floor (with optional smoothing)
114 if (dbfs < dbfs_floor_global_) {
115 if (smoothing_alpha_ <= 0.0) {
116 dbfs_floor_global_ = dbfs;
117 } else {
120 }
122 }
123
124 // 3) estimate SPL
125 current_spl_ = dbfs + offset_;
126}
127
128void AudioSample::fft(FFTBins *out) const {
129 fl::span<const fl::i16> sample = pcm();
131 args.samples = sample.size();
132 args.bands = out->size();
135 args.sample_rate =
136 FFT_Args::DefaultSampleRate(); // TODO: get sample rate from AudioSample
137 get_flex_fft().run(sample, out, args);
138}
139
140} // namespace fl
const VectorPCM & pcm() const
Definition audio.cpp:17
AudioSampleImplPtr mImpl
Definition audio.h:52
fl::vector< fl::i16 > VectorPCM
Definition audio.h:23
float zcf() const
Definition audio.cpp:74
fl::size size() const
Definition audio.cpp:30
bool operator!=(const AudioSample &other) const
Definition audio.cpp:64
bool isValid() const
Definition audio.h:29
bool operator==(const AudioSample &other) const
Definition audio.cpp:46
const fl::i16 & operator[](fl::size i) const
Definition audio.cpp:44
void fft(FFTBins *out) const
Definition audio.cpp:128
float rms() const
Definition audio.cpp:83
const fl::i16 & at(fl::size i) const
Definition audio.cpp:37
fl::u32 timestamp() const
Definition audio.cpp:76
AudioSample & operator=(const AudioSample &other)
Definition audio.cpp:25
static const VectorPCM & empty()
Definition audio.cpp:68
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:97
double dbfs_floor_global_
Definition audio.h:95
double current_dbfs_
Definition audio.h:97
double smoothing_alpha_
Definition audio.h:94
void processBlock(const fl::i16 *samples, fl::size count)
Process a block of int16 PCM samples.
Definition audio.cpp:102
double spl_floor_
Definition audio.h:93
double current_spl_
Definition audio.h:98
#define INFINITY_DOUBLE
Definition math_macros.h:77
Slice< T > span
Definition span.h:8
ThreadLocalFake< T > ThreadLocal
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