diff --git a/plugin.json b/plugin.json index cd07939..1dad1e8 100644 --- a/plugin.json +++ b/plugin.json @@ -13,7 +13,8 @@ "slug": "EvenVCO", "name": "EvenVCO", "tags": [ - "VCO" + "VCO", + "Polyphonic" ] }, { diff --git a/src/ABC.cpp b/src/ABC.cpp index 2d02464..680f504 100644 --- a/src/ABC.cpp +++ b/src/ABC.cpp @@ -3,7 +3,7 @@ #define MAX(a,b) (a>b)?a:b - +/* static float clip(float x) { // Pade approximant of x/(1 + x^12)^(1/12) const float limit = 1.16691853009184; @@ -11,6 +11,7 @@ static float clip(float x) { 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 simd::float_4 clip4(simd::float_4 x) { // Pade approximant of x/(1 + x^12)^(1/12) @@ -61,13 +62,11 @@ struct ABC : Module { NUM_OUTPUTS }; enum LightIds { - ENUMS(OUT1_LIGHT, 2), - ENUMS(OUT2_LIGHT, 2), + ENUMS(OUT1_LIGHT, 3), + ENUMS(OUT2_LIGHT, 3), NUM_LIGHTS }; - // simd::float_4 mask[4]; - ChannelMask channelMask; @@ -77,16 +76,6 @@ struct ABC : Module { configParam(C1_LEVEL_PARAM, -1.0, 1.0, 0.0, "C1 Level"); configParam(B2_LEVEL_PARAM, -1.0, 1.0, 0.0, "B2 Level"); configParam(C2_LEVEL_PARAM, -1.0, 1.0, 0.0, "C2 Level"); - -/* - __m128i tmp = _mm_cmpeq_epi16(_mm_set_epi32(0,0,0,0),_mm_set_epi32(0,0,0,0)); - - for(int i=0; i<4; i++) { - mask[3-i] = simd::float_4(_mm_castsi128_ps(tmp)); - tmp = _mm_srli_si128(tmp, 4); - } -*/ - } @@ -104,76 +93,84 @@ struct ABC : Module { simd::float_4 c2[4]; simd::float_4 out2[4]; - int channels_A1 = inputs[A1_INPUT].getChannels(); - int channels_A2 = inputs[A2_INPUT].getChannels(); + int channels_1 = 1; + int channels_2 = 1; - int channels_B1 = inputs[B1_INPUT].getChannels(); - int channels_B2 = inputs[B2_INPUT].getChannels(); - int channels_C1 = inputs[C1_INPUT].getChannels(); - int channels_C2 = inputs[C2_INPUT].getChannels(); - int channels_1 = 1; - channels_1 = MAX(channels_1, channels_A1); - channels_1 = MAX(channels_1, channels_B1); - channels_1 = MAX(channels_1, channels_C1); + // process upper section - int channels_2 = 1; - channels_2 = MAX(channels_2, channels_A2); - channels_2 = MAX(channels_2, channels_B2); - channels_2 = MAX(channels_2, channels_C2); + if(outputs[OUT1_OUTPUT].isConnected() || outputs[OUT2_OUTPUT].isConnected() ) { - float mult_B1 = (2.f/5.f)*exponentialBipolar80Pade_5_4(params[B1_LEVEL_PARAM].getValue()); - float mult_C1 = exponentialBipolar80Pade_5_4(params[C1_LEVEL_PARAM].getValue()); + int channels_A1 = inputs[A1_INPUT].getChannels(); + int channels_B1 = inputs[B1_INPUT].getChannels(); + int channels_C1 = inputs[C1_INPUT].getChannels(); - float mult_B2 = (2.f/5.f)*exponentialBipolar80Pade_5_4(params[B2_LEVEL_PARAM].getValue()); - float mult_C2 = exponentialBipolar80Pade_5_4(params[C2_LEVEL_PARAM].getValue()); + channels_1 = MAX(channels_1, channels_A1); + channels_1 = MAX(channels_1, channels_B1); + channels_1 = MAX(channels_1, channels_C1); + float mult_B1 = (2.f/5.f)*exponentialBipolar80Pade_5_4(params[B1_LEVEL_PARAM].getValue()); + float mult_C1 = exponentialBipolar80Pade_5_4(params[C1_LEVEL_PARAM].getValue()); - load_input(inputs[A1_INPUT], a1, channels_A1); - channelMask.apply(a1, channels_1); + load_input(inputs[A1_INPUT], a1, channels_A1); + channelMask.apply(a1, channels_1); - if(inputs[B1_INPUT].isConnected()) { - load_input(inputs[B1_INPUT], b1, channels_B1); - for(int c=0; c(Vec(7, 279), module, ABC::C2_INPUT)); addOutput(createOutput(Vec(7, 321), module, ABC::OUT2_OUTPUT)); - addChild(createLight>(Vec(37, 162), module, ABC::OUT1_LIGHT)); - addChild(createLight>(Vec(37, 329), module, ABC::OUT2_LIGHT)); + addChild(createLight>(Vec(37, 162), module, ABC::OUT1_LIGHT)); + addChild(createLight>(Vec(37, 329), module, ABC::OUT2_LIGHT)); } }; diff --git a/src/DualAtenuverter.cpp b/src/DualAtenuverter.cpp index 08ae9e6..987c690 100644 --- a/src/DualAtenuverter.cpp +++ b/src/DualAtenuverter.cpp @@ -21,10 +21,8 @@ struct DualAtenuverter : Module { NUM_OUTPUTS }; enum LightIds { - OUT1_POS_LIGHT, - OUT1_NEG_LIGHT, - OUT2_POS_LIGHT, - OUT2_NEG_LIGHT, + ENUMS(OUT1_LIGHT, 3), + ENUMS(OUT2_LIGHT, 3), NUM_LIGHTS }; @@ -62,10 +60,28 @@ struct DualAtenuverter : Module { float light1 = outputs[OUT1_OUTPUT].getVoltageSum()/channels1; float light2 = outputs[OUT2_OUTPUT].getVoltageSum()/channels2; - lights[OUT1_POS_LIGHT].setSmoothBrightness(light1 / 5.f, args.sampleTime); - lights[OUT1_NEG_LIGHT].setSmoothBrightness(-light1 / 5.f, args.sampleTime); - lights[OUT2_POS_LIGHT].setSmoothBrightness(light2 / 5.f, args.sampleTime); - lights[OUT2_NEG_LIGHT].setSmoothBrightness(-light2 / 5.f, args.sampleTime); + if(channels1==1) { + lights[OUT1_LIGHT ].setSmoothBrightness(light1 / 5.f, args.sampleTime); + lights[OUT1_LIGHT+1].setSmoothBrightness(-light1 / 5.f, args.sampleTime); + lights[OUT1_LIGHT+2].setBrightness(0.0f); + } else { + lights[OUT1_LIGHT ].setBrightness(0.0f); + lights[OUT1_LIGHT+1].setBrightness(0.0f); + lights[OUT1_LIGHT+2].setBrightness(10.0f); + } + + if(channels2==1) { + lights[OUT2_LIGHT ].setSmoothBrightness(light2 / 5.f, args.sampleTime); + lights[OUT2_LIGHT+1].setSmoothBrightness(-light2 / 5.f, args.sampleTime); + lights[OUT2_LIGHT+2].setBrightness(0.0f); + } else { + lights[OUT2_LIGHT ].setBrightness(0.0f); + lights[OUT2_LIGHT+1].setBrightness(0.0f); + lights[OUT2_LIGHT+2].setBrightness(10.0f); + } + + + } }; @@ -89,8 +105,8 @@ struct DualAtenuverterWidget : ModuleWidget { addInput(createInput(Vec(7, 319), module, DualAtenuverter::IN2_INPUT)); addOutput(createOutput(Vec(43, 319), module, DualAtenuverter::OUT2_OUTPUT)); - addChild(createLight>(Vec(33, 143), module, DualAtenuverter::OUT1_POS_LIGHT)); - addChild(createLight>(Vec(33, 311), module, DualAtenuverter::OUT2_POS_LIGHT)); + addChild(createLight>(Vec(33, 143), module, DualAtenuverter::OUT1_LIGHT)); + addChild(createLight>(Vec(33, 311), module, DualAtenuverter::OUT2_LIGHT)); } }; diff --git a/src/EvenVCO.cpp b/src/EvenVCO.cpp index d3ac1a5..8850914 100644 --- a/src/EvenVCO.cpp +++ b/src/EvenVCO.cpp @@ -60,24 +60,6 @@ struct EvenVCO : Module { for(int c=0; c simd::float_4::zero()); @@ -23,7 +23,7 @@ struct PulseGenerator_4 { } /** Begins a trigger with the given `duration`. */ - void trigger(simd::float_4 mask, float duration = 1e-3f) { + inline void trigger(simd::float_4 mask, float duration = 1e-3f) { // Keep the previous pulse if the existing pulse will be held longer than the currently requested one. simd::float_4 duration_4 = simd::float_4(duration); remaining = ifelse( mask&(duration_4>remaining), duration_4, remaining); diff --git a/src/Rampage.cpp b/src/Rampage.cpp index a51ff0a..ecd4435 100644 --- a/src/Rampage.cpp +++ b/src/Rampage.cpp @@ -64,15 +64,15 @@ struct Rampage : Module { NUM_OUTPUTS }; enum LightIds { - COMPARATOR_LIGHT, - MIN_LIGHT, - MAX_LIGHT, - OUT_A_LIGHT, - OUT_B_LIGHT, - RISING_A_LIGHT, - RISING_B_LIGHT, - FALLING_A_LIGHT, - FALLING_B_LIGHT, + ENUMS(COMPARATOR_LIGHT, 3), + ENUMS(MIN_LIGHT, 3), + ENUMS(MAX_LIGHT, 3), + ENUMS(OUT_A_LIGHT, 3), + ENUMS(OUT_B_LIGHT, 3), + ENUMS(RISING_A_LIGHT, 3), + ENUMS(RISING_B_LIGHT, 3), + ENUMS(FALLING_A_LIGHT, 3), + ENUMS(FALLING_B_LIGHT, 3), NUM_LIGHTS }; @@ -118,11 +118,11 @@ struct Rampage : Module { // determine number of channels: for (int part=0; part<2; part++) { - int tmp = inputs[IN_A_INPUT+part].getChannels(); - channels_in[part] = MAX(1,tmp); - tmp = inputs[TRIGG_A_INPUT+part].getChannels(); - channels_trig[part] = MAX(1,tmp); + + channels_in[part] = inputs[IN_A_INPUT+part].getChannels(); + channels_trig[part] = inputs[TRIGG_A_INPUT+part].getChannels(); channels[part] = MAX(channels_in[part], channels_trig[part]); + channels[part] = MAX(1, channels[part]); outputs[OUT_A_OUTPUT+part].setChannels(channels[part]); outputs[RISING_A_OUTPUT+part].setChannels(channels[part]); @@ -131,16 +131,22 @@ struct Rampage : Module { } int channels_max = MAX(channels[0], channels[1]); + outputs[COMPARATOR_OUTPUT].setChannels(channels_max); + outputs[MIN_OUTPUT].setChannels(channels_max); + outputs[MAX_OUTPUT].setChannels(channels_max); + // loop over two parts of Rampage: for (int part = 0; part < 2; part++) { simd::float_4 in[4]; simd::float_4 in_trig[4]; - simd::float_4 expCV[4] = {}; - simd::float_4 riseCV[4] = {}; - simd::float_4 fallCV[4] = {}; - simd::float_4 cycle[4] = {}; + simd::float_4 expCV[4]; + simd::float_4 riseCV[4]; + simd::float_4 fallCV[4]; + simd::float_4 cycle[4]; + + // get parameters: float shape = params[SHAPE_A_PARAM + part].getValue(); float minTime; @@ -150,11 +156,22 @@ struct Rampage : Module { default: minTime = 1e-1; break; } - simd::float_4 param_rise = simd::float_4(params[RISE_A_PARAM + part].getValue()); - simd::float_4 param_fall = simd::float_4(params[FALL_A_PARAM + part].getValue()); - simd::float_4 param_trig = simd::float_4(params[TRIGG_A_PARAM + part].getValue() * 10.0f); + simd::float_4 param_rise = simd::float_4(params[RISE_A_PARAM + part].getValue() * 10.0f); + simd::float_4 param_fall = simd::float_4(params[FALL_A_PARAM + part].getValue() * 10.0f); + simd::float_4 param_trig = simd::float_4(params[TRIGG_A_PARAM + part].getValue() * 20.0f); simd::float_4 param_cycle = simd::float_4(params[CYCLE_A_PARAM + part].getValue() * 10.0f); + for(int c=0; c simd::float_4::zero(); simd::float_4 delta_lt_0 = delta < simd::float_4::zero(); simd::float_4 delta_eq_0 = ~(delta_lt_0|delta_gt_0); simd::float_4 rateCV = ifelse(delta_gt_0, riseCV[c/4], simd::float_4::zero()); rateCV = ifelse(delta_lt_0, fallCV[c/4], rateCV); - rateCV = clamp(rateCV, simd::float_4::zero(), simd::float_4(1.0f)); + rateCV = clamp(rateCV, simd::float_4::zero(), simd::float_4(10.0f)); - simd::float_4 rate = minTime * simd::pow(2.0f, rateCV * 10.0f); + simd::float_4 rate = minTime * simd::pow(2.0f, rateCV); out[part][c/4] += shapeDelta(delta, rate, shape) * args.sampleTime; @@ -249,14 +251,25 @@ struct Rampage : Module { } // for(int c, ...) if(channels[part] == 1) { - lights[RISING_A_LIGHT + part].setSmoothBrightness(outputs[RISING_A_OUTPUT+part].getVoltage()/10.f, args.sampleTime); - lights[FALLING_A_LIGHT + part].setSmoothBrightness(outputs[FALLING_A_OUTPUT+part].getVoltage()/10.f, args.sampleTime); - lights[OUT_A_LIGHT + part].setSmoothBrightness(out[part][0].s[0] / 10.0, args.sampleTime); + lights[RISING_A_LIGHT + 3*part ].setSmoothBrightness(outputs[RISING_A_OUTPUT+part].getVoltage()/10.f, args.sampleTime); + lights[RISING_A_LIGHT + 3*part+1].setBrightness(0.0f); + lights[RISING_A_LIGHT + 3*part+2].setBrightness(0.0f); + lights[FALLING_A_LIGHT + 3*part ].setSmoothBrightness(outputs[FALLING_A_OUTPUT+part].getVoltage()/10.f, args.sampleTime); + lights[FALLING_A_LIGHT + 3*part+1].setBrightness(0.0f); + lights[FALLING_A_LIGHT + 3*part+2].setBrightness(0.0f); + lights[OUT_A_LIGHT + 3*part ].setSmoothBrightness(out[part][0].s[0] / 10.0, args.sampleTime); + lights[OUT_A_LIGHT + 3*part+1].setBrightness(0.0f); + lights[OUT_A_LIGHT + 3*part+2].setBrightness(0.0f); } else { - lights[RISING_A_LIGHT + part].setSmoothBrightness(outputs[RISING_A_OUTPUT+part].getVoltageSum()/10.f, args.sampleTime); - lights[FALLING_A_LIGHT + part].setSmoothBrightness(outputs[FALLING_A_OUTPUT+part].getVoltageSum()/10.f, args.sampleTime); - lights[OUT_A_LIGHT + part].setSmoothBrightness(outputs[OUT_A_OUTPUT].getVoltageSum() / 10.0, args.sampleTime); - + lights[RISING_A_LIGHT + 3*part ].setBrightness(0.0f); + lights[RISING_A_LIGHT + 3*part+1].setBrightness(0.0f); + lights[RISING_A_LIGHT + 3*part+2].setBrightness(10.0f); + lights[FALLING_A_LIGHT + 3*part ].setBrightness(0.0f); + lights[FALLING_A_LIGHT + 3*part+1].setBrightness(0.0f); + lights[FALLING_A_LIGHT + 3*part+2].setBrightness(10.0f); + lights[OUT_A_LIGHT + 3*part ].setBrightness(0.0f); + lights[OUT_A_LIGHT + 3*part+1].setBrightness(0.0f); + lights[OUT_A_LIGHT + 3*part+2].setBrightness(10.0f); } // Integrator @@ -323,9 +336,9 @@ struct Rampage : Module { simd::float_4 b = out[1][c/4]; if (balance < 0.5) - b *= 2.0 * balance; + b *= 2.0f * balance; else if (balance > 0.5) - a *= 2.0 * (1.0 - balance); + a *= 2.0f * (1.0 - balance); simd::float_4 comp = ifelse( b>a, simd::float_4(10.0f), simd::float_4::zero() ); simd::float_4 out_min = simd::fmin(a,b); @@ -337,9 +350,27 @@ struct Rampage : Module { } // Lights - lights[COMPARATOR_LIGHT].setSmoothBrightness(outputs[COMPARATOR_OUTPUT].getVoltageSum() / 10.0, args.sampleTime); - lights[MIN_LIGHT].setSmoothBrightness(outputs[MIN_OUTPUT].getVoltageSum() / 10.0, args.sampleTime); - lights[MAX_LIGHT].setSmoothBrightness(outputs[MAX_OUTPUT].getVoltageSum() / 10.0, args.sampleTime); + if(channels_max==1) { + lights[COMPARATOR_LIGHT ].setSmoothBrightness(outputs[COMPARATOR_OUTPUT].getVoltage(), args.sampleTime); + lights[COMPARATOR_LIGHT+1].setBrightness(0.0f); + lights[COMPARATOR_LIGHT+2].setBrightness(0.0f); + lights[MIN_LIGHT ].setSmoothBrightness(outputs[MIN_OUTPUT].getVoltage(), args.sampleTime); + lights[MIN_LIGHT+1].setBrightness(0.0f); + lights[MIN_LIGHT+2].setBrightness(0.0f); + lights[MAX_LIGHT ].setSmoothBrightness(outputs[MAX_OUTPUT].getVoltage(), args.sampleTime); + lights[MAX_LIGHT+1].setBrightness(0.0f); + lights[MAX_LIGHT+2].setBrightness(0.0f); + } else { + lights[COMPARATOR_LIGHT ].setBrightness(0.0f); + lights[COMPARATOR_LIGHT+1].setBrightness(0.0f); + lights[COMPARATOR_LIGHT+2].setBrightness(10.0f); + lights[MIN_LIGHT ].setBrightness(0.0f); + lights[MIN_LIGHT+1].setBrightness(0.0f); + lights[MIN_LIGHT+2].setBrightness(10.0f); + lights[MAX_LIGHT ].setBrightness(0.0f); + lights[MAX_LIGHT+1].setBrightness(0.0f); + lights[MAX_LIGHT+2].setBrightness(10.0f); + } } // end process() }; @@ -377,7 +408,7 @@ struct RampageWidget : ModuleWidget { addInput(createInput(Vec(67, 268), module, Rampage::FALL_CV_A_INPUT)); addInput(createInput(Vec(38, 297), module, Rampage::EXP_CV_A_INPUT)); addInput(createInput(Vec(102, 290), module, Rampage::CYCLE_A_INPUT)); - addInput(createInput(Vec(229, 30), module, Rampage::IN_B_INPUT)); + addInput(createInput(Vec(229, 30), module, Rampage::IN_B_INPUT)); addInput(createInput(Vec(192, 37), module, Rampage::TRIGG_B_INPUT)); addInput(createInput(Vec(176, 268), module, Rampage::RISE_CV_B_INPUT)); addInput(createInput(Vec(237, 268), module, Rampage::FALL_CV_B_INPUT)); @@ -396,15 +427,15 @@ struct RampageWidget : ModuleWidget { addOutput(createOutput(Vec(89, 157), module, Rampage::MIN_OUTPUT)); addOutput(createOutput(Vec(155, 157), module, Rampage::MAX_OUTPUT)); - addChild(createLight>(Vec(132, 167), module, Rampage::COMPARATOR_LIGHT)); - addChild(createLight>(Vec(123, 174), module, Rampage::MIN_LIGHT)); - addChild(createLight>(Vec(141, 174), module, Rampage::MAX_LIGHT)); - addChild(createLight>(Vec(126, 185), module, Rampage::OUT_A_LIGHT)); - addChild(createLight>(Vec(138, 185), module, Rampage::OUT_B_LIGHT)); - addChild(createLight>(Vec(18, 312), module, Rampage::RISING_A_LIGHT)); - addChild(createLight>(Vec(78, 312), module, Rampage::FALLING_A_LIGHT)); - addChild(createLight>(Vec(187, 312), module, Rampage::RISING_B_LIGHT)); - addChild(createLight>(Vec(247, 312), module, Rampage::FALLING_B_LIGHT)); + addChild(createLight>(Vec(132, 167), module, Rampage::COMPARATOR_LIGHT)); + addChild(createLight>(Vec(123, 174), module, Rampage::MIN_LIGHT)); + addChild(createLight>(Vec(141, 174), module, Rampage::MAX_LIGHT)); + addChild(createLight>(Vec(126, 185), module, Rampage::OUT_A_LIGHT)); + addChild(createLight>(Vec(138, 185), module, Rampage::OUT_B_LIGHT)); + addChild(createLight>(Vec(18, 312), module, Rampage::RISING_A_LIGHT)); + addChild(createLight>(Vec(78, 312), module, Rampage::FALLING_A_LIGHT)); + addChild(createLight>(Vec(187, 312), module, Rampage::RISING_B_LIGHT)); + addChild(createLight>(Vec(247, 312), module, Rampage::FALLING_B_LIGHT)); } }; diff --git a/src/simd_mask.hpp b/src/simd_mask.hpp index 94924c8..158a3ce 100644 --- a/src/simd_mask.hpp +++ b/src/simd_mask.hpp @@ -37,18 +37,20 @@ struct ChannelMask { }; inline void load_input(Input &in, simd::float_4 *v, int numChannels) { - if(numChannels==1) { - for(int i=0; i<4; i++) v[i] = simd::float_4(in.getVoltage()); + int inChannels = in.getChannels(); + if(inChannels==1) { + for(int i=0; i