#pragma once #include #include struct BefacoTinyKnobRed : app::SvgKnob { BefacoTinyKnobRed() { minAngle = -0.8 * M_PI; maxAngle = 0.8 * M_PI; setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoTinyKnobRed.svg"))); } }; struct BefacoTinyKnobWhite : app::SvgKnob { BefacoTinyKnobWhite() { minAngle = -0.8 * M_PI; maxAngle = 0.8 * M_PI; setSvg(APP->window->loadSvg(asset::system("res/ComponentLibrary/BefacoTinyKnob.svg"))); } }; struct BefacoTinyKnobGrey : app::SvgKnob { BefacoTinyKnobGrey() { minAngle = -0.8 * M_PI; maxAngle = 0.8 * M_PI; setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoTinyKnobGrey.svg"))); } }; struct Davies1900hLargeGreyKnob : Davies1900hKnob { Davies1900hLargeGreyKnob() { setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Davies1900hLargeGrey.svg"))); } }; struct BefacoOutputPort : app::SvgPort { BefacoOutputPort() { setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoOutputPort.svg"))); } }; struct BefacoInputPort : app::SvgPort { BefacoInputPort() { setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoInputPort.svg"))); } }; template T sin2pi_pade_05_5_4(T x) { x -= 0.5f; return (T(-6.283185307) * x + T(33.19863968) * simd::pow(x, 3) - T(32.44191367) * simd::pow(x, 5)) / (1 + T(1.296008659) * simd::pow(x, 2) + T(0.7028072946) * simd::pow(x, 4)); } template T tanh_pade(T x) { T x2 = x * x; T q = 12.f + x2; return 12.f * x * q / (36.f * x2 + q * q); } struct ADEnvelope { enum Stage { STAGE_OFF, STAGE_ATTACK, STAGE_DECAY }; Stage stage = STAGE_OFF; float env = 0.f; float attackTime = 0.1, decayTime = 0.1; float attackShape = 1.0, decayShape = 1.0; ADEnvelope() { }; void process(const float& sampleTime) { if (stage == STAGE_OFF) { env = envLinear = 0.0f; } else if (stage == STAGE_ATTACK) { envLinear += sampleTime / attackTime; env = std::pow(envLinear, attackShape); } else if (stage == STAGE_DECAY) { envLinear -= sampleTime / decayTime; env = std::pow(envLinear, decayShape); } if (envLinear >= 1.0f) { stage = STAGE_DECAY; env = envLinear = 1.0f; } else if (envLinear <= 0.0f) { stage = STAGE_OFF; env = envLinear = 0.0f; } } void trigger() { stage = ADEnvelope::STAGE_ATTACK; // non-linear envelopes won't retrigger at the correct starting point if // attackShape != decayShape, so we advance the linear envelope envLinear = std::pow(env, 1.0f / attackShape); } private: float envLinear = 0.f; };