31template <
typename SampleType>
36template <
typename SampleType>
45 constexpr void reset() noexcept {
63template <
typename SampleType>
inline SampleType
quantization_step(SampleType bits)
noexcept {
64 if (!std::isfinite(bits))
66 return std::exp2(-(std::max(bits, SampleType{1}) - SampleType{1}));
75template <
typename SampleType>
76inline DitheredQuantizationResultT<SampleType>
79 SampleType first_uniform = SampleType{},
80 SampleType second_uniform = SampleType{})
noexcept {
81 DitheredQuantizationResultT<SampleType> result{};
82 if (!(std::isfinite(input) && std::isfinite(step) && step > SampleType{})) {
84 result.recovered =
true;
98 result.shaped_input = input +
feedback + result.dither;
99 const SampleType scaled = result.shaped_input / step;
100 if (!std::isfinite(result.shaped_input) || !std::isfinite(scaled) ||
101 std::abs(scaled) >
static_cast<SampleType
>(std::numeric_limits<std::int64_t>::max() / 2)) {
103 result.recovered =
true;
107 result.output = std::round(scaled) * step;
108 if (!std::isfinite(result.output)) {
111 result.recovered =
true;
118 result.quantization_error = result.output - input -
feedback;
119 const SampleType error_limit = SampleType{4} * step;
120 const SampleType
bounded = std::clamp(result.quantization_error, -error_limit, error_limit);
136 if (!std::isfinite(
bits)) {
137 bits_ = SampleType{24};
141 const SampleType sanitized = std::clamp(
bits, SampleType{1}, SampleType{24});
142 if (sanitized != bits_) {
151 std::clamp(state_.error_1, -error_limit, error_limit));
153 std::clamp(state_.error_2, -error_limit, error_limit));
158 if (mode != dither_mode_) state_.reset();
162 if (order != shaping_) state_.reset();
174 dither_mode_ = other.dither_mode_;
175 shaping_ = other.shaping_;
184 SampleType
process(SampleType input)
noexcept {
185 if (bits_ >= SampleType{24})
190 first = rng_.template next_unit<SampleType>();
191 second = rng_.template next_unit<SampleType>();
198 void process(SampleType* samples,
int count)
noexcept {
199 if (samples ==
nullptr || count <= 0)
201 for (
int i = 0;
i < count; ++
i)
205 SampleType
bits() const noexcept {
220 std::uint32_t
seed() const noexcept {
228 SampleType bits_{24};
231 NoiseShaperStateT<SampleType> state_{};
Stateful deterministic wrapper for per-sample and block processing.
Definition dither.hpp:131
float bits() const noexcept
Definition dither.hpp:205
void set_noise_shaping(NoiseShapingOrder order) noexcept
Definition dither.hpp:161
std::uint32_t seed() const noexcept
Definition dither.hpp:220
SampleType process(SampleType input) noexcept
Definition dither.hpp:184
void reset() noexcept
Definition dither.hpp:179
DitherMode dither_mode() const noexcept
Definition dither.hpp:208
void set_seed(std::uint32_t seed) noexcept
Definition dither.hpp:165
static constexpr int latency_samples() noexcept
Definition dither.hpp:223
void sync_configuration_from(const DitherQuantizerT &other) noexcept
Copy policy and reset seed without copying another instance's live error memory or random-stream posi...
Definition dither.hpp:172
static constexpr std::uint32_t default_seed
Definition dither.hpp:133
void set_bits(SampleType bits) noexcept
Definition dither.hpp:135
void process(SampleType *samples, int count) noexcept
Definition dither.hpp:198
void set_dither_mode(DitherMode mode) noexcept
Definition dither.hpp:157
std::uint32_t rng_state() const noexcept
Definition dither.hpp:217
NoiseShapingOrder noise_shaping() const noexcept
Definition dither.hpp:211
const NoiseShaperStateT< SampleType > & state() const noexcept
Definition dither.hpp:214
Definition additive_bank.hpp:218
@ feedback
Definition comb_filter.hpp:18
NoiseShapingOrder
Definition dither.hpp:21
@ none
Definition dither.hpp:22
@ first
Definition dither.hpp:23
@ second
Definition dither.hpp:24
DitheredQuantizationResultT< SampleType > quantize_with_error_feedback(SampleType input, SampleType step, DitherMode dither_mode, NoiseShapingOrder shaping, NoiseShaperStateT< SampleType > &state, SampleType first_uniform=SampleType{}, SampleType second_uniform=SampleType{}) noexcept
One allocation-free error-feedback transition.
Definition dither.hpp:77
DitherQuantizerT< float > DitherQuantizer
Definition dither.hpp:236
SampleType quantization_step(SampleType bits) noexcept
Mid-tread quantization step for a continuous bit-depth control.
Definition dither.hpp:63
@ bounded
Definition fm_operator_engine.hpp:35
DitherQuantizerT< double > DitherQuantizer64
Definition dither.hpp:237
T snap_to_zero(T x)
Returns 0 if |x| < snap_threshold, else x.
Definition denormal.hpp:45
@ u
Definition formant_filter_bank.hpp:20
@ i
Definition formant_filter_bank.hpp:20
DitherMode
Definition dither.hpp:16
@ tpdf
Definition dither.hpp:18
@ none
Definition dither.hpp:17
constexpr SampleType tpdf_difference(SampleType first, SampleType second) noexcept
Converts two independent uniform draws in [0, 1) to unit-peak TPDF noise.
Definition dither.hpp:32
constexpr SampleType tpdf_centered_sum(SampleType first, SampleType second) noexcept
Definition dither.hpp:37
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
Deterministic randomness for modulation: a counter-free PRNG, a Gaussian draw, a stateless purpose-ke...
Public intermediate returned by the pure quantizer transition.
Definition dither.hpp:54
SampleType shaped_input
Definition dither.hpp:56
bool recovered
Definition dither.hpp:59
SampleType quantization_error
Definition dither.hpp:58
SampleType dither
Definition dither.hpp:57
SampleType output
Definition dither.hpp:55
SampleType error_2
Definition dither.hpp:43
constexpr void reset() noexcept
Definition dither.hpp:45
SampleType error_1
Definition dither.hpp:42