Sound Byte Libs 29c5ff3
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
Namespaces | Classes | Typedefs | Enumerations | Functions | Variables
sbl::dsp Namespace Reference

DSP atoms for audio signal processing. More...

Namespaces

namespace  curve
 
namespace  lut
 Lookup table functions.
 
namespace  pitch
 Pitch conversion utilities.
 
namespace  polyblep
 Band-limited oscillator corrections.
 
namespace  stereo
 Stereo panning utilities.
 

Classes

class  AllpassFilter
 
class  DcBlocker
 
class  DelayLine
 
class  EnvelopeFollower
 
struct  ExpCurveWarp
 
struct  FloatRationalWarp
 
class  HysteresisQuantizer
 
class  ModulatedDelayLine
 
class  OnePole
 
class  ParameterInterpolator
 
class  PhaseAccumulator
 
struct  RationalWarp
 
struct  Segment
 
class  SegmentGenerator
 
class  SlewLimiter
 
class  Waveshaper
 
class  WavetableReader
 

Typedefs

using Sample = int32_t
 
using DefaultWarp = ExpCurveWarp
 
using FloatDefaultWarp = FloatRationalWarp
 

Enumerations

enum class  SegmentState : uint8_t { Idle , Running , Sustain , Complete }
 

Functions

float to_float (Sample s)
 
Sample to_sample (float f)
 
void to_float (const Sample *in, float *out, uint16_t frames)
 
void to_sample (const float *in, Sample *out, uint16_t frames)
 
void deinterleave_to_float (const int32_t *interleaved, float *left, float *right, uint16_t frames)
 
void interleave_from_float (const float *left, const float *right, int32_t *interleaved, uint16_t frames)
 
float fast_sinf (float x)
 
float fast_tan_pif (float f)
 
float fast_exp2f (float x)
 
constexpr int32_t saturate_24 (int32_t x)
 Clamp value to 24-bit audio range.
 
constexpr float crossfade (float a, float b, float t)
 Linear crossfade between two values.
 
constexpr float smooth_step (float t)
 Hermite smooth step (3rd-order S-curve)
 
constexpr int32_t crossfade_i16 (int16_t a, int16_t b, uint16_t t)
 Integer crossfade for 16-bit values.
 
float crossfade_equal_power (float a, float b, float t)
 Equal-power crossfade between two values.
 
void crossfade_block (const float *a, const float *b, float *out, float mix, uint16_t frames)
 Linear crossfade over a block with constant mix.
 
void crossfade_block_equal_power (const float *a, const float *b, float *out, float mix, uint16_t frames)
 Equal-power crossfade over a block with constant mix.
 
constexpr float cc_to_float (uint8_t val)
 Normalize MIDI CC (0-127) to [0.0, 1.0].
 
constexpr float u16_to_float (uint16_t val)
 Normalize 16-bit unsigned (0-65535) to [0.0, 1.0].
 
constexpr float u14_to_float (uint16_t val)
 Normalize 14-bit MIDI (0-16383) to [0.0, 1.0] (pitch bend, NRPN)
 
constexpr float map_linear (float t, float min, float max)
 Linear mapping: t → min + (max - min) * t.
 
constexpr float map_quadratic (float t, float min, float max)
 
constexpr float map_scurve (float t, float min, float max)
 
float semitones_to_ratio (float semitones)
 
float semitones_to_ratio_safe (float semitones)
 
float note_to_ratio (float midi_note)
 
float note_to_frequency (float midi_note)
 MIDI note to frequency in Hz. A4 = 440 Hz.
 
uint32_t note_to_phase_increment (float midi_note, float sample_rate)
 
float exp2_approx (float x)
 Fast 2^x approximation via pitch tables. x in [-10.67, +10.58].
 
float exp2_approx_safe (float x)
 Extended range 2^x.
 
float soft_limit (float x)
 Smooth saturation with unity gain at origin.
 
float soft_clip (float x)
 Bounded soft clipper — output in [-1, 1].
 
int32_t soft_clip_24 (int32_t x)
 Soft saturation for 24-bit audio samples.
 
template<uint16_t Size>
uint16_t lut_curve_warp (const uint16_t *table, uint16_t phase, uint16_t curve)
 

Variables

constexpr float SAMPLE_SCALE_F = 8388607.0f
 
constexpr float SAMPLE_SCALE_INV_F = 1.0f / 8388607.0f
 
constexpr uint32_t Q16_ONE = 65536u
 
constexpr uint16_t U16_MAX = 65535u
 
constexpr uint16_t U16_MID = 32768u
 
constexpr uint16_t FRAC16_MASK = 0xffff
 
constexpr int32_t SAMPLE_MAX_24 = 8388607
 
constexpr int32_t SAMPLE_MIN_24 = -8388607
 

Detailed Description

DSP atoms for audio signal processing.

Stateful signal processing primitives (Layer 3):

Typedef Documentation

◆ DefaultWarp

Definition at line 145 of file warp.hpp.

◆ FloatDefaultWarp

Default float warp engine for SegmentGenerator and Envelope. FloatRationalWarp: zero flash, analytical, good character.

Definition at line 184 of file warp.hpp.

◆ Sample

using sbl::dsp::Sample = typedef int32_t

Definition at line 11 of file types.hpp.

Enumeration Type Documentation

◆ SegmentState

enum class sbl::dsp::SegmentState : uint8_t
strong
Enumerator
Idle 
Running 
Sustain 
Complete 

Definition at line 33 of file segment.hpp.

Function Documentation

◆ cc_to_float()

constexpr float sbl::dsp::cc_to_float ( uint8_t  val)
inlineconstexpr

Normalize MIDI CC (0-127) to [0.0, 1.0].

Definition at line 20 of file param.hpp.

◆ crossfade()

constexpr float sbl::dsp::crossfade ( float  a,
float  b,
float  t 
)
inlineconstexpr

Linear crossfade between two values.

Parameters
aValue at t=0
bValue at t=1
tBlend factor [0.0, 1.0]
Returns
a + (b - a) * t

Definition at line 25 of file interpolate.hpp.

◆ crossfade_block()

void sbl::dsp::crossfade_block ( const float *  a,
const float *  b,
float *  out,
float  mix,
uint16_t  frames 
)
inline

Linear crossfade over a block with constant mix.

out[i] = a[i] * (1-mix) + b[i] * mix. In-place safe (out can alias a or b).

Definition at line 78 of file interpolate.hpp.

◆ crossfade_block_equal_power()

void sbl::dsp::crossfade_block_equal_power ( const float *  a,
const float *  b,
float *  out,
float  mix,
uint16_t  frames 
)
inline

Equal-power crossfade over a block with constant mix.

out[i] = a[i] * sqrt(1-mix) + b[i] * sqrt(mix). Gains computed once.

Definition at line 91 of file interpolate.hpp.

◆ crossfade_equal_power()

float sbl::dsp::crossfade_equal_power ( float  a,
float  b,
float  t 
)
inline

Equal-power crossfade between two values.

Maintains constant power across the fade (no dip at t=0.5). Uses sqrt approximation: a*sqrt(1-t) + b*sqrt(t).

Parameters
aValue at t=0 (dry)
bValue at t=1 (wet)
tBlend factor [0.0, 1.0]

Definition at line 67 of file interpolate.hpp.

◆ crossfade_i16()

constexpr int32_t sbl::dsp::crossfade_i16 ( int16_t  a,
int16_t  b,
uint16_t  t 
)
inlineconstexpr

Integer crossfade for 16-bit values.

Parameters
aValue at t=0
bValue at t=1
tBlend factor [0, 65535] (0 = all a, 65535 = all b)
Returns
Blended value

Definition at line 51 of file interpolate.hpp.

◆ deinterleave_to_float()

void sbl::dsp::deinterleave_to_float ( const int32_t *  interleaved,
float *  left,
float *  right,
uint16_t  frames 
)
inline

Definition at line 58 of file convert.hpp.

References SAMPLE_SCALE_INV_F.

◆ exp2_approx()

float sbl::dsp::exp2_approx ( float  x)
inline

Fast 2^x approximation via pitch tables. x in [-10.67, +10.58].

Definition at line 64 of file pitch.hpp.

References semitones_to_ratio().

Here is the call graph for this function:

◆ exp2_approx_safe()

float sbl::dsp::exp2_approx_safe ( float  x)
inline

Extended range 2^x.

Definition at line 69 of file pitch.hpp.

References semitones_to_ratio_safe().

Here is the call graph for this function:

◆ fast_exp2f()

float sbl::dsp::fast_exp2f ( float  x)
inline

Fast 2^x approximation for exponential modulation

Decomposes x into integer and fractional parts. The integer part is applied by shifting the IEEE 754 exponent field (exact). The fractional part uses a 3rd-order minimax polynomial (accurate to ~20 bits).

This is the "exponential converter" primitive — the analog equivalent of the circuit that makes 1V/oct work in a VCF or VCO.

Accuracy (vs std::exp2f): |x| <= 1 → max relative error < 0.02% |x| <= 4 → max relative error < 0.05% |x| > 16 → clamped (returns 0 for x < -16)

Parameters
xExponent (e.g., ±2.0 for ±2 octave modulation)
Returns
Approximation of 2^x

Definition at line 96 of file fast_math.hpp.

Referenced by sbl::signal::exp_mod().

Here is the caller graph for this function:

◆ fast_sinf()

float sbl::dsp::fast_sinf ( float  x)
inline

Fast sine approximation for x in [0, π/2]

Uses 5th-order Taylor series: x - x³/6 + x⁵/120

Accuracy: x = 0.0 → error = 0 x = 0.589 → error < 0.00016 (SVF max at 18 kHz / 48 kHz) x = π/2 → error ≈ 0.00045 (theoretical max in domain)

Parameters
xInput angle in radians, must be in [0, π/2]
Returns
Approximation of sin(x)

Definition at line 38 of file fast_math.hpp.

◆ fast_tan_pif()

float sbl::dsp::fast_tan_pif ( float  f)
inline

Fast tan(π·f) for normalized frequency f ∈ [0, 0.497]

[5,4] Padé approximant of tan(x) evaluated at x = π·f:

tan(x) ≈ x · (945 - 105x² + x⁴) / (945 - 420x² + 15x⁴)

Unlike a polynomial, the Padé rational function correctly models the pole at f = 0.5 (Nyquist). The denominator goes to zero at x = π/2, matching the true singularity of tan.

Accuracy vs true tan(π·f): f = 0.10 (4.8 kHz) → error < 0.001% f = 0.35 (16.8 kHz) → error < 0.3% f = 0.45 (21.6 kHz) → error < 2.4% f = 0.497 (23.9 kHz) → error < 0.1%

The previous 5th-order polynomial (from MI stmlib) diverged badly above f ≈ 0.35, giving 45% error at f = 0.45 — causing audible artifacts (secondary resonant peaks) in the ZDF SVF.

Cost: ~8 FMA + 1 VDIV ≈ 20–25 cycles on M7 FPU (vs ~5 for the old polynomial, vs ~50–100 for newlib tanf).

Parameters
fNormalized frequency (freq_hz / sample_rate), must be < 0.497
Returns
Approximation of tan(π·f)

Definition at line 68 of file fast_math.hpp.

Referenced by sbl::widgets::proc::Svf::process_modulated(), and sbl::widgets::proc::Svf::set_cutoff().

Here is the caller graph for this function:

◆ interleave_from_float()

void sbl::dsp::interleave_from_float ( const float *  left,
const float *  right,
int32_t *  interleaved,
uint16_t  frames 
)
inline

Definition at line 86 of file convert.hpp.

References SAMPLE_SCALE_F, and SBL_NAN_DETECTED.

Referenced by sbl::signal::Frame< MaxFrames >::end().

Here is the caller graph for this function:

◆ lut_curve_warp()

template<uint16_t Size>
uint16_t sbl::dsp::lut_curve_warp ( const uint16_t *  table,
uint16_t  phase,
uint16_t  curve 
)
inline

Definition at line 54 of file warp.hpp.

References sbl::dsp::lut::lookup_linear(), U16_MAX, and U16_MID.

Here is the call graph for this function:

◆ map_linear()

constexpr float sbl::dsp::map_linear ( float  t,
float  min,
float  max 
)
inlineconstexpr

Linear mapping: t → min + (max - min) * t.

Definition at line 37 of file param.hpp.

◆ map_quadratic()

constexpr float sbl::dsp::map_quadratic ( float  t,
float  min,
float  max 
)
inlineconstexpr

Quadratic mapping: t² curve. Good for frequency, cutoff, LFO rate. More resolution at low values, fast rise at high values.

Definition at line 43 of file param.hpp.

◆ map_scurve()

constexpr float sbl::dsp::map_scurve ( float  t,
float  min,
float  max 
)
inlineconstexpr

S-curve mapping via Hermite smooth step: t²(3 - 2t). Slow start, fast middle, slow finish. Good for crossfade morphs.

Definition at line 49 of file param.hpp.

◆ note_to_frequency()

float sbl::dsp::note_to_frequency ( float  midi_note)
inline

MIDI note to frequency in Hz. A4 = 440 Hz.

Definition at line 52 of file pitch.hpp.

References note_to_ratio().

Referenced by sbl::components::cv::VoctInput::frequency(), note_to_phase_increment(), and sbl::widgets::source::PolyBlepOsc::set_note().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ note_to_phase_increment()

uint32_t sbl::dsp::note_to_phase_increment ( float  midi_note,
float  sample_rate 
)
inline

MIDI note to phase increment for a given sample rate. phase_inc = freq / sample_rate * 2^32

Definition at line 58 of file pitch.hpp.

References note_to_frequency().

Referenced by sbl::components::cv::VoctInput::phase_increment(), sbl::widgets::source::ScanningOsc< TableSize, MaxTables >::set_note(), and sbl::widgets::source::WavetableOsc< TableSize >::set_note().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ note_to_ratio()

float sbl::dsp::note_to_ratio ( float  midi_note)
inline

MIDI note to frequency ratio relative to A4 (note 69). note_to_ratio(69) = 1.0, note_to_ratio(81) = 2.0.

Definition at line 47 of file pitch.hpp.

References semitones_to_ratio().

Referenced by note_to_frequency(), and sbl::components::cv::VoctInput::ratio().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ saturate_24()

constexpr int32_t sbl::dsp::saturate_24 ( int32_t  x)
inlineconstexpr

Clamp value to 24-bit audio range.

Definition at line 31 of file fixed.hpp.

References SAMPLE_MAX_24, and SAMPLE_MIN_24.

◆ semitones_to_ratio()

float sbl::dsp::semitones_to_ratio ( float  semitones)
inline
Note
All functions in sbl::dsp (pitch) are ISR-safe — bounded computation, no I/O. Convert semitones to frequency ratio using two-table multiplication. Input range: -128.0 to +127.0 semitones. 0 = unison (ratio 1.0). Cost: 1 float multiply + table lookups.

Definition at line 26 of file pitch.hpp.

References sbl::dsp::lut::pitch_ratio_high_256, and sbl::dsp::lut::pitch_ratio_low_256.

Referenced by exp2_approx(), note_to_ratio(), and semitones_to_ratio_safe().

Here is the caller graph for this function:

◆ semitones_to_ratio_safe()

float sbl::dsp::semitones_to_ratio_safe ( float  semitones)
inline

Extended range version — handles semitones outside [-128, 127]. Uses octave doubling/halving for extreme values.

Definition at line 38 of file pitch.hpp.

References semitones_to_ratio().

Referenced by exp2_approx_safe().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ smooth_step()

constexpr float sbl::dsp::smooth_step ( float  t)
inlineconstexpr

Hermite smooth step (3rd-order S-curve)

Maps [0, 1] → [0, 1] with zero derivative at endpoints. Useful for equal-power-like crossfade curves, smooth transitions, and perceptually linear parameter morphing.

Parameters
tInput [0.0, 1.0] (not clamped)
Returns
t² × (3 - 2t)

Definition at line 39 of file interpolate.hpp.

◆ soft_clip()

float sbl::dsp::soft_clip ( float  x)
inline

Bounded soft clipper — output in [-1, 1].

Pre-clamps to [-3, 3] then applies soft_limit. Since soft_limit(3) = 1.0 exactly, output is bounded to [-1, 1]. Gentle compression: soft_clip(1.0) ≈ 0.78, soft_clip(2.0) ≈ 0.98.

Definition at line 54 of file saturate.hpp.

References soft_limit().

Here is the call graph for this function:

◆ soft_clip_24()

int32_t sbl::dsp::soft_clip_24 ( int32_t  x)
inline

Soft saturation for 24-bit audio samples.

Normalizes to [-1, 1], applies soft_limit, scales back. Unity gain for very small signals, gentle 3rd-harmonic compression as level increases. Full-scale produces ~78% output — this is intentional musical compression, not transparent limiting.

For transparent hard limiting, use saturate_24() from fixed.hpp. For overdrive, pre-multiply by a gain factor before calling.

Definition at line 71 of file saturate.hpp.

References SAMPLE_MAX_24, and soft_limit().

Here is the call graph for this function:

◆ soft_limit()

float sbl::dsp::soft_limit ( float  x)
inline

Smooth saturation with unity gain at origin.

Uses rational approximation: x * (27 + x²) / (27 + 9x²). Monotonic, odd-symmetric, derivative = 1 at x=0. NOT bounded — approaches x/9 for large x. Use soft_clip() for bounded output.

Key values: soft_limit(1.0) ≈ 0.78, soft_limit(3.0) = 1.0

Definition at line 42 of file saturate.hpp.

Referenced by soft_clip(), and soft_clip_24().

Here is the caller graph for this function:

◆ to_float() [1/2]

void sbl::dsp::to_float ( const Sample in,
float *  out,
uint16_t  frames 
)
inline

Definition at line 41 of file convert.hpp.

References SAMPLE_SCALE_INV_F.

◆ to_float() [2/2]

float sbl::dsp::to_float ( Sample  s)
inline

Definition at line 31 of file convert.hpp.

References SAMPLE_SCALE_INV_F.

◆ to_sample() [1/2]

void sbl::dsp::to_sample ( const float *  in,
Sample out,
uint16_t  frames 
)
inline

Definition at line 47 of file convert.hpp.

References SAMPLE_SCALE_F.

◆ to_sample() [2/2]

Sample sbl::dsp::to_sample ( float  f)
inline

Definition at line 35 of file convert.hpp.

References SAMPLE_SCALE_F.

◆ u14_to_float()

constexpr float sbl::dsp::u14_to_float ( uint16_t  val)
inlineconstexpr

Normalize 14-bit MIDI (0-16383) to [0.0, 1.0] (pitch bend, NRPN)

Definition at line 30 of file param.hpp.

◆ u16_to_float()

constexpr float sbl::dsp::u16_to_float ( uint16_t  val)
inlineconstexpr

Normalize 16-bit unsigned (0-65535) to [0.0, 1.0].

Definition at line 25 of file param.hpp.

Variable Documentation

◆ FRAC16_MASK

constexpr uint16_t sbl::dsp::FRAC16_MASK = 0xffff
inlineconstexpr

Definition at line 24 of file fixed.hpp.

Referenced by sbl::dsp::lut::lookup_linear().

◆ Q16_ONE

constexpr uint32_t sbl::dsp::Q16_ONE = 65536u
inlineconstexpr

Definition at line 15 of file fixed.hpp.

Referenced by sbl::dsp::RationalWarp::warp().

◆ SAMPLE_MAX_24

constexpr int32_t sbl::dsp::SAMPLE_MAX_24 = 8388607
inlineconstexpr

Definition at line 27 of file fixed.hpp.

Referenced by saturate_24(), and soft_clip_24().

◆ SAMPLE_MIN_24

constexpr int32_t sbl::dsp::SAMPLE_MIN_24 = -8388607
inlineconstexpr

Definition at line 28 of file fixed.hpp.

Referenced by saturate_24().

◆ SAMPLE_SCALE_F

constexpr float sbl::dsp::SAMPLE_SCALE_F = 8388607.0f
inlineconstexpr

Definition at line 26 of file convert.hpp.

Referenced by interleave_from_float(), to_sample(), and to_sample().

◆ SAMPLE_SCALE_INV_F

constexpr float sbl::dsp::SAMPLE_SCALE_INV_F = 1.0f / 8388607.0f
inlineconstexpr

Definition at line 27 of file convert.hpp.

Referenced by deinterleave_to_float(), to_float(), and to_float().

◆ U16_MAX

constexpr uint16_t sbl::dsp::U16_MAX = 65535u
inlineconstexpr

Definition at line 18 of file fixed.hpp.

Referenced by lut_curve_warp(), sbl::dsp::lut::mix(), and sbl::dsp::RationalWarp::warp().

◆ U16_MID

constexpr uint16_t sbl::dsp::U16_MID = 32768u
inlineconstexpr

Definition at line 21 of file fixed.hpp.

Referenced by lut_curve_warp(), and sbl::dsp::RationalWarp::warp().