#pragma once #include #include #include class Delay { public: void prepare(double sr) { sampleRate = sr; int maxSamples = static_cast(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(timeMs * 0.001f * sampleRate); int bufMax = static_cast(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(bufferL.size()); if (pingpong) { int timeR = std::max(1, static_cast(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(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 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; };