From fd8032872726de0321b4939b395cfd0278afa3ee Mon Sep 17 00:00:00 2001 From: Geraint Date: Fri, 4 Jul 2025 23:47:19 +0100 Subject: [PATCH] Fade delays on chorus depth change --- chorus.h | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/chorus.h b/chorus.h index 6dc314d..02a496e 100644 --- a/chorus.h +++ b/chorus.h @@ -57,7 +57,7 @@ struct ChorusSTFX : public BaseEffect { storage.range("detune", detune) .info("detune", "detuning depth") - .range(1, 10, 50) + .range(1, 8, 50) .unit(" s.t.", 0); } @@ -73,6 +73,7 @@ struct ChorusSTFX : public BaseEffect { void reset() { delay.reset(); + phase = 0; } template @@ -80,13 +81,16 @@ struct ChorusSTFX : public BaseEffect { Sample detuneHz = detune*0.45f/depthMs; // 0.45ms oscillation at 1Hz is about 1 semitone Sample phaseStep = detuneHz/config.sampleRate; - Sample depthSamples = depthMs*0.001*config.sampleRate; + bool fading = depthMs.from() != depthMs.to(); + Sample depthSamples = depthMs.to()*0.001*config.sampleRate; + Sample depthSamplesFrom = depthMs.from()*0.001*config.sampleRate; std::array multiIn, multiOut; std::array delaySamples; - Sample dry = 1 - mix*mix, wet = mix*(2 - mix)/std::sqrt(Sample(6)); - + auto dry = block.smooth(mix, [](double m){return 1 - m*m;}); + auto wet = block.smooth(mix, [](double m){return m*(2 - m)/std::sqrt(Sample(6));}); + for (size_t i = 0; i < block.length; ++i) { for (size_t c = 0; c < 6; ++c) { size_t inputC = c%config.inputChannels; @@ -94,21 +98,32 @@ struct ChorusSTFX : public BaseEffect { } delay.write(multiIn); - Complex phaseComplex = std::polar(Sample(1), phase*Sample(2*M_PI)); - phase += phaseStep; - for (size_t c = 0; c < 6; ++c) { - Sample osc = (phaseComplex*oscillatorOffsets[c]).real(); - delaySamples[c] = depthSamples*Sample(0.5)*(1 + osc); - } - delay.readMulti(delaySamples, multiOut); - - for (size_t c = 0; c < config.outputChannels; ++c) { - Sample sum = 0; + for (size_t oc = 0; oc < config.outputChannels; ++oc) { + Complex phaseComplex = std::polar(Sample(1), phase*Sample(2*M_PI) + oc*Sample(2.632)); for (size_t c = 0; c < 6; ++c) { - sum += multiOut[c]; + Sample osc = (phaseComplex*oscillatorOffsets[c]).real(); + delaySamples[c] = depthSamples*Sample(0.5)*(1 + osc); } - io.output[c][i] = multiIn[c]*dry + sum*wet; + delay.readMulti(delaySamples, multiOut); + + if (fading) { + // read a second set of delay times, and fade between them + std::array multiOutFrom; + for (size_t c = 0; c < 6; ++c) { + Sample osc = (phaseComplex*oscillatorOffsets[c]).real(); + delaySamples[c] = depthSamplesFrom*Sample(0.5)*(1 + osc); + } + delay.readMulti(delaySamples, multiOutFrom); + for (size_t c = 0; c < 6; ++c) { + multiOut[c] = block.fade(i, multiOutFrom[c], multiOut[c]); + } + } + + // Arbitrarily chosen gains, 4 positive, 2 negative + Sample sum = multiOut[0] - multiOut[1] + multiOut[2] + multiOut[3] - multiOut[4] + multiOut[5]; + io.output[oc][i] = multiIn[oc]*dry.at(i) + sum*wet.at(i); } + phase += phaseStep; } phase -= std::floor(phase); }