diff --git a/src/sfizz/effects/Disto.cpp b/src/sfizz/effects/Disto.cpp index 946fdae6..0ee5534e 100644 --- a/src/sfizz/effects/Disto.cpp +++ b/src/sfizz/effects/Disto.cpp @@ -22,8 +22,7 @@ #include "Opcode.h" #include "Config.h" #include "MathHelpers.h" -#include -#include +#include "OversamplerHelpers.h" #include #include @@ -47,15 +46,9 @@ struct Disto::Impl { float _toneLpfMem[EffectChannels] = {}; faustDisto _stages[EffectChannels][Default::maxDistoStages]; - hiir::Upsampler2xFpu<12> _up2x[EffectChannels]; - hiir::Upsampler2xFpu<4> _up4x[EffectChannels]; - hiir::Upsampler2xFpu<3> _up8x[EffectChannels]; - - hiir::Downsampler2xFpu<12> _down2x[EffectChannels]; - hiir::Downsampler2xFpu<4> _down4x[EffectChannels]; - hiir::Downsampler2xFpu<3> _down8x[EffectChannels]; - - std::unique_ptr _temp8x[2]; + sfz::Upsampler _upsampler[EffectChannels]; + sfz::Downsampler _downsampler[EffectChannels]; + std::unique_ptr _temp[2]; // use the same formula as reverb float toneCutoff() const noexcept @@ -97,27 +90,14 @@ void Disto::setSampleRate(double sampleRate) stage.instanceConstants(sampleRate); } } - - static constexpr double coefs2x[12] = { 0.036681502163648017, 0.13654762463195794, 0.27463175937945444, 0.42313861743656711, 0.56109869787919531, 0.67754004997416184, 0.76974183386322703, 0.83988962484963892, 0.89226081800387902, 0.9315419599631839, 0.96209454837808417, 0.98781637073289585 }; - static constexpr double coefs4x[4] = { 0.042448989488488006, 0.17072114107630679, 0.39329183835224008, 0.74569514831986694 }; - static constexpr double coefs8x[3] = { 0.055748680811302048, 0.24305119574153092, 0.6466991311926823 }; - - for (unsigned c = 0; c < EffectChannels; ++c) { - impl._down2x[c].set_coefs(coefs2x); - impl._down4x[c].set_coefs(coefs4x); - impl._down8x[c].set_coefs(coefs8x); - impl._up2x[c].set_coefs(coefs2x); - impl._up4x[c].set_coefs(coefs4x); - impl._up8x[c].set_coefs(coefs8x); - } } void Disto::setSamplesPerBlock(int samplesPerBlock) { Impl& impl = *_impl; - for (std::unique_ptr& temp : impl._temp8x) - temp.reset(new float[8 * samplesPerBlock]); + for (std::unique_ptr& temp : impl._temp) + temp.reset(new float[_oversampling * samplesPerBlock]); } void Disto::clear() @@ -130,12 +110,8 @@ void Disto::clear() for (unsigned c = 0; c < EffectChannels; ++c) { impl._toneLpfMem[c] = 0.0f; - impl._up2x[c].clear_buffers(); - impl._up4x[c].clear_buffers(); - impl._up8x[c].clear_buffers(); - impl._down2x[c].clear_buffers(); - impl._down4x[c].clear_buffers(); - impl._down8x[c].clear_buffers(); + impl._downsampler[c].clear(); + impl._upsampler[c].clear(); } } @@ -162,14 +138,12 @@ void Disto::process(const float* const inputs[], float* const outputs[], unsigne } impl._toneLpfMem[c] = lpfMem; - // upsample to 8x + // upsample absl::Span temp[2] = { - absl::Span(impl._temp8x[0].get(), 8 * nframes), - absl::Span(impl._temp8x[1].get(), 8 * nframes), + absl::Span(impl._temp[0].get(), _oversampling * nframes), + absl::Span(impl._temp[1].get(), _oversampling * nframes), }; - impl._up2x[c].process_block(temp[0].data(), lpfOut.data(), nframes); - impl._up4x[c].process_block(temp[1].data(), temp[0].data(), 2 * nframes); - impl._up8x[c].process_block(temp[0].data(), temp[1].data(), 4 * nframes); + impl._upsampler[c].process(_oversampling, lpfOut.data(), temp[0].data(), nframes, temp[1].data(), static_cast(temp[1].size())); absl::Span upsamplerOut = temp[0]; // run disto stages @@ -180,13 +154,11 @@ void Disto::process(const float* const inputs[], float* const outputs[], unsigne // float *faustIn[] = { stageInOut.data() }; float *faustOut[] = { stageInOut.data() }; - impl._stages[c][s].compute(8 * nframes, faustIn, faustOut); + impl._stages[c][s].compute(_oversampling * nframes, faustIn, faustOut); } - // downsample to 1x - impl._down8x[c].process_block(temp[1].data(), stageInOut.data(), 4 * nframes); - impl._down4x[c].process_block(temp[0].data(), temp[1].data(), 2 * nframes); - impl._down2x[c].process_block(outputs[c], temp[0].data(), nframes); + // downsample + impl._downsampler[c].process(_oversampling, stageInOut.data(), outputs[c], nframes, temp[1].data(), static_cast(temp[1].size())); // dry/wet mix absl::Span mixOut(outputs[c], nframes);