Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::signal::NonlinAmbienceT< SampleType > Class Template Reference

The nonlin / gated ambience engine. Stereo, processed in place. More...

#include <nonlin_ambience.hpp>

Classes

struct  Tap
 One velvet tap: where to read, how much to scale it, and which spectral segment it belongs to. More...

Public Member Functions

void prepare (double sample_rate, double max_length_ms=nonlin_ambience::kMaxLengthMs, double max_predelay_ms=nonlin_ambience::kMaxPredelayMs)
 Allocates the tap ring and both tap banks.
void reset ()
 Clears every state.
void set_program (NonlinProgram program)
void set_length_ms (double ms)
 Window length in ms — the absolute time the dimensionless envelope is stretched across.
void set_predelay_ms (double ms)
void set_density_pct (double pct)
 Scales Nd_min only; Nd_max is fixed so the late field stays above the smoothness floor no matter how sparse the early field is made.
void set_density_growth (double gamma)
void set_gate_hold_pct (double pct)
 The Gated program's hold point, as a percent of the window.
void set_attack_pct (double pct)
 The Reverse program's rise point and the NonLin2 program's gate point, as a percent of the window.
void set_topology (NonlinProgram program, double length_ms, double predelay_ms, double density_pct, double density_growth, double gate_hold_pct, double attack_pct)
 Atomically applies the complete topology snapshot and regenerates the inactive tap bank at most once.
void request_topology (NonlinProgram program, double length_ms, double predelay_ms, double density_pct, double density_growth, double gate_hold_pct, double attack_pct)
 RT-bounded counterpart used by hosted automation.
std::uint64_t topology_rebuild_count () const
int topology_work_units_last_sample () const
void set_seed (std::uint32_t seed)
 Seed for the L channel; R derives as seed ⊕ kSeedRodd.
void set_diffusion (double g)
 Allpass coefficient.
void set_tone (double tone)
 Spectral tilt T ∈ [−1, +1]: positive keeps highs later (brighter), negative darkens.
void set_hf_damp_hz (double hz)
void set_width_pct (double pct)
 0 % is mono (both channels exactly the mid signal), 100 % is the two independent velvet realizations.
void set_converter_amount (double amount)
 0 disables the converter stage entirely.
void set_output_gain_db (double db)
void set_mix_pct (double pct)
 Dry/wet, 0 .. 100 %. The default is 100 (send style).
void process_sample (SampleType &left, SampleType &right)
 One stereo frame, in place. Allocation-free, lock-free, branch-light.
void process (SampleType *left, SampleType *right, int num_samples)
 A block of stereo frames, in place.
int tap_count (int channel) const
 Number of taps currently live on channel (0 = L, 1 = R).
const Tap & tap (int channel, int index) const
 Tap index on channel.
double tap_norm (int channel) const
 The L1 normalization scalar solved for channel's live tap table, so a caller can predict |g_k| without re-deriving the normalization.
int window_samples () const
 Window length in samples — the denominator of every τ.
int predelay_samples () const
int allpass_length (int index) const
double worst_case_gain () const
 The worst-case gain for the current settings, as a closed form of the shipped constants (series law 8).
NonlinProgram program () const
double length_ms () const
double tone () const
bool swap_in_progress () const
double envelope (double tau) const
 The normalized envelope this instance's current settings ask for.

Static Public Member Functions

static constexpr int latency_samples ()
 Series law 5: exactly zero.

Static Public Attributes

static constexpr int kTopologyWorkPerSample = 4
 Maximum tap-builder iterations charged to one audio frame.

Detailed Description

template<typename SampleType = float>
class pulp::signal::NonlinAmbienceT< SampleType >

The nonlin / gated ambience engine. Stereo, processed in place.

Member Function Documentation

◆ allpass_length()

template<typename SampleType = float>
int pulp::signal::NonlinAmbienceT< SampleType >::allpass_length ( int index) const
inline

◆ envelope()

template<typename SampleType = float>
double pulp::signal::NonlinAmbienceT< SampleType >::envelope ( double tau) const
inline

The normalized envelope this instance's current settings ask for.

The program-specific h / r are resolved from the percent parameters here so callers do not have to know which program reads which.

◆ latency_samples()

template<typename SampleType = float>
constexpr int pulp::signal::NonlinAmbienceT< SampleType >::latency_samples ( )
inlinestaticconstexpr

Series law 5: exactly zero.

The dry path is a straight wire and the wet pre-delay is the effect, not latency.

◆ length_ms()

template<typename SampleType = float>
double pulp::signal::NonlinAmbienceT< SampleType >::length_ms ( ) const
inline

◆ predelay_samples()

template<typename SampleType = float>
int pulp::signal::NonlinAmbienceT< SampleType >::predelay_samples ( ) const
inline

◆ prepare()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::prepare ( double sample_rate,
double max_length_ms = nonlin_ambience::kMaxLengthMs,
double max_predelay_ms = nonlin_ambience::kMaxPredelayMs )
inline

Allocates the tap ring and both tap banks.

The only function here that may allocate. max_length_ms and max_predelay_ms size the storage; no later set_* can outgrow them because both are clamped to these maxima.

◆ process()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::process ( SampleType * left,
SampleType * right,
int num_samples )
inline

A block of stereo frames, in place.

◆ process_sample()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::process_sample ( SampleType & left,
SampleType & right )
inline

One stereo frame, in place. Allocation-free, lock-free, branch-light.

◆ program()

template<typename SampleType = float>
NonlinProgram pulp::signal::NonlinAmbienceT< SampleType >::program ( ) const
inline

◆ request_topology()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::request_topology ( NonlinProgram program,
double length_ms,
double predelay_ms,
double density_pct,
double density_growth,
double gate_hold_pct,
double attack_pct )
inline

RT-bounded counterpart used by hosted automation.

The requested snapshot is generated incrementally into the inactive bank; the audible topology changes only after the complete, normalized bank is ready.

◆ reset()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::reset ( )
inline

Clears every state.

Never allocates. Tap tables survive — they are a pure function of the parameters, not of the signal history.

◆ set_attack_pct()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_attack_pct ( double pct)
inline

The Reverse program's rise point and the NonLin2 program's gate point, as a percent of the window.

Ignored by Ambience and Gated.

◆ set_converter_amount()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_converter_amount ( double amount)
inline

0 disables the converter stage entirely.

◆ set_density_growth()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_density_growth ( double gamma)
inline

◆ set_density_pct()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_density_pct ( double pct)
inline

Scales Nd_min only; Nd_max is fixed so the late field stays above the smoothness floor no matter how sparse the early field is made.

◆ set_diffusion()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_diffusion ( double g)
inline

Allpass coefficient.

Touches two scalars and no tap, so it does not rebuild (see the file note). Clamped below 1 for stability.

◆ set_gate_hold_pct()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_gate_hold_pct ( double pct)
inline

The Gated program's hold point, as a percent of the window.

◆ set_hf_damp_hz()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_hf_damp_hz ( double hz)
inline

◆ set_length_ms()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_length_ms ( double ms)
inline

Window length in ms — the absolute time the dimensionless envelope is stretched across.

Clamped to the prepare() maximum.

◆ set_mix_pct()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_mix_pct ( double pct)
inline

Dry/wet, 0 .. 100 %. The default is 100 (send style).

◆ set_output_gain_db()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_output_gain_db ( double db)
inline

◆ set_predelay_ms()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_predelay_ms ( double ms)
inline

◆ set_program()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_program ( NonlinProgram program)
inline

◆ set_seed()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_seed ( std::uint32_t seed)
inline

Seed for the L channel; R derives as seed ⊕ kSeedRodd.

Series law 2 — a preset choice, never automated.

◆ set_tone()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_tone ( double tone)
inline

Spectral tilt T ∈ [−1, +1]: positive keeps highs later (brighter), negative darkens.

Recomputes the segment coefficients rather than smoothing them — a one-pole corner change is state-continuous, so it produces no step in the output the way a gain change would.

◆ set_topology()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_topology ( NonlinProgram program,
double length_ms,
double predelay_ms,
double density_pct,
double density_growth,
double gate_hold_pct,
double attack_pct )
inline

Atomically applies the complete topology snapshot and regenerates the inactive tap bank at most once.

Catalog/host block boundaries use this instead of invoking seven independently rebuilding setters.

◆ set_width_pct()

template<typename SampleType = float>
void pulp::signal::NonlinAmbienceT< SampleType >::set_width_pct ( double pct)
inline

0 % is mono (both channels exactly the mid signal), 100 % is the two independent velvet realizations.

◆ swap_in_progress()

template<typename SampleType = float>
bool pulp::signal::NonlinAmbienceT< SampleType >::swap_in_progress ( ) const
inline

◆ tap()

template<typename SampleType = float>
const Tap & pulp::signal::NonlinAmbienceT< SampleType >::tap ( int channel,
int index ) const
inline

Tap index on channel.

Delay is in samples from the write head; segment is its spectral-tilt group.

◆ tap_count()

template<typename SampleType = float>
int pulp::signal::NonlinAmbienceT< SampleType >::tap_count ( int channel) const
inline

Number of taps currently live on channel (0 = L, 1 = R).

◆ tap_norm()

template<typename SampleType = float>
double pulp::signal::NonlinAmbienceT< SampleType >::tap_norm ( int channel) const
inline

The L1 normalization scalar solved for channel's live tap table, so a caller can predict |g_k| without re-deriving the normalization.

◆ tone()

template<typename SampleType = float>
double pulp::signal::NonlinAmbienceT< SampleType >::tone ( ) const
inline

◆ topology_rebuild_count()

template<typename SampleType = float>
std::uint64_t pulp::signal::NonlinAmbienceT< SampleType >::topology_rebuild_count ( ) const
inline

◆ topology_work_units_last_sample()

template<typename SampleType = float>
int pulp::signal::NonlinAmbienceT< SampleType >::topology_work_units_last_sample ( ) const
inline

◆ window_samples()

template<typename SampleType = float>
int pulp::signal::NonlinAmbienceT< SampleType >::window_samples ( ) const
inline

Window length in samples — the denominator of every τ.

Every geometry accessor describes the bank currently being heard, not the most recent set_*. During the kSwapFadeMs window after a topology change the two differ, and reporting the new geometry against the old tap table would make tap(ch, k).delay / window_samples() a τ that belongs to neither.

◆ worst_case_gain()

template<typename SampleType = float>
double pulp::signal::NonlinAmbienceT< SampleType >::worst_case_gain ( ) const
inline

The worst-case gain for the current settings, as a closed form of the shipped constants (series law 8).

Member Data Documentation

◆ kTopologyWorkPerSample

template<typename SampleType = float>
int pulp::signal::NonlinAmbienceT< SampleType >::kTopologyWorkPerSample = 4
staticconstexpr

Maximum tap-builder iterations charged to one audio frame.

Topology automation is staged into the inactive bank and therefore has a hard, input-independent callback cost instead of rebuilding the room at once.


The documentation for this class was generated from the following file: