47 const auto capacity =
static_cast<std::size_t
>(
49 line_.prepare(capacity);
57 reconstruction_.reset();
58 pre_emphasis_.reset();
65 void set_seed(std::uint32_t seed)
noexcept { rng_.reseed(seed); }
70 void update(
double character_amount)
noexcept {
76 quantization_step_ = std::pow(2.0, -(bits - 1.0));
79 anti_alias_.set_cutoff(band_edge, sample_rate_);
80 reconstruction_.set_cutoff(band_edge, sample_rate_);
90 double process(
double x,
double delay_seconds)
noexcept {
91 const double band_limited = pre_emphasis_.process(anti_alias_.process(x));
96 phase_ += internal_rate_ / sample_rate_;
97 while (phase_ >= 1.0) {
99 line_.push(quantize(band_limited));
117 held_ = line_.read(std::max(1.0, delay_seconds * internal_rate_ - phase_));
120 return reconstruction_.process(de_emphasis_.process(held_));
129 double quantize(
double x)
noexcept {
130 const double dither =
132 const double q = std::round((x + dither) / quantization_step_) * quantization_step_;
133 return std::clamp(q, -1.0, 1.0 - quantization_step_);
137 Butterworth6Lowpass anti_alias_;
138 Butterworth6Lowpass reconstruction_;
139 FirstOrderShelf pre_emphasis_;
140 FirstOrderShelf de_emphasis_;
143 double sample_rate_ = 48000.0;
144 double internal_rate_ = 32000.0;
145 double quantization_step_ = 1.0 / 8192.0;
Xorshift32 (Marsaglia, "Xorshift RNGs", J.
Definition rng.hpp:33
Definition vintage.hpp:40
double process(double x, double delay_seconds) noexcept
Definition vintage.hpp:90
void update(double character_amount) noexcept
Control-rate update: pick the "range switch" position (internal rate and word length) for this charac...
Definition vintage.hpp:70
void prepare(double fs)
Definition vintage.hpp:42
double internal_rate_hz() const noexcept
Definition vintage.hpp:87
double band_edge_hz() const noexcept
Definition vintage.hpp:88
void reset() noexcept
Definition vintage.hpp:54
void set_seed(std::uint32_t seed) noexcept
Definition vintage.hpp:65
double uniform() noexcept
Uniform in [0, 1].
Definition primitives.hpp:87
Deterministic TPDF dither and bounded error-feedback quantization.
constexpr double kVintageEmphasisDb
Definition tables.hpp:135
constexpr double kVintageEmphasisHz
3183 Hz is the 50 µs time constant — the published CD/FM-era emphasis standard (IEC 60908),...
Definition tables.hpp:134
constexpr std::array< double, 4 > kVintageInternalRateHz
Definition tables.hpp:124
constexpr std::uint32_t kPrngSeed
PRNG seed.
Definition tables.hpp:92
double interpolate_knots(const std::array< double, N > &axis, const std::array< double, N > &values, double c) noexcept
Definition primitives.hpp:125
constexpr double kVintageAntiAliasFraction
Anti-alias / reconstruction cutoff as a fraction of the internal rate.
Definition tables.hpp:129
constexpr std::array< double, 4 > kVintageAxis
Definition tables.hpp:123
constexpr std::array< double, 4 > kVintageBits
Definition tables.hpp:126
constexpr double kMaxAddressableDelayMs
Definition tables.hpp:35
FractionalDelayLineT< float > FractionalDelayLine
Definition fractional_delay.hpp:610
constexpr SampleType tpdf_centered_sum(SampleType first, SampleType second) noexcept
Definition dither.hpp:37