1
0

Fade delays on chorus depth change

This commit is contained in:
Geraint 2025-07-04 23:47:19 +01:00
parent 15c904aff6
commit fd80328727

View File

@ -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<class Io, class Config, class Block>
@ -80,12 +81,15 @@ 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<Sample, 6> multiIn, multiOut;
std::array<Sample, 6> 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) {
@ -94,22 +98,33 @@ struct ChorusSTFX : public BaseEffect {
}
delay.write(multiIn);
Complex phaseComplex = std::polar(Sample(1), phase*Sample(2*M_PI));
phase += phaseStep;
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) {
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;
if (fading) {
// read a second set of delay times, and fade between them
std::array<Sample, 6> multiOutFrom;
for (size_t c = 0; c < 6; ++c) {
sum += multiOut[c];
Sample osc = (phaseComplex*oscillatorOffsets[c]).real();
delaySamples[c] = depthSamplesFrom*Sample(0.5)*(1 + osc);
}
io.output[c][i] = multiIn[c]*dry + sum*wet;
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);
}