chromaflock/Source/DSP/Distortion.h

84 lines
2.4 KiB
C
Raw Permalink Normal View History

2026-07-13 20:57:38 +02:00
#pragma once
#include <cmath>
#include <algorithm>
enum class DistortionType { SoftClip = 0, HardClip, Foldback, Overdrive, NumTypes };
class Distortion {
public:
void prepare(double /*sr*/) {}
2026-07-15 23:51:38 +02:00
void setParameters(DistortionType type, float amount, float symmetry, float tone) {
2026-07-13 20:57:38 +02:00
distType = type;
distAmount = amount;
2026-07-15 23:51:38 +02:00
distSymmetry = symmetry;
distTone = tone;
dryWet = 1.0f;
2026-07-13 20:57:38 +02:00
}
float process(float input) {
float driven = input * (1.0f + distAmount * 9.0f);
float wet = 0.0f;
switch (distType) {
case DistortionType::SoftClip:
wet = std::tanh(driven);
break;
case DistortionType::HardClip: {
float threshold = 1.0f / (1.0f + distAmount * 9.0f);
wet = std::clamp(driven, -threshold, threshold);
break;
}
case DistortionType::Foldback: {
float threshold = 1.0f + distAmount * 3.0f;
wet = driven;
while (wet > threshold || wet < -threshold) {
if (wet > threshold)
wet = 2.0f * threshold - wet;
else if (wet < -threshold)
wet = -2.0f * threshold - wet;
else
break;
}
if (threshold > 0.0f)
wet /= threshold;
break;
}
case DistortionType::Overdrive: {
float t = driven;
if (t > 1.0f) t = 1.0f;
else if (t < -1.0f) t = -1.0f;
wet = t * (1.5f - 0.5f * t * t);
break;
}
default:
wet = driven;
break;
}
2026-07-15 23:51:38 +02:00
// Asymmetry: bias the signal before/after shaping for even-harmonic grit
wet += distSymmetry * 0.5f;
// Tone: one-pole low-pass to tame harsh high harmonics
float lpCoeff = distTone * 0.9f + 0.05f;
toneState += lpCoeff * (wet - toneState);
wet = toneState;
if (distAmount < 0.001f && std::abs(distSymmetry) < 0.001f)
2026-07-13 20:57:38 +02:00
return input;
return input + (wet - input) * dryWet;
}
private:
DistortionType distType = DistortionType::SoftClip;
float distAmount = 0.0f;
2026-07-15 23:51:38 +02:00
float distSymmetry = 0.0f;
float distTone = 1.0f;
float dryWet = 1.0f;
float toneState = 0.0f;
2026-07-13 20:57:38 +02:00
};