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

A bank of band-limited square-wave oscillators at fixed frequencies, summed into one output. More...

#include <square_osc_bank.hpp>

Classes

struct  Partial
 One partial of the bank: a frequency in Hz and a linear weight. More...

Public Member Functions

void prepare (SampleType sample_rate)
 Set the sample rate and re-arm the existing oscillators for it.
void set_partials (const Partial *partials, std::size_t count)
 Install the bank's partials.
void set_partials (const std::vector< Partial > &partials)
 Convenience overload for a std::vector of partials.
std::size_t size () const noexcept
void set_frequency (std::size_t index, SampleType hz) noexcept
 Retune one oscillator in place. No allocation; out-of-range is a no-op.
void set_amplitude (std::size_t index, SampleType amp) noexcept
 Reweight one oscillator in place. No allocation; out-of-range is a no-op.
SampleType frequency (std::size_t index) const noexcept
SampleType amplitude (std::size_t index) const noexcept
void set_level (SampleType level) noexcept
 Overall output gain applied after the weighted sum.
SampleType level () const noexcept
void reset () noexcept
 Zero every oscillator's phase so the cluster restarts coherent.
SampleType process () noexcept
 Sum of the weighted band-limited squares for the next sample.
SampleType peak_bound () const noexcept
 The largest magnitude process() can return with the current partials and level: |level| times the sum of the absolute weights.

Detailed Description

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

A bank of band-limited square-wave oscillators at fixed frequencies, summed into one output.

This is a reusable excitation source for metallic and electronic sounds: callers choose any number of independently tuned, weighted square oscillators, then apply their own filtering and amplitude envelope.

The frequencies are deliberately inharmonic (not integer multiples of a fundamental): a metallic timbre is a dense, clangorous cluster of partials with no shared period, which is exactly what a handful of detuned squares summed together produce. A single square already carries only odd harmonics; six of them at incommensurate pitches fill the spectrum without ever landing on a tidy harmonic series.

Each oscillator is the repository's band-limited OscillatorT set to its square waveform, so the sum inherits that class's polyBLEP anti-aliasing rather than a naive sign() square's alias skirt. See the anti-alias assertions in test_square_osc_bank.cpp for the measured alias floor.

RT contract: prepare() and set_partials() size the internal storage and may allocate. Every per-sample and per-parameter call after that – process(), reset(), set_frequency(), set_amplitude(), set_level() – allocates nothing and never resizes.

Member Function Documentation

◆ amplitude()

template<typename SampleType = float>
SampleType pulp::signal::SquareOscBankT< SampleType >::amplitude ( std::size_t index) const
inlinenoexcept

◆ frequency()

template<typename SampleType = float>
SampleType pulp::signal::SquareOscBankT< SampleType >::frequency ( std::size_t index) const
inlinenoexcept

◆ level()

template<typename SampleType = float>
SampleType pulp::signal::SquareOscBankT< SampleType >::level ( ) const
inlinenoexcept

◆ peak_bound()

template<typename SampleType = float>
SampleType pulp::signal::SquareOscBankT< SampleType >::peak_bound ( ) const
inlinenoexcept

The largest magnitude process() can return with the current partials and level: |level| times the sum of the absolute weights.

A caller can use this to normalize the bank to unity, or a test can assert the output never exceeds it.

◆ prepare()

template<typename SampleType = float>
void pulp::signal::SquareOscBankT< SampleType >::prepare ( SampleType sample_rate)
inline

Set the sample rate and re-arm the existing oscillators for it.

Safe to call before or after set_partials(); does not change the partial layout.

◆ process()

template<typename SampleType = float>
SampleType pulp::signal::SquareOscBankT< SampleType >::process ( )
inlinenoexcept

Sum of the weighted band-limited squares for the next sample.

No allocation, no locking, no resizing.

◆ reset()

template<typename SampleType = float>
void pulp::signal::SquareOscBankT< SampleType >::reset ( )
inlinenoexcept

Zero every oscillator's phase so the cluster restarts coherent.

Cheap; safe on the audio thread. Not called implicitly by process().

◆ set_amplitude()

template<typename SampleType = float>
void pulp::signal::SquareOscBankT< SampleType >::set_amplitude ( std::size_t index,
SampleType amp )
inlinenoexcept

Reweight one oscillator in place. No allocation; out-of-range is a no-op.

◆ set_frequency()

template<typename SampleType = float>
void pulp::signal::SquareOscBankT< SampleType >::set_frequency ( std::size_t index,
SampleType hz )
inlinenoexcept

Retune one oscillator in place. No allocation; out-of-range is a no-op.

◆ set_level()

template<typename SampleType = float>
void pulp::signal::SquareOscBankT< SampleType >::set_level ( SampleType level)
inlinenoexcept

Overall output gain applied after the weighted sum.

◆ set_partials() [1/2]

template<typename SampleType = float>
void pulp::signal::SquareOscBankT< SampleType >::set_partials ( const Partial * partials,
std::size_t count )
inline

Install the bank's partials.

Allocates when the count changes; this is a prepare-time call, not an audio-thread call. Phases are reset so the cluster always starts coherent.

◆ set_partials() [2/2]

template<typename SampleType = float>
void pulp::signal::SquareOscBankT< SampleType >::set_partials ( const std::vector< Partial > & partials)
inline

Convenience overload for a std::vector of partials.

◆ size()

template<typename SampleType = float>
std::size_t pulp::signal::SquareOscBankT< SampleType >::size ( ) const
inlinenoexcept

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