diff --git a/plugin.json b/plugin.json index 0a8d927..bad3264 100644 --- a/plugin.json +++ b/plugin.json @@ -1,48 +1,70 @@ { - "slug": "Befaco", - "version": "1.0.0", - "license": "BSD-3-Clause", - "name": "Befaco", - "author": "VCV", - "authorEmail": "contact@vcvrack.com", - "pluginUrl": "https://vcvrack.com/Befaco.html", - "authorUrl": "https://vcvrack.com/", - "sourceUrl": "https://github.com/VCVRack/Befaco", - "modules": [ - { - "slug": "EvenVCO", - "name": "EvenVCO", - "tags": ["VCO"] - }, - { - "slug": "Rampage", - "name": "Rampage", - "tags": ["Function Generator", "Logic", "Slew Limiter", "Envelope Follower", "Dual"] - }, - { - "slug": "ABC", - "name": "A*B+C", - "tags": ["Ring Modulator", "Attenuator", "Dual"] - }, - { - "slug": "SpringReverb", - "name": "Spring Reverb", - "tags": ["Reverb"] - }, - { - "slug": "Mixer", - "name": "Mixer", - "tags": ["Mixer"] - }, - { - "slug": "SlewLimiter", - "name": "Slew Limiter", - "tags": ["Slew Limiter", "Envelope Follower"] - }, - { - "slug": "DualAtenuverter", - "name": "Dual Atenuverter", - "tags": ["Attenuator", "Dual"] - } - ] + "slug": "Befaco", + "version": "1.0.0", + "license": "BSD-3-Clause", + "name": "Befaco", + "author": "VCV", + "authorEmail": "contact@vcvrack.com", + "pluginUrl": "https://vcvrack.com/Befaco.html", + "authorUrl": "https://vcvrack.com/", + "sourceUrl": "https://github.com/VCVRack/Befaco", + "modules": [ + { + "slug": "EvenVCO", + "name": "EvenVCO", + "tags": [ + "VCO" + ] + }, + { + "slug": "Rampage", + "name": "Rampage", + "tags": [ + "Function Generator", + "Logic", + "Slew Limiter", + "Envelope Follower", + "Dual" + ] + }, + { + "slug": "ABC", + "name": "A*B+C", + "tags": [ + "Ring Modulator", + "Attenuator", + "Dual" + ] + }, + { + "slug": "SpringReverb", + "name": "Spring Reverb", + "tags": [ + "Reverb" + ] + }, + { + "slug": "Mixer", + "name": "Mixer", + "tags": [ + "Mixer" + ] + }, + { + "slug": "SlewLimiter", + "name": "Slew Limiter", + "tags": [ + "Slew Limiter", + "Envelope Follower" + ] + }, + { + "slug": "DualAtenuverter", + "name": "Dual Atenuverter", + "tags": [ + "Attenuator", + "Dual" + ] + } + ] } \ No newline at end of file diff --git a/src/ABC.cpp b/src/ABC.cpp index b98422e..4de5a22 100644 --- a/src/ABC.cpp +++ b/src/ABC.cpp @@ -3,8 +3,16 @@ static float clip(float x) { - x = clamp(x, -2.f, 2.f); - return x / std::pow(1.f + std::pow(x, 24.f), 1/24.f); + // Pade approximant of x/(1 + x^12)^(1/12) + const float limit = 1.16691853009184; + x = clamp(x, -limit, limit); + return (x + 1.45833*std::pow(x, 13) + 0.559028*std::pow(x, 25) + 0.0427035*std::pow(x, 37)) + / (1. + 1.54167*std::pow(x, 12) + 0.642361*std::pow(x, 24) + 0.0579909*std::pow(x, 36)); +} + +static float exponentialBipolar80Pade_5_4(float x) { + return (0.109568*x + 0.281588*std::pow(x, 3) + 0.133841*std::pow(x, 5)) + / (1. - 0.630374*std::pow(x, 2) + 0.166271*std::pow(x, 4)); } @@ -31,10 +39,8 @@ struct ABC : Module { NUM_OUTPUTS }; enum LightIds { - OUT1_POS_LIGHT, - OUT1_NEG_LIGHT, - OUT2_POS_LIGHT, - OUT2_NEG_LIGHT, + ENUMS(OUT1_LIGHT, 2), + ENUMS(OUT2_LIGHT, 2), NUM_LIGHTS }; @@ -48,13 +54,13 @@ struct ABC : Module { void process(const ProcessArgs &args) override { float a1 = inputs[A1_INPUT].getVoltage(); - float b1 = inputs[B1_INPUT].getNormalVoltage(5.f) * 2.f*dsp::exponentialBipolar(80.f, params[B1_LEVEL_PARAM].getValue()); - float c1 = inputs[C1_INPUT].getNormalVoltage(10.f) * dsp::exponentialBipolar(80.f, params[C1_LEVEL_PARAM].getValue()); + float b1 = inputs[B1_INPUT].getNormalVoltage(5.f) * 2.f*exponentialBipolar80Pade_5_4(params[B1_LEVEL_PARAM].getValue()); + float c1 = inputs[C1_INPUT].getNormalVoltage(10.f) * exponentialBipolar80Pade_5_4(params[C1_LEVEL_PARAM].getValue()); float out1 = a1 * b1 / 5.f + c1; float a2 = inputs[A2_INPUT].getVoltage(); - float b2 = inputs[B2_INPUT].getNormalVoltage(5.f) * 2.f*dsp::exponentialBipolar(80.f, params[B2_LEVEL_PARAM].getValue()); - float c2 = inputs[C2_INPUT].getNormalVoltage(10.f) * dsp::exponentialBipolar(80.f, params[C2_LEVEL_PARAM].getValue()); + float b2 = inputs[B2_INPUT].getNormalVoltage(5.f) * 2.f*exponentialBipolar80Pade_5_4(params[B2_LEVEL_PARAM].getValue()); + float c2 = inputs[C2_INPUT].getNormalVoltage(10.f) * exponentialBipolar80Pade_5_4(params[C2_LEVEL_PARAM].getValue()); float out2 = a2 * b2 / 5.f + c2; // Set outputs @@ -69,10 +75,10 @@ struct ABC : Module { } // Lights - lights[OUT1_POS_LIGHT].setSmoothBrightness(out1 / 5.f, args.sampleTime); - lights[OUT1_NEG_LIGHT].setSmoothBrightness(-out1 / 5.f, args.sampleTime); - lights[OUT2_POS_LIGHT].setSmoothBrightness(out2 / 5.f, args.sampleTime); - lights[OUT2_NEG_LIGHT].setSmoothBrightness(-out2 / 5.f, args.sampleTime); + lights[OUT1_LIGHT + 0].setSmoothBrightness(out1 / 5.f, args.sampleTime); + lights[OUT1_LIGHT + 1].setSmoothBrightness(-out1 / 5.f, args.sampleTime); + lights[OUT2_LIGHT + 0].setSmoothBrightness(out2 / 5.f, args.sampleTime); + lights[OUT2_LIGHT + 1].setSmoothBrightness(-out2 / 5.f, args.sampleTime); } }; @@ -99,8 +105,8 @@ struct ABCWidget : ModuleWidget { addInput(createInput(Vec(7, 279), module, ABC::C2_INPUT)); addOutput(createOutput(Vec(7, 321), module, ABC::OUT2_OUTPUT)); - addChild(createLight>(Vec(37, 162), module, ABC::OUT1_POS_LIGHT)); - addChild(createLight>(Vec(37, 329), module, ABC::OUT2_POS_LIGHT)); + addChild(createLight>(Vec(37, 162), module, ABC::OUT1_LIGHT)); + addChild(createLight>(Vec(37, 329), module, ABC::OUT2_LIGHT)); } };