|
@@ -34,8 +34,8 @@ struct Delay : Module { |
|
|
|
|
|
|
|
|
Delay() { |
|
|
Delay() { |
|
|
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); |
|
|
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); |
|
|
configParam(TIME_PARAM, 0.f, 1.f, 0.5f, "Time"); |
|
|
|
|
|
configParam(FEEDBACK_PARAM, 0.f, 1.f, 0.5f, "Feedback"); |
|
|
|
|
|
|
|
|
configParam(TIME_PARAM, 0.f, 1.f, 0.5f, "Time", " s", 10.f / 1e-3, 1e-3); |
|
|
|
|
|
configParam(FEEDBACK_PARAM, 0.f, 1.f, 0.5f, "Feedback", "%", 0, 100); |
|
|
configParam(COLOR_PARAM, 0.f, 1.f, 0.5f, "Color"); |
|
|
configParam(COLOR_PARAM, 0.f, 1.f, 0.5f, "Color"); |
|
|
configParam(MIX_PARAM, 0.f, 1.f, 0.5f, "Mix", "%", 0, 100); |
|
|
configParam(MIX_PARAM, 0.f, 1.f, 0.5f, "Mix", "%", 0, 100); |
|
|
|
|
|
|
|
@@ -50,13 +50,16 @@ struct Delay : Module { |
|
|
void process(const ProcessArgs &args) override { |
|
|
void process(const ProcessArgs &args) override { |
|
|
// Get input to delay block |
|
|
// Get input to delay block |
|
|
float in = inputs[IN_INPUT].getVoltage(); |
|
|
float in = inputs[IN_INPUT].getVoltage(); |
|
|
float feedback = clamp(params[FEEDBACK_PARAM].getValue() + inputs[FEEDBACK_INPUT].getVoltage() / 10.f, 0.f, 1.f); |
|
|
|
|
|
|
|
|
float feedback = params[FEEDBACK_PARAM].getValue() + inputs[FEEDBACK_INPUT].getVoltage() / 10.f; |
|
|
|
|
|
feedback = clamp(feedback, 0.f, 1.f); |
|
|
float dry = in + lastWet * feedback; |
|
|
float dry = in + lastWet * feedback; |
|
|
|
|
|
|
|
|
// Compute delay time in seconds |
|
|
// Compute delay time in seconds |
|
|
float delay = 1e-3 * std::pow(10.f / 1e-3, clamp(params[TIME_PARAM].getValue() + inputs[TIME_INPUT].getVoltage() / 10.f, 0.f, 1.f)); |
|
|
|
|
|
|
|
|
float delay = params[TIME_PARAM].getValue() + inputs[TIME_INPUT].getVoltage() / 10.f; |
|
|
|
|
|
delay = clamp(delay, 0.f, 1.f); |
|
|
|
|
|
delay = 1e-3 * std::pow(10.f / 1e-3, delay); |
|
|
// Number of delay samples |
|
|
// Number of delay samples |
|
|
float index = delay * args.sampleRate; |
|
|
|
|
|
|
|
|
float index = std::round(delay * args.sampleRate); |
|
|
|
|
|
|
|
|
// Push dry sample into history buffer |
|
|
// Push dry sample into history buffer |
|
|
if (!historyBuffer.full()) { |
|
|
if (!historyBuffer.full()) { |
|
@@ -69,6 +72,7 @@ struct Delay : Module { |
|
|
if (outBuffer.empty()) { |
|
|
if (outBuffer.empty()) { |
|
|
double ratio = 1.f; |
|
|
double ratio = 1.f; |
|
|
if (std::fabs(consume) >= 16.f) { |
|
|
if (std::fabs(consume) >= 16.f) { |
|
|
|
|
|
// Here's where the delay magic is. Smooth the ratio depending on how divergent we are from the correct delay time. |
|
|
ratio = std::pow(10.f, clamp(consume / 10000.f, -1.f, 1.f)); |
|
|
ratio = std::pow(10.f, clamp(consume / 10000.f, -1.f, 1.f)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -90,20 +94,24 @@ struct Delay : Module { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Apply color to delay wet output |
|
|
// Apply color to delay wet output |
|
|
// TODO Make it sound better |
|
|
|
|
|
float color = clamp(params[COLOR_PARAM].getValue() + inputs[COLOR_INPUT].getVoltage() / 10.f, 0.f, 1.f); |
|
|
|
|
|
float lowpassFreq = 10000.f * std::pow(10.f, clamp(2.f*color, 0.f, 1.f)); |
|
|
|
|
|
lowpassFilter.setCutoff(lowpassFreq / args.sampleRate); |
|
|
|
|
|
|
|
|
float color = params[COLOR_PARAM].getValue() + inputs[COLOR_INPUT].getVoltage() / 10.f; |
|
|
|
|
|
color = clamp(color, 0.f, 1.f); |
|
|
|
|
|
float colorFreq = std::pow(100.f, 2.f * color - 1.f); |
|
|
|
|
|
|
|
|
|
|
|
float lowpassFreq = clamp(20000.f * colorFreq, 20.f, 20000.f); |
|
|
|
|
|
lowpassFilter.setCutoffFreq(lowpassFreq / args.sampleRate); |
|
|
lowpassFilter.process(wet); |
|
|
lowpassFilter.process(wet); |
|
|
wet = lowpassFilter.lowpass(); |
|
|
wet = lowpassFilter.lowpass(); |
|
|
float highpassFreq = 10.f * std::pow(100.f, clamp(2.f*color - 1.f, 0.f, 1.f)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float highpassFreq = clamp(20.f * colorFreq, 20.f, 20000.f); |
|
|
highpassFilter.setCutoff(highpassFreq / args.sampleRate); |
|
|
highpassFilter.setCutoff(highpassFreq / args.sampleRate); |
|
|
highpassFilter.process(wet); |
|
|
highpassFilter.process(wet); |
|
|
wet = highpassFilter.highpass(); |
|
|
wet = highpassFilter.highpass(); |
|
|
|
|
|
|
|
|
lastWet = wet; |
|
|
lastWet = wet; |
|
|
|
|
|
|
|
|
float mix = clamp(params[MIX_PARAM].getValue() + inputs[MIX_INPUT].getVoltage() / 10.f, 0.f, 1.f); |
|
|
|
|
|
|
|
|
float mix = params[MIX_PARAM].getValue() + inputs[MIX_INPUT].getVoltage() / 10.f; |
|
|
|
|
|
mix = clamp(mix, 0.f, 1.f); |
|
|
float out = crossfade(in, wet, mix); |
|
|
float out = crossfade(in, wet, mix); |
|
|
outputs[OUT_OUTPUT].setVoltage(out); |
|
|
outputs[OUT_OUTPUT].setVoltage(out); |
|
|
} |
|
|
} |
|
|