Browse Source

Some attempt at improving Delay

tags/v0.4.0
Andrew Belt 6 years ago
parent
commit
bdcf327dfb
3 changed files with 82 additions and 28 deletions
  1. +57
    -25
      src/Delay.cpp
  2. +22
    -0
      src/Scope.cpp
  3. +3
    -3
      src/VCMixer.cpp

+ 57
- 25
src/Delay.cpp View File

@@ -27,7 +27,9 @@ struct Delay : Module {
DoubleRingBuffer<float, HISTORY_SIZE> historyBuffer;
DoubleRingBuffer<float, 16> outBuffer;
SampleRateConverter<1> src;
float lastIndex = 0.0;
float lastWet = 0.0;
RCFilter lowpassFilter;
RCFilter highpassFilter;

Delay();

@@ -42,39 +44,69 @@ Delay::Delay() {
}

void Delay::step() {
// Compute delay time
// Get input to delay block
float in = getf(inputs[IN_INPUT]);
float feedback = clampf(params[FEEDBACK_PARAM] + getf(inputs[FEEDBACK_INPUT]) / 10.0, 0.0, 0.99);
float dry = in + lastWet * feedback;

// Compute delay time in seconds
float delay = 1e-3 * powf(10.0 / 1e-3, clampf(params[TIME_PARAM] + getf(inputs[TIME_INPUT]) / 10.0, 0.0, 1.0));
// Number of delay samples
float index = delay * gSampleRate;
// lastIndex = crossf(lastIndex, index, 0.001);

// Read the history
int consume = (int)(historyBuffer.size() - index);
// TODO This is a horrible digital delay algorithm. Rewrite later.

// Push dry sample into history buffer
if (!historyBuffer.full()) {
historyBuffer.push(dry);
}

// How many samples do we need consume to catch up?
float consume = index - historyBuffer.size();
// printf("%f\t%d\t%f\n", index, historyBuffer.size(), consume);

// printf("wanted: %f\tactual: %d\tdiff: %d\tratio: %f\n", index, historyBuffer.size(), consume, index / historyBuffer.size());
if (outBuffer.empty()) {
if (consume > 0) {
int inFrames = consume;
int outFrames = outBuffer.capacity();
// printf("\t%d\t%d\n", inFrames, outFrames);
src.setRatioSmooth(index / historyBuffer.size());
src.process((const Frame<1>*)historyBuffer.startData(), &inFrames, (Frame<1>*)outBuffer.endData(), &outFrames);
historyBuffer.startIncr(inFrames);
outBuffer.endIncr(outFrames);
// printf("\t%d\t%d\n", inFrames, outFrames);
// if (historyBuffer.size() >= index)
// outBuffer.push(historyBuffer.shift());
}
// Idk wtf I'm doing
double ratio = 1.0;
if (consume <= -16)
ratio = 0.5;
else if (consume >= 16)
ratio = 2.0;

// printf("%f\t%lf\n", consume, ratio);
int inFrames = mini(historyBuffer.size(), 16);
int outFrames = outBuffer.capacity();
// printf(">\t%d\t%d\n", inFrames, outFrames);
src.setRatioSmooth(ratio);
src.process((const Frame<1>*)historyBuffer.startData(), &inFrames, (Frame<1>*)outBuffer.endData(), &outFrames);
historyBuffer.startIncr(inFrames);
outBuffer.endIncr(outFrames);
// printf("<\t%d\t%d\n", inFrames, outFrames);
// printf("====================================\n");
}

float out = 0.0;
float wet = 0.0;
if (!outBuffer.empty()) {
out = outBuffer.shift();
wet = outBuffer.shift();
}

// Write the history
float in = getf(inputs[IN_INPUT]);
historyBuffer.push(in + out * clampf(params[FEEDBACK_PARAM] + getf(inputs[FEEDBACK_INPUT]) / 10.0, 0.0, 1.0));
out = crossf(in, out, clampf(params[MIX_PARAM] + getf(inputs[MIX_INPUT]) / 10.0, 0.0, 1.0));

// Apply color to delay wet output
// TODO Make it sound better
float color = clampf(params[COLOR_PARAM] + getf(inputs[COLOR_INPUT]) / 10.0, 0.0, 1.0);
float lowpassFreq = 10000.0 * powf(10.0, clampf(2.0*color, 0.0, 1.0));
lowpassFilter.setCutoff(lowpassFreq / gSampleRate);
lowpassFilter.process(wet);
wet = lowpassFilter.lowpass();
float highpassFreq = 10.0 * powf(100.0, clampf(2.0*color - 1.0, 0.0, 1.0));
highpassFilter.setCutoff(highpassFreq / gSampleRate);
highpassFilter.process(wet);
wet = highpassFilter.highpass();

lastWet = wet;

float mix = clampf(params[MIX_PARAM] + getf(inputs[MIX_INPUT]) / 10.0, 0.0, 1.0);
float out = crossf(in, wet, mix);
setf(outputs[OUT_OUTPUT], out);
}

@@ -98,7 +130,7 @@ DelayWidget::DelayWidget() {

addParam(createParam<Davies1900hBlackKnob>(Vec(67, 57), module, Delay::TIME_PARAM, 0.0, 1.0, 0.5));
addParam(createParam<Davies1900hBlackKnob>(Vec(67, 123), module, Delay::FEEDBACK_PARAM, 0.0, 1.0, 0.5));
addParam(createParam<Davies1900hBlackKnob>(Vec(67, 190), module, Delay::COLOR_PARAM, -1.0, 1.0, 0.0));
addParam(createParam<Davies1900hBlackKnob>(Vec(67, 190), module, Delay::COLOR_PARAM, 0.0, 1.0, 0.5));
addParam(createParam<Davies1900hBlackKnob>(Vec(67, 257), module, Delay::MIX_PARAM, 0.0, 1.0, 0.5));

addInput(createInput<PJ301MPort>(Vec(14, 63), module, Delay::TIME_INPUT));


+ 22
- 0
src/Scope.cpp View File

@@ -40,6 +40,28 @@ struct Scope : Module {

Scope();
void step();

json_t *toJson() {
json_t *rootJ = json_object();
json_object_set_new(rootJ, "sum", json_integer((int) sum));
json_object_set_new(rootJ, "ext", json_integer((int) ext));
return rootJ;
}

void fromJson(json_t *rootJ) {
json_t *sumJ = json_object_get(rootJ, "sum");
if (sumJ)
sum = json_integer_value(sumJ);

json_t *extJ = json_object_get(rootJ, "ext");
if (extJ)
ext = json_integer_value(extJ);
}

void initialize() {
sum = false;
ext = false;
}
};




+ 3
- 3
src/VCMixer.cpp View File

@@ -70,9 +70,9 @@ VCMixerWidget::VCMixerWidget() {
addChild(createScrew<ScrewSilver>(Vec(box.size.x-30, 365)));

addParam(createParam<Davies1900hLargeBlackKnob>(Vec(48, 55), module, VCMixer::MIX_PARAM, 0.0, 1.0, 0.5));
addParam(createParam<Davies1900hBlackKnob>(Vec(57, 139), module, VCMixer::CH1_PARAM, 0.0, 1.0, 0.5));
addParam(createParam<Davies1900hBlackKnob>(Vec(57, 219), module, VCMixer::CH2_PARAM, 0.0, 1.0, 0.5));
addParam(createParam<Davies1900hBlackKnob>(Vec(57, 300), module, VCMixer::CH3_PARAM, 0.0, 1.0, 0.5));
addParam(createParam<Davies1900hBlackKnob>(Vec(57, 139), module, VCMixer::CH1_PARAM, 0.0, 1.0, 0.0));
addParam(createParam<Davies1900hBlackKnob>(Vec(57, 219), module, VCMixer::CH2_PARAM, 0.0, 1.0, 0.0));
addParam(createParam<Davies1900hBlackKnob>(Vec(57, 300), module, VCMixer::CH3_PARAM, 0.0, 1.0, 0.0));

addInput(createInput<PJ301MPort>(Vec(16, 69), module, VCMixer::MIX_CV_INPUT));
addInput(createInput<PJ301MPort>(Vec(22, 129), module, VCMixer::CH1_INPUT));


Loading…
Cancel
Save