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

◆ process()

Sample fl::audio::AutoGain::process ( const Sample & sample)

Process audio sample with automatic gain adjustment.

Parameters
sampleInput audio sample
Returns
Gain-adjusted audio sample

Definition at line 78 of file auto_gain.cpp.hpp.

78 {
79 // Pass through if disabled
80 if (!mConfig.enabled) {
81 return sample;
82 }
83
84 // Return empty sample if input is invalid or empty
85 if (!sample.isValid() || sample.size() == 0) {
86 return Sample(); // Return invalid sample
87 }
88
89 // Calculate input RMS
90 const float inputRMS = sample.rms();
91 mStats.inputRMS = inputRMS;
92
93 // Compute dt from sample size and sample rate
94 const float dt = (mSampleRate > 0 && sample.size() > 0)
95 ? static_cast<float>(sample.size()) / static_cast<float>(mSampleRate)
96 : 0.023f;
97
98 // Silence detection: spin down integrator when input is essentially silent
99 // (WLED: control_integrated *= 0.91 during silence)
100 const float silenceThreshold = 10.0f;
101 if (inputRMS < silenceThreshold) {
102 mIntegrator *= 0.91f;
103 if (fl::abs(mIntegrator) < 0.01f) mIntegrator = 0.0f;
104 }
105
106 // Step 1: Update peak envelope (fast attack, slow decay)
107 mPeakEnvelope.update(inputRMS, dt);
108 const float peakEnv = mPeakEnvelope.value();
109 mStats.peakEnvelope = peakEnv;
110
111 // Step 2: Compute target gain from peak envelope
112 const float targetGain = computeTargetGain();
113 mStats.targetGain = targetGain;
114
115 // Step 3: PI controller smoothly drives gain toward target
116 const float smoothedGain = updatePIController(targetGain, dt);
117
118 // Step 4: Clamp to configured range
119 const float clampedGain = fl::max(mConfig.minGain,
120 fl::min(mConfig.maxGain, smoothedGain));
121 mStats.currentGain = clampedGain;
122 mLastGain = clampedGain;
123
124 // Step 5: Apply gain to audio
125 const auto& pcm = sample.pcm();
126 mOutputBuffer.clear();
127 mOutputBuffer.reserve(pcm.size());
128 applyGain(pcm, clampedGain, mOutputBuffer);
129
130 // Calculate output RMS for statistics
131 i64 sumSq = 0;
132 for (size i = 0; i < mOutputBuffer.size(); ++i) {
133 i32 val = static_cast<i32>(mOutputBuffer[i]);
134 sumSq += val * val;
135 }
136 mStats.outputRMS = sqrtf(static_cast<float>(sumSq) / static_cast<float>(mOutputBuffer.size()));
137
138 // Update stats
139 mStats.samplesProcessed += sample.size();
140 mStats.integrator = mIntegrator;
141
142 // Create new Sample from amplified PCM
143 SampleImplPtr impl = fl::make_shared<SampleImpl>();
144 impl->assign(mOutputBuffer.begin(), mOutputBuffer.end(), sample.timestamp());
145 return Sample(impl);
146}
float mLastGain
Last smoothed gain output.
Definition auto_gain.h:158
AttackDecayFilter< float > mPeakEnvelope
Peak envelope tracker: fast attack (10ms), slow decay (preset-dependent)
Definition auto_gain.h:152
void applyGain(const vector< i16 > &input, float gain, vector< i16 > &output)
Apply gain to audio samples.
vector< i16 > mOutputBuffer
Working buffer (reused to avoid allocations)
Definition auto_gain.h:161
float updatePIController(float targetGain, float dt)
Update PI controller toward target gain.
float computeTargetGain()
Compute target gain from peak envelope.
float mIntegrator
PI integrator state.
Definition auto_gain.h:155
AutoGainConfig mConfig
Definition auto_gain.h:140
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NOEXCEPT
Definition math.h:71
float sqrtf(float value) FL_NOEXCEPT
Definition math.h:453
constexpr common_type_t< T, U > max(T a, U b) FL_NOEXCEPT
Definition math.h:75
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
fl::i64 i64
Definition s16x16x4.h:222
shared_ptr< T > make_shared(Args &&... args) FL_NOEXCEPT
Definition shared_ptr.h:414
constexpr enable_if< is_fixed_point< T >::value, T >::type abs(T x) FL_NOEXCEPT

References fl::abs(), applyGain(), computeTargetGain(), fl::make_shared(), fl::max(), mConfig, fl::min(), mIntegrator, mLastGain, mOutputBuffer, mPeakEnvelope, mSampleRate, mStats, fl::sample(), fl::sqrtf(), and updatePIController().

Referenced by ~AutoGain().

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