Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::signal::osc::VcoOscillator Class Reference

Virtual-analog VCO over the static shapes, with a circuit-flavored deterministic path. More...

#include <vco.hpp>

Public Member Functions

 VcoOscillator () noexcept
 Seed the drift filter coefficients for the default sample rate so a default-constructed oscillator is valid before prepare(); prepare() recomputes them for the real rate.
void prepare (double sample_rate) noexcept
void set_shape (VaShape shape) noexcept
VaShape shape () const noexcept
void set_pulse_width (double width) noexcept
double pulse_width () const noexcept
void set_bow (double curvature) noexcept
 Curvature of the saw/ramp bow.
double bow () const noexcept
void set_waveshaper (VaShape shape, const WaveshaperParams &params) noexcept
WaveshaperParams waveshaper (VaShape shape) const noexcept
void set_level_tilt (double db_per_octave) noexcept
 Output level tilt, in dB per octave relative to kLevelReferenceHz.
double level_tilt () const noexcept
void set_core_reset_time (double seconds) noexcept
 Finite core-reset time, in seconds.
double core_reset_time () const noexcept
void set_ac_coupling (double corner_hz) noexcept
 Output DC-blocking corner, in Hz.
double ac_coupling () const noexcept
double ac_pole () const noexcept
 The DC blocker's realized pole for the current corner and sample rate; 1.0 when the stage is bypassed.
void set_drift_depth (double depth_cents) noexcept
 RMS of the slow drift wander, in cents.
double drift_depth () const noexcept
void set_drift_rate_hz (double corner_hz) noexcept
 Corner of the drift coloring filter, in Hz.
double drift_rate_hz () const noexcept
void set_jitter_depth (double depth_cents) noexcept
 RMS of the fast, near-white cycle-to-cycle jitter, in cents per sample.
double jitter_depth () const noexcept
void set_seed (std::uint64_t seed) noexcept
 Seed for both noise streams.
std::uint64_t seed () const noexcept
void reset (double phase=0.0) noexcept
 Reset the phase (and the AC-coupling and correction state) to a known point, and restart the noise streams from seed() so a reset render reproduces bit-for-bit.
double phase () const noexcept
double next (double increment) noexcept
 Generate one sample and advance by increment cycles.

Static Public Attributes

static constexpr double kDefaultDriftRateHz = 0.4
 Default drift corner (Hz): a wander whose correlation time is a few hundred milliseconds — slow relative to any audio-rate structure.
static constexpr double kLevelReferenceHz = 1000.0
 Reference level frequency for the tilt curve.

Detailed Description

Virtual-analog VCO over the static shapes, with a circuit-flavored deterministic path.

prepare(sample_rate) before the frequency-dependent stages (level-vs-pitch, AC coupling) are meaningful; the neutral defaults need no sample rate.

Constructor & Destructor Documentation

◆ VcoOscillator()

pulp::signal::osc::VcoOscillator::VcoOscillator ( )
inlinenoexcept

Seed the drift filter coefficients for the default sample rate so a default-constructed oscillator is valid before prepare(); prepare() recomputes them for the real rate.

Member Function Documentation

◆ ac_coupling()

double pulp::signal::osc::VcoOscillator::ac_coupling ( ) const
inlinenoexcept

◆ ac_pole()

double pulp::signal::osc::VcoOscillator::ac_pole ( ) const
inlinenoexcept

The DC blocker's realized pole for the current corner and sample rate; 1.0 when the stage is bypassed.

Exposed so a test can reproduce the exact LTI response the VCO applies.

◆ bow()

double pulp::signal::osc::VcoOscillator::bow ( ) const
inlinenoexcept

◆ core_reset_time()

double pulp::signal::osc::VcoOscillator::core_reset_time ( ) const
inlinenoexcept

◆ drift_depth()

double pulp::signal::osc::VcoOscillator::drift_depth ( ) const
inlinenoexcept

◆ drift_rate_hz()

double pulp::signal::osc::VcoOscillator::drift_rate_hz ( ) const
inlinenoexcept

◆ jitter_depth()

double pulp::signal::osc::VcoOscillator::jitter_depth ( ) const
inlinenoexcept

◆ level_tilt()

double pulp::signal::osc::VcoOscillator::level_tilt ( ) const
inlinenoexcept

◆ next()

double pulp::signal::osc::VcoOscillator::next ( double increment)
inlinenoexcept

Generate one sample and advance by increment cycles.

increment is the per-sample phase step (frequency ÷ sample rate) and is read every call, so FM and per-sample pitch modulation — and the drift/jitter source at this site — compose without an API change.

◆ phase()

double pulp::signal::osc::VcoOscillator::phase ( ) const
inlinenoexcept

◆ prepare()

void pulp::signal::osc::VcoOscillator::prepare ( double sample_rate)
inlinenoexcept

◆ pulse_width()

double pulp::signal::osc::VcoOscillator::pulse_width ( ) const
inlinenoexcept

◆ reset()

void pulp::signal::osc::VcoOscillator::reset ( double phase = 0.0)
inlinenoexcept

Reset the phase (and the AC-coupling and correction state) to a known point, and restart the noise streams from seed() so a reset render reproduces bit-for-bit.

◆ seed()

std::uint64_t pulp::signal::osc::VcoOscillator::seed ( ) const
inlinenoexcept

◆ set_ac_coupling()

void pulp::signal::osc::VcoOscillator::set_ac_coupling ( double corner_hz)
inlinenoexcept

Output DC-blocking corner, in Hz.

0 disables the stage (exact bypass, DC passes). When enabled the output is high-passed by a one-pole DC blocker whose pole is exp(-2*pi*corner/sample_rate), so DC is fully removed and the -3 dB point sits at the corner. Call prepare() first.

◆ set_bow()

void pulp::signal::osc::VcoOscillator::set_bow ( double curvature)
inlinenoexcept

Curvature of the saw/ramp bow.

0 is a perfectly linear ramp (exact bypass); larger values bow the rising ramp harder (a leaky integrator charges fast then flattens). The reshape is a pure function of phase, so its level is pitch-independent by construction — the leaky-integrator level defect the suite guards against never appears. Applies to the saw shape only; the other shapes' character comes from stages this increment does not model.

◆ set_core_reset_time()

void pulp::signal::osc::VcoOscillator::set_core_reset_time ( double seconds)
inlinenoexcept

Finite core-reset time, in seconds.

The reset edge consumes a fixed slice of every period, so it eats a growing FRACTION of shorter (higher-pitch) periods — a level sag proportional to frequency. 0 disables it (exact bypass). This is the level-vs-pitch contribution the identifiability table corroborates against edge width and HF tilt; here it is the level term.

◆ set_drift_depth()

void pulp::signal::osc::VcoOscillator::set_drift_depth ( double depth_cents)
inlinenoexcept

RMS of the slow drift wander, in cents.

0 disables drift (its stream does not advance). The drift is a one-pole-colored random walk whose stationary output has unit variance, so this depth is the RMS pitch excursion the wander reaches; its timescale is set_drift_rate_hz. Off by default, so a neutral VCO is unaffected.

◆ set_drift_rate_hz()

void pulp::signal::osc::VcoOscillator::set_drift_rate_hz ( double corner_hz)
inlinenoexcept

Corner of the drift coloring filter, in Hz.

Lower is a slower wander; the default puts the wander in the hundreds-of-milliseconds range. Recomputes the filter pole against the current sample rate.

◆ set_jitter_depth()

void pulp::signal::osc::VcoOscillator::set_jitter_depth ( double depth_cents)
inlinenoexcept

RMS of the fast, near-white cycle-to-cycle jitter, in cents per sample.

0 disables jitter (its stream does not advance). Independent per sample, so this is the RMS of the per-sample frequency deviation. Off by default.

◆ set_level_tilt()

void pulp::signal::osc::VcoOscillator::set_level_tilt ( double db_per_octave)
inlinenoexcept

Output level tilt, in dB per octave relative to kLevelReferenceHz.

0 is flat (exact bypass); POSITIVE rolls the top off (gain 10^(-tilt·octaves/20), so a note an octave above the reference loses tilt dB), as an analog VCO's output buffer does; negative lifts it. Independent of the core-reset sag below.

◆ set_pulse_width()

void pulp::signal::osc::VcoOscillator::set_pulse_width ( double width)
inlinenoexcept

◆ set_seed()

void pulp::signal::osc::VcoOscillator::set_seed ( std::uint64_t seed)
inlinenoexcept

Seed for both noise streams.

Determinism is a contract: the same seed and inputs reproduce the output bit-for-bit. Takes effect on the streams immediately and is re-applied by reset(), so a seeded render starts from a known point.

◆ set_shape()

void pulp::signal::osc::VcoOscillator::set_shape ( VaShape shape)
inlinenoexcept

◆ set_waveshaper()

void pulp::signal::osc::VcoOscillator::set_waveshaper ( VaShape shape,
const WaveshaperParams & params )
inlinenoexcept

◆ shape()

VaShape pulp::signal::osc::VcoOscillator::shape ( ) const
inlinenoexcept

◆ waveshaper()

WaveshaperParams pulp::signal::osc::VcoOscillator::waveshaper ( VaShape shape) const
inlinenoexcept

Member Data Documentation

◆ kDefaultDriftRateHz

double pulp::signal::osc::VcoOscillator::kDefaultDriftRateHz = 0.4
staticconstexpr

Default drift corner (Hz): a wander whose correlation time is a few hundred milliseconds — slow relative to any audio-rate structure.

◆ kLevelReferenceHz

double pulp::signal::osc::VcoOscillator::kLevelReferenceHz = 1000.0
staticconstexpr

Reference level frequency for the tilt curve.


The documentation for this class was generated from the following file:
  • /home/runner/work/pulp/pulp/core/signal/include/pulp/signal/osc/vco.hpp