FastLED 3.9.15
Loading...
Searching...
No Matches

◆ processSample()

Sample fl::audio::SignalConditioner::processSample ( const Sample & sample)

Process a raw audio sample through the conditioning pipeline.

Parameters
sampleRaw audio sample from microphone/I2S
Returns
Cleaned audio sample (DC-removed, spike-filtered, gated)

Definition at line 33 of file signal_conditioner.cpp.hpp.

33 {
34 if (!sample.isValid() || sample.size() == 0) {
35 return Sample(); // Return empty sample
36 }
37
38 const auto pcm = sample.pcm();
39 const size sampleCount = pcm.size();
40
41 // Reserve buffers to avoid repeated allocations
42 mValidMask.clear();
43 mValidMask.reserve(sampleCount);
44 mTempBuffer.clear();
45 mTempBuffer.reserve(sampleCount);
46 mOutputBuffer.clear();
47 mOutputBuffer.reserve(sampleCount);
48
49 // Stage 1: Spike filtering (if enabled)
50 if (mConfig.enableSpikeFilter) {
52 } else {
53 // All samples valid if spike filtering disabled
54 mValidMask.assign(sampleCount, true);
55 }
56
57 // Stage 2: DC offset removal (if enabled)
58 // Uses per-buffer instantaneous DC calculation for accuracy,
59 // plus per-sample DCBlocker for cross-buffer continuity.
60 i32 dcOffset = 0;
61 if (mConfig.enableDCRemoval) {
62 dcOffset = calculateDCOffset(pcm, mValidMask);
63 removeDCOffset(pcm, dcOffset, mTempBuffer);
64 } else {
65 // Copy samples to temp buffer without DC removal
66 mTempBuffer.assign(pcm.begin(), pcm.end());
67 }
68
69 // Stage 3: Noise gate (if enabled)
70 if (mConfig.enableNoiseGate) {
72 } else {
73 // Copy temp buffer to output without gating
75 }
76
77 // Update stats
78 mStats.dcOffset = dcOffset;
79 mStats.noiseGateOpen = mNoiseGateOpen;
80 mStats.samplesProcessed += sampleCount;
81
82 // Create new Sample from cleaned PCM
83 SampleImplPtr impl = fl::make_shared<SampleImpl>();
84 impl->assign(mOutputBuffer.begin(), mOutputBuffer.end(), sample.timestamp());
85 return Sample(impl);
86}
void removeDCOffset(span< const i16 > pcm, i32 dcOffset, vector< i16 > &output) FL_NOEXCEPT
Remove DC offset from samples.
bool mNoiseGateOpen
Noise gate state.
i32 calculateDCOffset(span< const i16 > pcm, const vector< bool > &validMask) FL_NOEXCEPT
Calculate DC offset from valid samples only.
vector< bool > mValidMask
Working buffers (reused to avoid allocations)
void applyNoiseGate(span< const i16 > pcm, vector< i16 > &output) FL_NOEXCEPT
Apply noise gate with hysteresis.
size filterSpikes(span< const i16 > pcm, vector< bool > &validMask) FL_NOEXCEPT
Detect and reject spike samples.
SignalConditionerConfig mConfig
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
shared_ptr< T > make_shared(Args &&... args) FL_NOEXCEPT
Definition shared_ptr.h:414

References applyNoiseGate(), calculateDCOffset(), filterSpikes(), fl::make_shared(), mConfig, mNoiseGateOpen, mOutputBuffer, mStats, mTempBuffer, mValidMask, removeDCOffset(), and fl::sample().

Referenced by ~SignalConditioner().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: