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

Dedicated variable-clock ZOH wavetable oscillator (the lo-fi tier). More...

#include <wt_lofi.hpp>

Public Member Functions

bool set_tables (std::vector< std::vector< double > > tables, int bit_depth=kDefaultBitDepth)
 Install the raw single-cycle table set (off the audio thread), returning whether the set was accepted.
void prepare (double sample_rate)
 Set the sample rate. Safe to call again on a rate change.
void set_scan (double pos)
 Select the table nearest scan position pos (0 = first, 1 = last), clamped.
void set_reconstruction (bool enabled)
 Enable (default) or disable the oversample → reconstruction → decimate stage.
void set_oversample_factor (int factor)
 Set the reconstruction oversample factor (>= 1; 1 disables the stage even when reconstruction is enabled).
void reset ()
 Reset the playback phase to the start of the cycle and clear the reconstruction filter state.
double next (double increment)
 Generate one sample and advance by increment cycles (frequency ÷ sample rate).
std::size_t table_length () const
std::size_t table_count () const
int current_table () const
int bit_depth () const
std::span< const double > stored_table (std::size_t i) const
 Read-only view of a stored table — the actual (post-quantization) sample data the reader plays.
double sample_rate () const
 The configured sample rate.
bool reconstruction_enabled () const
int oversample_factor () const

Static Public Attributes

static constexpr int kDefaultBitDepth = 8
 Default stored-table resolution.
static constexpr int kFullPrecision = 0
 Sentinel bit depth: store the table at full double precision (no quantization).
static constexpr int kDefaultOversampleFactor = 16
 Default oversample factor for the reconstruction stage.
static constexpr double kReconstructionStopbandDb = 96.0
 Reconstruction-filter stopband depth (dB) handed to the Kaiser design.

Detailed Description

Dedicated variable-clock ZOH wavetable oscillator (the lo-fi tier).

Member Function Documentation

◆ bit_depth()

int pulp::signal::osc::LofiWtOscillator::bit_depth ( ) const
inline

◆ current_table()

int pulp::signal::osc::LofiWtOscillator::current_table ( ) const
inline

◆ next()

double pulp::signal::osc::LofiWtOscillator::next ( double increment)
inline

Generate one sample and advance by increment cycles (frequency ÷ sample rate).

The table-phase clock advances by increment · L table samples per host sample — i.e. the table is clocked at fs_play = f0 · L — so the ZOH images ride at n · L · f0 and track pitch. Playback is for non-negative increments.

◆ oversample_factor()

int pulp::signal::osc::LofiWtOscillator::oversample_factor ( ) const
inline

◆ prepare()

void pulp::signal::osc::LofiWtOscillator::prepare ( double sample_rate)
inline

Set the sample rate. Safe to call again on a rate change.

◆ reconstruction_enabled()

bool pulp::signal::osc::LofiWtOscillator::reconstruction_enabled ( ) const
inline

◆ reset()

void pulp::signal::osc::LofiWtOscillator::reset ( )
inline

Reset the playback phase to the start of the cycle and clear the reconstruction filter state.

◆ sample_rate()

double pulp::signal::osc::LofiWtOscillator::sample_rate ( ) const
inline

The configured sample rate.

The reader itself is rate-agnostic — it works in per-sample increment terms and designs the reconstruction filter in frequency normalized to the oversample rate — so this is retained only for module-convention parity and host reporting.

◆ set_oversample_factor()

void pulp::signal::osc::LofiWtOscillator::set_oversample_factor ( int factor)
inline

Set the reconstruction oversample factor (>= 1; 1 disables the stage even when reconstruction is enabled).

Rebuilds the filter (off the audio thread).

◆ set_reconstruction()

void pulp::signal::osc::LofiWtOscillator::set_reconstruction ( bool enabled)
inline

Enable (default) or disable the oversample → reconstruction → decimate stage.

Disabled = raw naive point-sampling at the host rate, which folds an audible supra-Nyquist image in-band; exposed for A/B and for the rawer grit. Rebuilds the filter (off the audio thread).

◆ set_scan()

void pulp::signal::osc::LofiWtOscillator::set_scan ( double pos)
inline

Select the table nearest scan position pos (0 = first, 1 = last), clamped.

HARD select: no interpolation across the scan dimension and no slew, so a scan sweep STEPS between adjacent tables — the faithful lo-fi zipper. Contrast WtOscillator::set_position, which slews.

◆ set_tables()

bool pulp::signal::osc::LofiWtOscillator::set_tables ( std::vector< std::vector< double > > tables,
int bit_depth = kDefaultBitDepth )
inline

Install the raw single-cycle table set (off the audio thread), returning whether the set was accepted.

Every table must share one length L: a mismatched set (tables of differing length) is REJECTED — the call is a no-op that leaves the previous set intact and returns false — rather than truncated to the shortest common length, because truncating a table plays a fraction of its cycle as a full cycle (a corrupted, off-pitch waveform). An empty set is accepted and leaves the oscillator silent. Each accepted table is copied and, when bit_depth is not kFullPrecision, quantized about zero to bit_depth bits — on the stored table data, which is where the lo-fi grit lives.

◆ stored_table()

std::span< const double > pulp::signal::osc::LofiWtOscillator::stored_table ( std::size_t i) const
inline

Read-only view of a stored table — the actual (post-quantization) sample data the reader plays.

Exposed so a test can grade the engine's own quantization directly rather than re-deriving it from a private copy of the quantizer (which would pass even if the engine's quantizer drifted). Empty span for an out-of-range index.

◆ table_count()

std::size_t pulp::signal::osc::LofiWtOscillator::table_count ( ) const
inline

◆ table_length()

std::size_t pulp::signal::osc::LofiWtOscillator::table_length ( ) const
inline

Member Data Documentation

◆ kDefaultBitDepth

int pulp::signal::osc::LofiWtOscillator::kDefaultBitDepth = 8
staticconstexpr

Default stored-table resolution.

8 bits is the lo-fi grit; pass kFullPrecision for an ungritted table (the tests use it so the ZOH images are the only spuria).

◆ kDefaultOversampleFactor

int pulp::signal::osc::LofiWtOscillator::kDefaultOversampleFactor = 16
staticconstexpr

Default oversample factor for the reconstruction stage.

Chosen so the residual modeling-alias floor sits comfortably below −77 dBc in-band; see the reconstruction discussion above.

◆ kFullPrecision

int pulp::signal::osc::LofiWtOscillator::kFullPrecision = 0
staticconstexpr

Sentinel bit depth: store the table at full double precision (no quantization).

Any depth <= 0 or >= 53 is treated as full precision.

◆ kReconstructionStopbandDb

double pulp::signal::osc::LofiWtOscillator::kReconstructionStopbandDb = 96.0
staticconstexpr

Reconstruction-filter stopband depth (dB) handed to the Kaiser design.


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