Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
tables.hpp File Reference
#include <pulp/signal/oversampling_fir.hpp>
#include <array>
#include <cstddef>
#include <cstdint>

Go to the source code of this file.

Namespaces

namespace  pulp
namespace  pulp::signal
namespace  pulp::signal::chardelay

Variables

constexpr double pulp::signal::chardelay::kMaxDelayMs = 2000.0
 Maximum left-channel base delay and stereo-offset bounds.
constexpr double pulp::signal::chardelay::kTimeOffsetMin = 0.5
constexpr double pulp::signal::chardelay::kTimeOffsetMax = 1.5
constexpr double pulp::signal::chardelay::kMaxAddressableDelayMs = kMaxDelayMs * kTimeOffsetMax
constexpr int pulp::signal::chardelay::kControlInterval = 32
 Coefficient recomputation and stochastic-walk stepping cadence, in samples.
constexpr double pulp::signal::chardelay::kParamGlideS = 0.005
 De-zipper glide for scalar params (feedback, crossfeed, duck, freeze, and the character table's per-sample outputs), in seconds.
constexpr double pulp::signal::chardelay::kUnsaturatedFeedbackMax = 0.98
 Feedback ceiling for the characters with NO in-loop saturator.
constexpr double pulp::signal::chardelay::kSaturatedFeedbackMax = 1.1
 Feedback ceiling for the saturating characters.
constexpr double pulp::signal::chardelay::kModRateMinHz = 0.05
 Generic modulation LFO: log rate map and maximum depth as a fraction of delay time.
constexpr double pulp::signal::chardelay::kModRateMaxHz = 10.0
constexpr double pulp::signal::chardelay::kModMaxDepth = 0.05
constexpr double pulp::signal::chardelay::kLoopToneHpMinHz = 20.0
 User-facing in-loop tone stage.
constexpr double pulp::signal::chardelay::kLoopToneHpMaxHz = 2000.0
constexpr double pulp::signal::chardelay::kLoopToneLpMinHz = 200.0
constexpr double pulp::signal::chardelay::kLoopToneLpMaxHz = 20000.0
constexpr double pulp::signal::chardelay::kLoopToneNyquistFraction = 0.45
 Keep the TPT prewarp strictly below Nyquist.
constexpr double pulp::signal::chardelay::kLoopToneResMin = 0.5
 Resonance range for both loop-tone filters.
constexpr double pulp::signal::chardelay::kLoopToneResMax = 2.0
constexpr double pulp::signal::chardelay::kStereoDecorr = 0.95
 Right-channel depth scaler for every shared-LFO modulation.
constexpr std::uint32_t pulp::signal::chardelay::kPrngSeed = 74207u
 PRNG seed.
constexpr double pulp::signal::chardelay::kTimeSlewCleanMs = 15.0
constexpr double pulp::signal::chardelay::kTimeSlewVintageMs = 50.0
constexpr double pulp::signal::chardelay::kTimeSlewTapeMs = 250.0
constexpr double pulp::signal::chardelay::kTimeSlewBbdMs = 80.0
constexpr double pulp::signal::chardelay::kTimeSlewDiffusionMs = 15.0
constexpr std::array< double, 3 > pulp::signal::chardelay::kCleanAxis = {0.0, 0.5, 1.0}
constexpr std::array< double, 3 > pulp::signal::chardelay::kCleanLoopLpHz = {20000.0, 12000.0, 6000.0}
constexpr std::array< double, 3 > pulp::signal::chardelay::kCleanLoopHpHz = {20.0, 20.0, 120.0}
constexpr double pulp::signal::chardelay::kLoopLpBypassHz = 20000.0
 A loop lowpass at or above this cutoff is BYPASSED rather than run.
constexpr std::array< double, 4 > pulp::signal::chardelay::kVintageAxis = {0.0, 0.33, 0.67, 1.0}
constexpr std::array< double, 4 > pulp::signal::chardelay::kVintageInternalRateHz
constexpr std::array< double, 4 > pulp::signal::chardelay::kVintageBits = {14.0, 12.0, 12.0, 10.0}
constexpr double pulp::signal::chardelay::kVintageAntiAliasFraction = 0.45
 Anti-alias / reconstruction cutoff as a fraction of the internal rate.
constexpr double pulp::signal::chardelay::kVintageEmphasisHz = 3183.0
 3183 Hz is the 50 µs time constant — the published CD/FM-era emphasis standard (IEC 60908), not a tuned value.
constexpr double pulp::signal::chardelay::kVintageEmphasisDb = 9.0
constexpr std::array< double, 4 > pulp::signal::chardelay::kTapeAxis = {0.0, 0.33, 0.67, 1.0}
constexpr std::array< double, 4 > pulp::signal::chardelay::kTapeDrive = {1.5, 2.5, 4.0, 6.0}
constexpr std::array< double, 4 > pulp::signal::chardelay::kTapeBias = {0.0, 0.10, 0.20, 0.30}
constexpr std::array< double, 4 > pulp::signal::chardelay::kTapeWowDepthMs = {0.0, 0.15, 0.5, 1.2}
constexpr std::array< double, 4 > pulp::signal::chardelay::kTapeFlutterDepthMs = {0.0, 0.05, 0.15, 0.4}
constexpr std::array< double, 4 > pulp::signal::chardelay::kTapeLossLpHz = {12000.0, 9000.0, 6000.0, 3500.0}
constexpr std::array< double, 4 > pulp::signal::chardelay::kTapeBumpDb = {1.5, 2.0, 3.0, 4.0}
constexpr std::array< double, 4 > pulp::signal::chardelay::kTapePhysicalFeedbackCompensation
 Physical-loop compensation at each age knot.
constexpr double pulp::signal::chardelay::kTapeEmphasisDb = 3.0
 Record/playback EQ bracketing the saturator: boost HF into saturation, cut it after, so the saturator works the highs harder than the lows.
constexpr double pulp::signal::chardelay::kTapeEmphasisHz = 1600.0
constexpr double pulp::signal::chardelay::kTapeBumpHz = 60.0
 Loss stand-in head bump (the physical tier replaces this with a speed-dependent center; see kHeadBumpIps/kHeadBumpHz).
constexpr double pulp::signal::chardelay::kTapeBumpQ = 1.5
constexpr double pulp::signal::chardelay::kTapeDcBlockHz = 15.0
 In-loop DC blocker.
constexpr double pulp::signal::chardelay::kWowRateHz = 1.0
 Wow: periodic + stochastic.
constexpr double pulp::signal::chardelay::kWowOuTheta = 1.5
constexpr double pulp::signal::chardelay::kWowOuSigma = 0.6
constexpr double pulp::signal::chardelay::kWowOuNoiseLpHz = 10.0
constexpr double pulp::signal::chardelay::kFlutterBaseHz = 8.0
 Flutter: published band 5–100 Hz.
constexpr std::array< double, 3 > pulp::signal::chardelay::kFlutterAmplitudes = {1.0, 0.5, 0.25}
constexpr std::array< double, 3 > pulp::signal::chardelay::kFlutterPhases = {0.0, 0.33, 0.71}
constexpr double pulp::signal::chardelay::kFlutterPhaseRight = 0.41
 Right-channel flutter phase offset, in cycles.
constexpr std::array< double, 3 > pulp::signal::chardelay::kBbdAxis = {0.0, 0.5, 1.0}
constexpr std::array< double, 3 > pulp::signal::chardelay::kBbdStages = {4096.0, 2048.0, 1024.0}
 PUBLISHED chip stage counts (Panasonic MN3005 / MN3008 / MN3007 datasheets), not design parameters: they are what sets each device's delay-per-clock and therefore its bandwidth at a given time.
constexpr std::array< double, 3 > pulp::signal::chardelay::kBbdDrive = {0.10, 0.30, 0.50}
constexpr std::array< double, 3 > pulp::signal::chardelay::kBbdJitterAmount = {0.0, 0.3, 0.6}
constexpr std::array< double, 3 > pulp::signal::chardelay::kBbdFlutterDepth = {0.0, 0.005, 0.015}
constexpr std::size_t pulp::signal::chardelay::kBbdMaxStages = 4096
 Largest stage count any table knot may request; sizes the bucket buffer.
constexpr int pulp::signal::chardelay::kBbdOversample = 16
 Internal oversampling of the clocked core.
constexpr double pulp::signal::chardelay::kBbdBandwidthDivisor = 3.0
 Bandwidth law: the usable passband must sit well below the clock's Nyquist (the published aliasing constraint in both BBD papers).
constexpr double pulp::signal::chardelay::kBbdBandwidthMinHz = 300.0
constexpr double pulp::signal::chardelay::kBbdBandwidthMaxHz = 10000.0
constexpr double pulp::signal::chardelay::kBbdFilterCutoffScale = 2.1
 The clock law names the complete wet path's audible -3 dB edge.
constexpr double pulp::signal::chardelay::kBbdCompanderTauMs = 10.0
 Compander: hardware τ is set by an external capacitor, so real units vary.
constexpr double pulp::signal::chardelay::kBbdCompanderFloor = 0.01
constexpr double pulp::signal::chardelay::kBbdCompanderDriveScale = 0.3
 The compander holds loop level near the rail, so the waveshaper's drive is backed off when it runs behind one.
constexpr double pulp::signal::chardelay::kBbdDriveGainSpan = 9.0
 Asymmetric soft clip: gain map and DC offset for even-harmonic content.
constexpr double pulp::signal::chardelay::kBbdShape = 0.25
constexpr double pulp::signal::chardelay::kBbdJitterMax = 5e-4
 Clock jitter, as a fraction of the clock period. [1e-4–2e-3].
constexpr double pulp::signal::chardelay::kBbdJitterSmoothness = 0.5
constexpr double pulp::signal::chardelay::kBbdFlutterRateBaseHz = 0.3
 BBD flutter rate map, Hz.
constexpr double pulp::signal::chardelay::kBbdFlutterRateSpanHz = 1.2
constexpr std::array< double, 4 > pulp::signal::chardelay::kDiffusionStageMs
constexpr std::array< double, 4 > pulp::signal::chardelay::kDiffusionStageGain = {0.75, 0.75, 0.625, 0.625}
constexpr std::array< double, 3 > pulp::signal::chardelay::kDiffusionAxis = {0.0, 0.5, 1.0}
constexpr std::array< double, 3 > pulp::signal::chardelay::kDiffusionSizeScale = {0.5, 1.0, 1.7}
constexpr std::array< double, 3 > pulp::signal::chardelay::kDiffusionGainScale = {0.7, 1.0, 1.12}
constexpr double pulp::signal::chardelay::kDiffusionGainMax = 0.85
 Stability / metallicity guard.
constexpr double pulp::signal::chardelay::kDiffusionModDepthSamples = 2.0
 Anti-metallic modulation of stages 1 and 3 (Dattorro modulates his diffusers).
constexpr std::array< double, 2 > pulp::signal::chardelay::kDiffusionModRatesHz = {0.40, 0.53}
constexpr double pulp::signal::chardelay::kDiffusionLoopHpHz = 20.0
 Diffusion loop filters. [LP is a design parameter].
constexpr double pulp::signal::chardelay::kDiffusionLoopLpHz = 9000.0
constexpr std::array< double, 3 > pulp::signal::chardelay::kDiffusionTankAxis = {0.0, 0.5, 1.0}
constexpr std::array< double, 2 > pulp::signal::chardelay::kDiffusionTankDelayAMs = {30.51, 44.79}
 Branch delays in ms, mutually prime-ish so their comb nulls never align.
constexpr std::array< double, 2 > pulp::signal::chardelay::kDiffusionTankDelayBMs = {37.13, 53.27}
constexpr std::array< double, 2 > pulp::signal::chardelay::kDiffusionTankApAMs = {22.58, 60.48}
 The two decay-diffuser allpasses per branch. [design parameters].
constexpr std::array< double, 2 > pulp::signal::chardelay::kDiffusionTankApBMs = {30.24, 89.24}
constexpr double pulp::signal::chardelay::kDiffusionTankApGain1 = 0.70
constexpr double pulp::signal::chardelay::kDiffusionTankApGain2 = 0.50
constexpr std::array< double, 3 > pulp::signal::chardelay::kDiffusionTankSizeScale = {0.6, 1.0, 1.6}
 Tank size scaler and recirculation decay by character amount.
constexpr std::array< double, 3 > pulp::signal::chardelay::kDiffusionTankDecay = {0.0, 0.62, 0.80}
constexpr std::array< double, 3 > pulp::signal::chardelay::kDiffusionTankMix = {0.0, 0.55, 0.85}
 How much of the character's output is the tank rather than the bare diffuser.
constexpr std::array< double, 3 > pulp::signal::chardelay::kDiffusionTankDampHz = {12000.0, 7000.0, 4200.0}
 In-tank damping.
constexpr std::array< double, 3 > pulp::signal::chardelay::kDiffusionTankModDepth = {0.0, 14.0, 42.0}
 Tank modulation — this is what makes the cloud granular rather than static.
constexpr std::array< double, 2 > pulp::signal::chardelay::kDiffusionTankModRatesHz = {0.83, 1.27}
constexpr std::array< double, 2 > pulp::signal::chardelay::kDiffusionTankTapFraction = {0.37, 0.71}
 Extra scattered taps read at their own modulated offsets, as a fraction of the branch delay.
constexpr double pulp::signal::chardelay::kDiffusionTankLowGuardHz = 90.0
 In-tank low cut.
constexpr double pulp::signal::chardelay::kDiffusionTankDelaySlewMs = 5.0
 Live character automation moves tank taps toward their new positions over a short continuous glide instead of changing fractional reads at control-rate boundaries.
constexpr int pulp::signal::chardelay::kReverseFadeSamples = 96
 Raised-cosine splice fade at each end of a reversed segment, in samples.
constexpr double pulp::signal::chardelay::kReverseLineMs = 30.0
 Delay the CLOCK-DOMAIN characters' own line runs at while reverse is engaged, in milliseconds.
constexpr double pulp::signal::chardelay::kDuckAttackS = 0.005
constexpr double pulp::signal::chardelay::kDuckReleaseS = 0.250
constexpr double pulp::signal::chardelay::kDuckThreshold = 0.1
constexpr double pulp::signal::chardelay::kJaSaturationMagnetization = 3.5e5
 PUBLISHED γ-Fe2O3 material constants (Jiles, Thoelke & Devine 1992, reproduced in Chowdhury 2019).
constexpr double pulp::signal::chardelay::kJaAnhystereticShape = 2.2e4
constexpr double pulp::signal::chardelay::kJaPinning = 2.7e4
constexpr double pulp::signal::chardelay::kJaReversibility = 0.2
constexpr double pulp::signal::chardelay::kJaInterdomainCoupling = 1.6e-3
constexpr int pulp::signal::chardelay::kJaMaxIterations = 8
 Newton-Raphson budget.
constexpr double pulp::signal::chardelay::kJaConvergenceThreshold = 6e-8
constexpr double pulp::signal::chardelay::kJaLangevinClamp = 30.0
 Langevin argument clamp — keeps coth() and its derivative in the range where the rational approximation is accurate and the solver well-scaled.
constexpr double pulp::signal::chardelay::kJaSilenceThreshold = 1e-7
 Below this |H| and |dH/dt|, magnetization is snapped to 0 so a silent loop cannot hold a frozen DC magnetization.
constexpr std::size_t pulp::signal::chardelay::kHysteresisHalfBandTaps = kHouseHalfBandTaps
 Hysteresis oversampling factor and half-band design.
constexpr double pulp::signal::chardelay::kHysteresisHalfBandStopbandDb = kHouseHalfBandStopbandDb
constexpr double pulp::signal::chardelay::kJaMakeupToleranceDb = 1.0
 Makeup-gain tolerance around unity small-signal gain, in dB.
constexpr std::size_t pulp::signal::chardelay::kLossFirOrder48k = 96
 Wallace playback loss (Wallace 1951; physical ranges from Bertram 1994) is split across two realizations — see tape_loss.hpp for why.
constexpr int pulp::signal::chardelay::kLossIirFitPoints = 64
 The smooth spacing × thickness tilt goes to a fitted IIR cascade: how many log-spaced points the least-squares fit is evaluated at, and how many simplex iterations it gets.
constexpr std::size_t pulp::signal::chardelay::kSpacingPoleSections = 3
 Sections in each fitted cascade.
constexpr std::size_t pulp::signal::chardelay::kSpacingShelfSections = 8
constexpr std::size_t pulp::signal::chardelay::kThicknessPoleSections = 1
constexpr std::size_t pulp::signal::chardelay::kThicknessShelfSections = 2
constexpr std::size_t pulp::signal::chardelay::kLossPoleSections
constexpr std::size_t pulp::signal::chardelay::kLossShelfSections
constexpr std::size_t pulp::signal::chardelay::kLossSearchDimension
 Search dimension of ONE shape fit (the larger of the two).
constexpr std::array< double, kSpacingPoleSections > pulp::signal::chardelay::kSpacingShapePoleX
 THE FITTED SHAPES, as shipped.
constexpr std::array< double, kSpacingShelfSections > pulp::signal::chardelay::kSpacingShapeShelfX
constexpr std::array< double, kSpacingShelfSections > pulp::signal::chardelay::kSpacingShapeShelfDb
constexpr std::array< double, kThicknessPoleSections > pulp::signal::chardelay::kThicknessShapePoleX
constexpr std::array< double, kThicknessShelfSections > pulp::signal::chardelay::kThicknessShapeShelfX
constexpr std::array< double, kThicknessShelfSections > pulp::signal::chardelay::kThicknessShapeShelfDb
constexpr double pulp::signal::chardelay::kLossShapeMinX = 1e-3
 Normalized-frequency range each shape is fitted over, and how many log-spaced points.
constexpr double pulp::signal::chardelay::kLossShapeMaxX = 4.0
constexpr int pulp::signal::chardelay::kLossIirFitIterations = 4000
 Simplex iterations per start, restarts per start, and how many starts.
constexpr int pulp::signal::chardelay::kLossIirFitRestarts = 3
constexpr int pulp::signal::chardelay::kLossIirFitStarts = 16
constexpr double pulp::signal::chardelay::kLossShelfMinDb = -40.0
 Deepest cut any one shelf may ask for.
constexpr double pulp::signal::chardelay::kLossBankCrossfadeS = 0.030
 NOTE: there are no age knots and no interpolation along the age axis.
constexpr double pulp::signal::chardelay::kTapeCoatingThicknessM = 12e-6
 Fixed tape geometry, in metres.
constexpr double pulp::signal::chardelay::kTapeHeadGapM = 3e-6
constexpr std::array< double, 5 > pulp::signal::chardelay::kTapeSpeedsIps = {1.875, 3.75, 7.5, 15.0, 30.0}
 The IEC/NAB standard tape-speed set, in inches per second (published).
constexpr std::array< double, 5 > pulp::signal::chardelay::kHeadBumpIps = {1.875, 3.75, 7.5, 15.0, 30.0}
 Head-bump center against speed.
constexpr std::array< double, 5 > pulp::signal::chardelay::kHeadBumpHz = {35.0, 45.0, 60.0, 80.0, 105.0}
constexpr std::array< double, 3 > pulp::signal::chardelay::kAgeAxis = {0.0, 0.5, 1.0}
 Age macro.
constexpr std::array< double, 3 > pulp::signal::chardelay::kAgeSpacingUm = {5.0, 12.0, 25.0}
constexpr std::array< double, 3 > pulp::signal::chardelay::kAgeHissDbfs = {-120.0, -78.0, -60.0}
constexpr std::array< double, 3 > pulp::signal::chardelay::kAgeChewDepth = {0.0, 0.2, 0.6}
constexpr std::array< double, 3 > pulp::signal::chardelay::kAgeDegrade = {0.0, 0.2, 0.5}
constexpr double pulp::signal::chardelay::kHissLpHz = 4000.0
 Hiss: white noise through a 1-pole lowpass, injected AFTER the delay line so it accumulates per repeat the way real tape self-noise does.
constexpr double pulp::signal::chardelay::kChewCleanScaleS = 1.5
 Chew — an intermittent dropout modeled as a two-state machine.
constexpr double pulp::signal::chardelay::kChewDegradedScaleS = 0.4
constexpr double pulp::signal::chardelay::kChewVariance = 1.5
constexpr double pulp::signal::chardelay::kChewTransitionS = 0.008
constexpr double pulp::signal::chardelay::kChewPower = 2.0
constexpr double pulp::signal::chardelay::kChewLpHz = 3000.0
constexpr double pulp::signal::chardelay::kDegradeMinLpHz = 500.0
 Degrade — continuous wear.
constexpr double pulp::signal::chardelay::kDegradeGainDipDb = -1.5
constexpr int pulp::signal::chardelay::kDegradeUpdateSamples = 1024