DSPark 1.6.1
Header-only audio DSP framework in pure C++20 — zero dependencies
Loading...
Searching...
No Matches
LevelFollower.h File Reference

Envelope follower for real-time peak and RMS level metering. More...

#include "../Core/AudioBuffer.h"
#include "../Core/AudioSpec.h"
#include "../Core/DspMath.h"
#include <algorithm>
#include <array>
#include <atomic>
#include <cmath>
#include <type_traits>
Include dependency graph for LevelFollower.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  dspark::LevelFollower< T, MaxChannels >
 Per-channel peak and RMS envelope follower with lock-free readout. More...
 

Namespaces

namespace  dspark
 Main namespace for the DSPark framework.
 

Detailed Description

Envelope follower for real-time peak and RMS level metering.

Tracks per-channel peak and RMS levels with lock-free readout for UI metering. Peak uses an asymmetric attack/release one-pole; RMS uses a symmetric one-pole exponential integrator over the squared signal (a VU-style exponential window whose time constant equals the configured window time - not a rectangular moving average). A small constant offset keeps both recursions out of the subnormal range on decay tails; its equilibrium floor sits far below the -100 dB readout floor.

Threading:

  • prepare() / reset(): setup thread (not concurrent with process()).
  • setAttackMs() / setReleaseMs() / setRmsWindowMs(): any thread. Parameters and coefficients are published atomically; process() picks them up at the next block. A block may observe one changed coefficient before another (benign for metering). Non-finite values are ignored.
  • process(): audio thread (stream owner).
  • getPeakLevel() / getRmsLevel() / *Db(): any thread (relaxed atomic reads; values are approximate while a block is in flight - metering).

Dependencies: AudioBuffer.h, AudioSpec.h, DspMath.h.

meter.prepare(spec);
meter.setAttackMs(1.0f);
meter.setReleaseMs(100.0f);
meter.setRmsWindowMs(300.0f);
// In process() (Audio Thread):
meter.process(buffer.toView());
// In UI Thread (Safe, lock-free reading):
float peakDb = meter.getPeakLevelDb(0);
float rmsDb = meter.getRmsLevelDb(0);
Per-channel peak and RMS envelope follower with lock-free readout.
void prepare(const AudioSpec &spec) noexcept
Prepares the follower for the given audio environment.
T getRmsLevelDb(int channel) const noexcept
Returns the current RMS level in decibels (optimized).
void setReleaseMs(float ms) noexcept
Sets the release time for peak metering.
void setRmsWindowMs(float ms) noexcept
Sets the integration time constant for RMS metering.
T getPeakLevelDb(int channel) const noexcept
Returns the current peak level in decibels.
void process(AudioBufferView< const T > buffer) noexcept
Processes a block of audio and updates level tracking.
void setAttackMs(float ms) noexcept
Sets the attack time for peak metering.

Definition in file LevelFollower.h.