1
0

Update to new STFX

This commit is contained in:
Geraint 2023-12-03 20:49:49 +00:00
parent 7896c05a5e
commit d22cd189fe
5 changed files with 40 additions and 31 deletions

View File

@ -12,10 +12,11 @@ SIGNALSMITH_DSP_VERSION_CHECK(1, 4, 1)
namespace signalsmith { namespace basics { namespace signalsmith { namespace basics {
template<typename Sample, class BaseEffect> template<class BaseEffect>
class CrunchSTFX : public BaseEffect { class CrunchSTFX : public BaseEffect {
using typename BaseEffect::Sample;
using typename BaseEffect::ParamRange; using typename BaseEffect::ParamRange;
using typename BaseEffect::ParamSteps; using typename BaseEffect::ParamStepped;
int channels = 0; int channels = 0;
signalsmith::rates::Oversampler2xFIR<Sample> oversampler; signalsmith::rates::Oversampler2xFIR<Sample> oversampler;
@ -83,22 +84,22 @@ namespace signalsmith { namespace basics {
if (version != 0) return; if (version != 0) return;
using namespace signalsmith::units; using namespace signalsmith::units;
storage.param("drive", drive) storage.range("drive", drive)
.info("drive", "pre-distortion input gain") .info("drive", "pre-distortion input gain")
.range(dbToGain(-12), 4, dbToGain(40)) .range(dbToGain(-12), 4, dbToGain(40))
.unit("dB", 1, dbToGain, gainToDb) .unit("dB", 1, dbToGain, gainToDb)
.unit(""); .unit("");
storage.param("fuzz", fuzz) storage.range("fuzz", fuzz)
.info("fuzz", "amplitude-independent distortion") .info("fuzz", "amplitude-independent distortion")
.range(0, 0.5, 1) .range(0, 0.5, 1)
.unit("%", 0, pcToRatio, ratioToPc); .unit("%", 0, pcToRatio, ratioToPc);
storage.param("toneHz", toneHz) storage.range("toneHz", toneHz)
.info("tone", "limits the brightness of the distortion") .info("tone", "limits the brightness of the distortion")
.range(100, 4000, 20000) .range(100, 4000, 20000)
.unit("Hz", 0, 0, 1000) .unit("Hz", 0, 0, 1000)
.unit("kHz", 1, kHzToHz, hzToKHz, 1000, 1e100); .unit("kHz", 1, kHzToHz, hzToKHz, 1000, 1e100);
storage.param("outGain", outGain) storage.range("outGain", outGain)
.info("out", "output gain") .info("out", "output gain")
.range(dbToGain(-12), 1, dbToGain(24)) .range(dbToGain(-12), 1, dbToGain(24))
.unit("dB", 1, dbToGain, gainToDb) .unit("dB", 1, dbToGain, gainToDb)

View File

@ -14,10 +14,11 @@ SIGNALSMITH_DSP_VERSION_CHECK(1, 1, 0)
namespace signalsmith { namespace basics { namespace signalsmith { namespace basics {
template<typename Sample, class BaseEffect> template<class BaseEffect>
class LimiterSTFX : public BaseEffect { class LimiterSTFX : public BaseEffect {
using typename BaseEffect::Sample;
using typename BaseEffect::ParamRange; using typename BaseEffect::ParamRange;
using typename BaseEffect::ParamSteps; using typename BaseEffect::ParamStepped;
int channels = 0; int channels = 0;
double maxDelayMs = 0; double maxDelayMs = 0;
@ -28,7 +29,7 @@ namespace signalsmith { namespace basics {
ParamRange outputLimit{signalsmith::units::dbToGain(-3)}; ParamRange outputLimit{signalsmith::units::dbToGain(-3)};
ParamRange attackMs{20}, holdMs{0}, releaseMs{0}; ParamRange attackMs{20}, holdMs{0}, releaseMs{0};
ParamSteps smoothingStages{1}; ParamStepped smoothingStages{1};
ParamRange linkChannels{0.5}; ParamRange linkChannels{0.5};
LimiterSTFX(double maxDelayMs=100) : maxDelayMs(maxDelayMs) {} LimiterSTFX(double maxDelayMs=100) : maxDelayMs(maxDelayMs) {}
@ -40,35 +41,35 @@ namespace signalsmith { namespace basics {
int version = storage.version(4); int version = storage.version(4);
if (version != 4) return; if (version != 4) return;
storage.param("inputGain", inputGain) storage.range("inputGain", inputGain)
.info("pre-gain", "amplifies the input before limiting") .info("pre-gain", "amplifies the input before limiting")
.range(dbToGain(-12), 1, dbToGain(24)) .range(dbToGain(-12), 1, dbToGain(24))
.unit("dB", 1, dbToGain, gainToDb) .unit("dB", 1, dbToGain, gainToDb)
.unit(""); .unit("");
storage.param("outputLimit", outputLimit) storage.range("outputLimit", outputLimit)
.info("limit", "maximum output amplitude") .info("limit", "maximum output amplitude")
.range(dbToGain(-24), dbToGain(-12), 1) .range(dbToGain(-24), dbToGain(-12), 1)
.unit("dB", 1, dbToGain, gainToDb) .unit("dB", 1, dbToGain, gainToDb)
// Extra resolution between -1dB and 0dB // Extra resolution between -1dB and 0dB
.unit("dB", 2, dbToGain, gainToDb, dbToGain(-1), 1) .unit("dB", 2, dbToGain, gainToDb, dbToGain(-1), 1)
.unit(""); .unit("");
storage.param("attackMs", attackMs) storage.range("attackMs", attackMs)
.info("attack", "envelope smoothing time") .info("attack", "envelope smoothing time")
.range(1, 10, maxDelayMs/2) .range(1, 10, maxDelayMs/2)
.unit("ms", 0); .unit("ms", 0);
storage.param("holdMs", holdMs) storage.range("holdMs", holdMs)
.info("hold", "hold constant after peaks") .info("hold", "hold constant after peaks")
.range(0, 10, maxDelayMs/2) .range(0, 10, maxDelayMs/2)
.unit("ms", 0); .unit("ms", 0);
storage.param("releaseMs", releaseMs) storage.range("releaseMs", releaseMs)
.info("release", "extra release time (in addition to attack + hold)") .info("release", "extra release time (in addition to attack + hold)")
.range(0, 10, 250) .range(0, 10, 250)
.unit("ms", 0); .unit("ms", 0);
storage.param("smoothingStages", smoothingStages) storage.stepped("smoothingStages", smoothingStages)
.info("smoothing", "smoothing filter(s) used for attack-smoothing") .info("smoothing", "smoothing filter(s) used for attack-smoothing")
.names(1, "rect", "double"); .label(1, "rect", "double");
storage.param("linkChannels", linkChannels) storage.range("linkChannels", linkChannels)
.info("link", "link channel gains together") .info("link", "link channel gains together")
.range(0, 0.5, 1) .range(0, 0.5, 1)
.unit("%", 0, pcToRatio, ratioToPc); .unit("%", 0, pcToRatio, ratioToPc);
@ -144,7 +145,7 @@ namespace signalsmith { namespace basics {
int attackSamples = delaySamplesTo; int attackSamples = delaySamplesTo;
int holdSamples = std::ceil(holdMs*0.001*sampleRate); int holdSamples = std::ceil(holdMs*0.001*sampleRate);
Sample releaseSamples = releaseMs*0.001*sampleRate; Sample releaseSamples = releaseMs*0.001*sampleRate;
int stages = smoothingStages.to(); int stages = smoothingStages;
for (auto &envelope : channelEnvelopes) { for (auto &envelope : channelEnvelopes) {
envelope.peakHold.set(attackSamples + holdSamples); envelope.peakHold.set(attackSamples + holdSamples);

View File

@ -16,10 +16,11 @@ SIGNALSMITH_DSP_VERSION_CHECK(1, 3, 3)
namespace signalsmith { namespace basics { namespace signalsmith { namespace basics {
template<typename Sample, class BaseEffect> template<class BaseEffect>
struct ReverbSTFX : public BaseEffect { struct ReverbSTFX : public BaseEffect {
using typename BaseEffect::Sample;
using typename BaseEffect::ParamRange; using typename BaseEffect::ParamRange;
using typename BaseEffect::ParamSteps; using typename BaseEffect::ParamStepped;
using Array = std::array<Sample, 8>; using Array = std::array<Sample, 8>;
using Array3 = std::array<Sample, 3>; using Array3 = std::array<Sample, 3>;
@ -42,7 +43,7 @@ namespace signalsmith { namespace basics {
int version = storage.version(5); int version = storage.version(5);
if (version != 5) return; if (version != 5) return;
storage.param("dry", dry) storage.range("dry", dry)
.info("dry", "dry signal gain") .info("dry", "dry signal gain")
.range(0, 1, 4) .range(0, 1, 4)
.unit("dB", 1, dbToGain, gainToDb) .unit("dB", 1, dbToGain, gainToDb)
@ -50,7 +51,7 @@ namespace signalsmith { namespace basics {
.exact(0, "off") .exact(0, "off")
.unit(""); .unit("");
storage.param("wet", wet) storage.range("wet", wet)
.info("wet", "reverb tail gain") .info("wet", "reverb tail gain")
.range(0, 1, 4) .range(0, 1, 4)
.unit("dB", 1, dbToGain, gainToDb) .unit("dB", 1, dbToGain, gainToDb)
@ -58,42 +59,42 @@ namespace signalsmith { namespace basics {
.exact(0, "off") .exact(0, "off")
.unit(""); .unit("");
storage.param("roomMs", roomMs) storage.range("roomMs", roomMs)
.info("room", "room size (1ms ~ 1 foot)") .info("room", "room size (1ms ~ 1 foot)")
.range(10, 100, maxRoomMs) .range(10, 100, maxRoomMs)
.unit("ms", 0); .unit("ms", 0);
storage.param("rt20", rt20) storage.range("rt20", rt20)
.info("decay", "RT20: decay time to -20dB") .info("decay", "RT20: decay time to -20dB")
.range(0.01, 2, 30) .range(0.01, 2, 30)
.unit("seconds", 2, 0, 1) .unit("seconds", 2, 0, 1)
.unit("seconds", 1, 1, 1e100); .unit("seconds", 1, 1, 1e100);
storage.param("early", early) storage.range("early", early)
.info("early", "Early reflections") .info("early", "Early reflections")
.range(0, 1, 2.5) .range(0, 1, 2.5)
.unit("%", 0, pcToRatio, ratioToPc); .unit("%", 0, pcToRatio, ratioToPc);
storage.param("detune", detune) storage.range("detune", detune)
.info("detune", "Detuning rate (inside feedback loop)") .info("detune", "Detuning rate (inside feedback loop)")
.range(0, 5, 50) .range(0, 5, 50)
.unit("", 1); .unit("", 1);
storage.param("lowCutHz", lowCutHz) storage.range("lowCutHz", lowCutHz)
.info("low cut", "Removes low frequencies") .info("low cut", "Removes low frequencies")
.range(10, 80, 500) .range(10, 80, 500)
.unit("Hz", 0); .unit("Hz", 0);
storage.param("lowDampRate", lowDampRate) storage.range("lowDampRate", lowDampRate)
.info("low damp", "Reduce low frequencies over time") .info("low damp", "Reduce low frequencies over time")
.range(1, 2, 10) .range(1, 2, 10)
.unit("", 1); .unit("", 1);
storage.param("highCutHz", highCutHz) storage.range("highCutHz", highCutHz)
.info("high cut", "Removes high frequencies") .info("high cut", "Removes high frequencies")
.range(1000, 5000, 20000) .range(1000, 5000, 20000)
.unit("kHz", 1, kHzToHz, hzToKHz, 1000, 1e100) .unit("kHz", 1, kHzToHz, hzToKHz, 1000, 1e100)
.unit("Hz", 0); .unit("Hz", 0);
storage.param("highDampRate", highDampRate) storage.range("highDampRate", highDampRate)
.info("high damp", "Reduce high frequencies over time") .info("high damp", "Reduce high frequencies over time")
.range(1, 2, 10) .range(1, 2, 10)
.unit("", 1); .unit("", 1);

View File

@ -251,7 +251,7 @@ namespace stfx {
/// Creates an effect class from an effect template, with optional extra config. /// Creates an effect class from an effect template, with optional extra config.
/// The effect template takes `EffectTemplate<Sample, BaseClass, ...ExtraConfig>` /// The effect template takes `EffectTemplate<Sample, BaseClass, ...ExtraConfig>`
template<typename Sample, template <class, class, class...> class EffectTemplate, class ...ExtraConfig> template<typename Sample, template <class, class...> class EffectTemplate, class ...ExtraConfig>
class LibraryEffect : public EffectTemplate<Sample, stfx::LibraryEffectBase, ExtraConfig...> { class LibraryEffect : public EffectTemplate<Sample, stfx::LibraryEffectBase, ExtraConfig...> {
using EffectClass = EffectTemplate<Sample, stfx::LibraryEffectBase, ExtraConfig...>; using EffectClass = EffectTemplate<Sample, stfx::LibraryEffectBase, ExtraConfig...>;

View File

@ -13,6 +13,12 @@ namespace signalsmith { namespace units {
static double gainToDb(double gain) { static double gainToDb(double gain) {
return std::log10(std::max<double>(gain, 1e-10))*20; return std::log10(std::max<double>(gain, 1e-10))*20;
} }
static double dbToEnergy(double db) {
return std::pow(10, db*0.1);
}
static double energyToDb(double gain) {
return std::log10(std::max<double>(gain, 1e-10))*10;
}
static double pcToRatio(double percent) { static double pcToRatio(double percent) {
return percent*0.01; return percent*0.01;
} }