123 configure_kind_filters();
128 configure_kind_filters();
141 return static_cast<int>(factor_);
152 const int stages = stage_count();
153 for (
int stage = 0; stage < stages; ++stage) {
154 exact +=
static_cast<double>(fir_stages_[stage].taps() - 1u) /
155 static_cast<double>(1u << (stage + 1));
157 return {
static_cast<int>(
exact),
exact,
true};
174 const int stages = stage_count();
175 for (
int stage = 0; stage < stages; ++stage) {
176 const double rate =
static_cast<double>(1u << (stage + 1));
177 const double f = frequency / rate;
182 const auto&
design = iir_designs_[
static_cast<std::size_t
>(stage)];
189 biquad_up_stages_[
static_cast<std::size_t
>(stage)].coefficients(),
190 2.0 * std::numbers::pi * f) /
210 constexpr std::array<std::size_t, kMaxStages> kStandardCounts = {12, 4, 3, 2};
211 constexpr std::array<std::size_t, kMaxStages> kPristineCounts = {16, 6, 4, 3};
212 constexpr double base_edge = 0.2425;
213 if (stage < 0 || stage >=
static_cast<int>(kMaxStages))
215 const auto index =
static_cast<std::size_t
>(stage);
216 const double edge = base_edge /
static_cast<double>(1u << index);
227 double worst = -1e300;
228 for (
int stage = 0; stage < static_cast<int>(kMaxStages); ++stage)
239 template <
typename Callback> SampleType
process(SampleType input, Callback&& callback) {
241 process_chunk(&input, &output, 1, callback);
251 SampleType
process(SampleType input,
const std::function<SampleType(SampleType)>& callback) {
253 process_chunk(&input, &output, 1, callback);
259 template <
typename Callback>
260 void process_block(
const SampleType* input, SampleType* output, std::size_t num_samples,
261 Callback&& callback) {
262 const std::size_t chunk = kScratchSamples /
static_cast<std::size_t
>(
factor_value());
263 for (std::size_t offset = 0; offset < num_samples; offset += chunk) {
264 const std::size_t count = std::min(chunk, num_samples - offset);
265 process_chunk(input + offset, output + offset, count, callback);
270 for (
auto& stage : biquad_up_stages_)
272 for (
auto& stage : biquad_down_stages_)
274 for (
auto& stage : iir_stages_)
276 for (
auto& stage : fir_stages_)
281 static constexpr std::size_t kMaxStages = 4;
283 static constexpr std::size_t kScratchSamples = 512;
287 SampleType sample_rate_ = SampleType{44100.0f};
290 std::array<SampleType, kScratchSamples> scratch_a_{};
291 std::array<SampleType, kScratchSamples> scratch_b_{};
294 return static_cast<int>(
factor);
297 int stage_count() const noexcept {
307 template <
typename Callback>
308 void process_chunk(
const SampleType* input, SampleType* output, std::size_t count,
309 Callback& callback) {
311 for (std::size_t
i = 0;
i <
count; ++
i)
312 output[
i] = process_biquad_sample(input[
i], callback);
315 const int stages = stage_count();
316 SampleType* buffers[2] = {scratch_a_.data(), scratch_b_.data()};
317 const SampleType* source = input;
320 for (
int stage = 0; stage < stages; ++stage) {
321 upsample_stage(stage, source, buffers[next], n);
322 source = buffers[next];
326 SampleType* work = buffers[next ^ 1];
327 for (std::size_t
i = 0;
i <
n; ++
i)
328 work[
i] = callback(work[
i]);
329 for (
int stage = stages; stage-- > 0;) {
331 SampleType* destination = stage == 0 ? output : buffers[next];
332 downsample_stage(stage, work, destination, n);
338 void upsample_stage(
int stage,
const SampleType* input, SampleType* output, std::size_t n) {
339 const auto s =
static_cast<std::size_t
>(stage);
341 iir_stages_[
s].upsample(input, output, n);
344 fir_stages_[
s].upsample(input, output, n);
347 void downsample_stage(
int stage,
const SampleType* input, SampleType* output, std::size_t n) {
348 const auto s =
static_cast<std::size_t
>(stage);
350 iir_stages_[
s].downsample(input, output, n);
353 fir_stages_[
s].downsample(input, output, n);
361 template <
typename Callback>
362 SampleType process_biquad_sample(SampleType input, Callback& callback) {
363 constexpr auto kMax =
static_cast<std::size_t
>(
Factor::x16);
364 std::array<SampleType, kMax> values;
365 std::array<SampleType, kMax> expanded;
367 std::size_t
count = 1;
368 const int stages = stage_count();
369 for (
int stage = 0; stage < stages; ++stage) {
370 auto&
up = biquad_up_stages_[
static_cast<std::size_t
>(stage)];
371 for (std::size_t
i = 0;
i <
count; ++
i) {
372 expanded[2 *
i] =
up.process(SampleType{2} * values[
i]);
373 expanded[2 *
i + 1] =
up.process(SampleType{0});
376 std::copy_n(expanded.begin(), count, values.begin());
378 for (std::size_t
i = 0;
i <
count; ++
i)
379 values[
i] = callback(values[
i]);
380 for (
int stage = stages; stage-- > 0;) {
381 auto&
down = biquad_down_stages_[
static_cast<std::size_t
>(stage)];
383 for (std::size_t
i = 0;
i <
count; ++
i) {
384 values[
i] =
down.process(values[2 *
i]);
385 static_cast<void>(
down.process(values[2 *
i + 1]));
391 void configure_kind_filters() {
393 configure_linear_phase_filters();
395 configure_polyphase_filters();
399 std::array<BiquadT<SampleType>, kMaxStages> biquad_up_stages_;
400 std::array<BiquadT<SampleType>, kMaxStages> biquad_down_stages_;
402 void configure_filters() {
409 const SampleType base_cutoff = sample_rate_ * SampleType{0.4f};
410 for (std::size_t stage = 0; stage < kMaxStages; ++stage) {
411 const SampleType stage_rate = sample_rate_ *
static_cast<SampleType
>(1u << (stage + 1));
412 const SampleType stage_cutoff = base_cutoff *
static_cast<SampleType
>(1u << stage);
414 stage_cutoff, SampleType{0.707f}, stage_rate);
416 stage_cutoff, SampleType{0.707f},
419 configure_kind_filters();
422 void configure_linear_phase_filters() {
432 fir_stages_[1].configure(0.225, 140.0, 69u);
433 fir_stages_[2].configure(0.1125, 140.0, 57u);
434 fir_stages_[3].configure(0.05625, 140.0, 49u);
436 fir_stages_[1].configure(0.20, 96.0, 49u);
437 fir_stages_[2].configure(0.10, 96.0, 33u);
438 fir_stages_[3].configure(0.05, 96.0, 33u);
443 std::array<HalfBandIirDesign, kMaxStages> iir_designs_{};
444 std::array<HalfBandIirStageT<SampleType>, kMaxStages> iir_stages_;
446 void configure_polyphase_filters() {
447 for (std::size_t stage = 0; stage < kMaxStages; ++stage) {
449 iir_stages_[stage].configure(iir_designs_[stage]);
454 std::array<detail::LinearPhaseOversamplingBlockStage2x<SampleType>, kMaxStages> fir_stages_;
@ lowpass
Definition biquad.hpp:58
Definition oversampling.hpp:78
OversamplerT()
Definition oversampling.hpp:100
static double polyphase_stopband_db(Quality quality) noexcept
The polyphase lane's stopband floor at quality, in dB (negative): the worst equiripple level over eve...
Definition oversampling.hpp:226
void set_kind(Kind kind)
Definition oversampling.hpp:121
void set_sample_rate(SampleType sr)
Definition oversampling.hpp:116
int latency_samples() const noexcept
Definition oversampling.hpp:160
void reset()
Definition oversampling.hpp:269
Quality quality() const
Definition oversampling.hpp:134
int factor_value() const
Definition oversampling.hpp:140
SampleType process(SampleType input, Callback &&callback)
Definition oversampling.hpp:239
void set_factor(Factor f)
RT contract: set_factor(), set_sample_rate(), set_kind(), and reset() are setup/control operations th...
Definition oversampling.hpp:111
SampleType process(SampleType input, const std::function< SampleType(SampleType)> &callback)
Definition oversampling.hpp:251
void set_quality(Quality quality)
Definition oversampling.hpp:126
Latency latency() const noexcept
Linear-phase modes expose a constant delay suitable for host compensation.
Definition oversampling.hpp:148
void process_block(const SampleType *input, SampleType *output, std::size_t num_samples, Callback &&callback)
Definition oversampling.hpp:260
Kind kind() const
Definition oversampling.hpp:131
Quality
Definition oversampling.hpp:89
@ pristine
FIR: 140 dB, flat to 0.45 Fs. IIR: 153.2 dB, flat to 0.485 Fs.
Definition oversampling.hpp:91
@ standard
FIR: 96 dB, flat to 0.40 Fs. IIR: 114.6 dB, flat to 0.485 Fs.
Definition oversampling.hpp:90
double group_delay_samples(double frequency) const noexcept
Group delay of the round trip (upsample, identity callback, downsample) in base-rate samples at frequ...
Definition oversampling.hpp:170
static HalfBandIirDesign polyphase_stage_design(Quality quality, int stage) noexcept
The elliptic half-band design stage stage (0 to 3) uses in the polyphase_iir lane at quality.
Definition oversampling.hpp:201
Kind
Which anti-aliasing filter family the oversampler uses.
Definition oversampling.hpp:83
@ fir_biquad
Butterworth biquad lowpass on both sides; ~7 dB rejection.
Definition oversampling.hpp:84
@ linear_phase_fir
Linear-phase FIR with reported integer latency.
Definition oversampling.hpp:86
@ polyphase_iir
Elliptic half-band polyphase IIR (allpass network). Default.
Definition oversampling.hpp:85
Factor
Definition oversampling.hpp:80
@ x16
Definition oversampling.hpp:80
@ x2
Definition oversampling.hpp:80
@ x4
Definition oversampling.hpp:80
@ x8
Definition oversampling.hpp:80
Factor factor() const
Definition oversampling.hpp:137
Evaluate what a biquad (or a cascade of them) does to the spectrum.
Polyphase IIR allpass-network half-band filters for 2x oversampling.
@ count
sentinel: number of real capabilities (keep LAST)
Definition canvas_capability.hpp:38
Definition design_adherence.hpp:32
Definition additive_bank.hpp:218
double halfband_iir_group_delay(const HalfBandIirDesign &design, double frequency) noexcept
Group delay of H(z) in samples of the filter's own rate.
Definition halfband_iir.hpp:287
@ up
Upper sideband on both channels: f → f + Δf.
Definition frequency_shifter_ssb.hpp:315
@ down
Lower sideband on both channels: f → f − Δf.
Definition frequency_shifter_ssb.hpp:316
HalfBandIirDesign design_halfband_iir(std::size_t coefficient_count, double passband_edge) noexcept
Closed-form elliptic half-band design (see the file comment).
Definition halfband_iir.hpp:185
double section_group_delay(const BiquadCoefficientsT< SampleType > &c, double omega)
Group delay of one biquad section at omega (radians per sample), in samples: -d(arg H)/d(omega) for H...
Definition frequency_response.hpp:68
OversamplerT< double > Oversampler64
Definition oversampling.hpp:458
@ i
Definition formant_filter_bank.hpp:20
OversamplerT< float > Oversampler
Definition oversampling.hpp:457
@ exact
Definition fast_math.hpp:630
double halfband_iir_stopband_db(const HalfBandIirDesign &design) noexcept
Worst-case (largest) stopband magnitude in dB over [stopband_edge(), 0.5], sampled densely enough to ...
Definition halfband_iir.hpp:301
@ s
Definition input_events.hpp:41
@ n
Definition input_events.hpp:40
Linear-phase 2x FIR stage used by the realtime oversampler.
Coefficients of one elliptic polyphase half-band filter, ascending.
Definition halfband_iir.hpp:148
Definition oversampling.hpp:94
double exact_input_samples
Definition oversampling.hpp:96
bool constant
Definition oversampling.hpp:97
int input_samples
Definition oversampling.hpp:95