chromaflock/Source/DSP/Delay.h

76 lines
2.4 KiB
C
Raw Normal View History

2026-07-13 20:57:38 +02:00
#pragma once
#include <vector>
#include <algorithm>
#include <cmath>
class Delay {
public:
void prepare(double sr) {
sampleRate = sr;
int maxSamples = static_cast<int>(sr * 2.0);
bufferL.resize(maxSamples, 0.0f);
bufferR.resize(maxSamples, 0.0f);
writePos = 0;
}
void setParameters(float timeMs, float fb, float mx, bool pp, float spr) {
timeSamples = static_cast<int>(timeMs * 0.001f * sampleRate);
int bufMax = static_cast<int>(bufferL.size()) - 1;
timeSamples = std::clamp(timeSamples, 1, bufMax);
feedback = std::clamp(fb, 0.0f, 0.95f);
mix = std::clamp(mx, 0.0f, 1.0f);
pingpong = pp;
spread = std::clamp(spr, 0.25f, 0.75f);
}
void process(float& left, float& right) {
int bufSize = static_cast<int>(bufferL.size());
if (pingpong) {
int timeR = std::max(1, static_cast<int>(timeSamples * spread));
int readL = (writePos - timeSamples + bufSize) % bufSize;
int readR = (writePos - timeR + bufSize) % bufSize;
float outL = bufferR[readR];
float outR = bufferL[readL];
bufferL[writePos] = left + outR * feedback;
bufferR[writePos] = right + outL * feedback;
writePos = (writePos + 1) % bufSize;
left = left * (1.0f - mix) + outL * mix;
right = right * (1.0f - mix) + outR * mix;
} else {
int readPos1 = (writePos - timeSamples + bufSize) % bufSize;
int time2 = std::max(1, static_cast<int>(timeSamples * spread));
int readPos2 = (writePos - time2 + bufSize) % bufSize;
float tap1L = bufferL[readPos1];
float tap1R = bufferR[readPos1];
float tap2L = bufferL[readPos2];
float tap2R = bufferR[readPos2];
float outL = tap1L + tap2L * 0.6f;
float outR = tap1R + tap2R * 0.6f;
bufferL[writePos] = left + outL * feedback;
bufferR[writePos] = right + outR * feedback;
writePos = (writePos + 1) % bufSize;
left = left * (1.0f - mix) + outL * mix;
right = right * (1.0f - mix) + outR * mix;
}
}
private:
std::vector<float> bufferL, bufferR;
int writePos = 0;
double sampleRate = 44100;
int timeSamples = 8820;
float feedback = 0.3f;
float mix = 0.25f;
bool pingpong = false;
float spread = 0.5f;
};