FastLED 3.10.8
Loading...
Searching...
No Matches
audio_batch.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/stl/mutex.h"
4#include "fl/stl/span.h"
5#include "fl/stl/stdint.h"
7#include "fl/stl/noexcept.h"
8
9namespace fl {
10
11namespace audio {
12class Processor;
13} // namespace audio
14
15// ---------------------------------------------------------------------------
16// Lightweight snapshot structs — owned copies, no dangling references.
17// Live in fl:: namespace so effects don't need audio internals.
18// ---------------------------------------------------------------------------
19
21struct VibeLevels {
22 // Self-normalizing relative levels (~1.0 = average for current song)
23 float bass = 1.0f;
24 float mid = 1.0f;
25 float treb = 1.0f;
26 float vol = 1.0f; // (bass + mid + treb) / 3
27
28 // Spike detection (true when energy is rising)
29 bool bassSpike = false;
30 bool midSpike = false;
31 bool trebSpike = false;
32};
33
35struct EqLevels {
36 static constexpr int kNumBins = 16;
37 float bins[kNumBins] = {};
38 float bass = 0;
39 float mid = 0;
40 float treble = 0;
41 float volume = 0;
42 float dominantFreqHz = 0;
43 bool isSilence = false;
44};
45
48 bool kick = false;
49 bool snare = false;
50 bool hihat = false;
51 bool tom = false;
52};
53
54// ---------------------------------------------------------------------------
55// AudioBatch — lazy proxy over a batch of AudioFrames + optional Processor.
56//
57// Created on the stack once per draw() cycle and shared (via const pointer)
58// across both compositor layers. Cheap accessors (bass/mid/treble/volume/beat)
59// aggregate over AudioFrames. Expensive accessors (vibe/equalizer/percussion)
60// lazily snapshot from the Processor on first call.
61//
62// All accessors are const and mutex-guarded — safe to call from either layer.
63// When no Processor is wired, expensive accessors return default-constructed
64// (zero/neutral) snapshots.
65// ---------------------------------------------------------------------------
67 public:
70 audio::Processor *proc = nullptr)
71 FL_NO_EXCEPT : mFrames(frames), mProc(proc) {}
72
75
76 // --- Cheap: peak aggregates over AudioFrames (compute-once) ---
77 float bass() const FL_NO_EXCEPT { ensurePeaks(); return mPeaks.bass; }
78 float mid() const FL_NO_EXCEPT { ensurePeaks(); return mPeaks.mid; }
79 float treble() const FL_NO_EXCEPT { ensurePeaks(); return mPeaks.treble; }
80 float volume() const FL_NO_EXCEPT { ensurePeaks(); return mPeaks.volume; }
81 bool beat() const FL_NO_EXCEPT { ensurePeaks(); return mPeaks.beat; }
82
83 // --- Expensive: lazy snapshots from Processor (compute-once) ---
84 const VibeLevels &vibe() const FL_NO_EXCEPT;
85 const EqLevels &equalizer() const FL_NO_EXCEPT;
87
88 // --- Raw frame access ---
89 fl::span<const AudioFrame> frames() const FL_NO_EXCEPT { return mFrames; }
90 bool empty() const FL_NO_EXCEPT { return mFrames.empty(); }
91 fl::size frameCount() const FL_NO_EXCEPT { return mFrames.size(); }
92 bool hasProcessor() const FL_NO_EXCEPT { return mProc != nullptr; }
93
94 // --- Range-based for over raw frames ---
95 const AudioFrame *begin() const FL_NO_EXCEPT { return mFrames.begin(); }
96 const AudioFrame *end() const FL_NO_EXCEPT { return mFrames.end(); }
97
98 private:
100 audio::Processor *mProc = nullptr; // non-owning, null = no audio
101
103
104 // Cheap peak aggregate
105 mutable bool mPeaksComputed = false;
107
108 // Expensive lazy snapshots
109 mutable bool mVibeComputed = false;
111
112 mutable bool mEqComputed = false;
113 mutable EqLevels mEq;
114
115 mutable bool mPercComputed = false;
117
118 void ensurePeaks() const FL_NO_EXCEPT;
119};
120
121} // namespace fl
void ensurePeaks() const FL_NO_EXCEPT
const AudioFrame * begin() const FL_NO_EXCEPT
Definition audio_batch.h:95
float mid() const FL_NO_EXCEPT
Definition audio_batch.h:78
float bass() const FL_NO_EXCEPT
Definition audio_batch.h:77
float treble() const FL_NO_EXCEPT
Definition audio_batch.h:79
fl::span< const AudioFrame > frames() const FL_NO_EXCEPT
Definition audio_batch.h:89
PercussionState mPerc
fl::size frameCount() const FL_NO_EXCEPT
Definition audio_batch.h:91
VibeLevels mVibe
bool hasProcessor() const FL_NO_EXCEPT
Definition audio_batch.h:92
float volume() const FL_NO_EXCEPT
Definition audio_batch.h:80
AudioBatch & operator=(const AudioBatch &) FL_NO_EXCEPT=delete
audio::Processor * mProc
bool beat() const FL_NO_EXCEPT
Definition audio_batch.h:81
const VibeLevels & vibe() const FL_NO_EXCEPT
const EqLevels & equalizer() const FL_NO_EXCEPT
fl::span< const AudioFrame > mFrames
Definition audio_batch.h:99
bool empty() const FL_NO_EXCEPT
Definition audio_batch.h:90
AudioBatch(const AudioBatch &) FL_NO_EXCEPT=delete
const AudioFrame * end() const FL_NO_EXCEPT
Definition audio_batch.h:96
const PercussionState & percussion() const FL_NO_EXCEPT
AudioFrame mPeaks
AudioBatch() FL_NO_EXCEPT=default
fl::mutex mMutex
Platform-independent mutex interface.
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
fl::platforms::mutex mutex
Definition mutex.h:20
Base definition for an LED controller.
Definition crgb.hpp:179
Snapshot of self-normalizing MilkDrop-style vibe levels.
Definition audio_batch.h:21
Snapshot of percussion detection state.
Definition audio_batch.h:47
Lightweight snapshot of pre-computed audio analysis for one audio sample.
Definition audio_frame.h:10
static constexpr int kNumBins
Definition audio_batch.h:36
float dominantFreqHz
Definition audio_batch.h:42
float bins[kNumBins]
Definition audio_batch.h:37
Snapshot of 16-bin normalized spectrum.
Definition audio_batch.h:35