Browse Source

Polyphony finished

Signed-off-by: hemmer <915048+hemmer@users.noreply.github.com>
tags/v1.1.0^2
Martin hemmer 5 years ago
parent
commit
0cb2d2e6bd
7 changed files with 227 additions and 189 deletions
  1. +2
    -1
      plugin.json
  2. +81
    -75
      src/ABC.cpp
  3. +26
    -10
      src/DualAtenuverter.cpp
  4. +0
    -18
      src/EvenVCO.cpp
  5. +2
    -2
      src/PulseGenerator_4.hpp
  6. +108
    -77
      src/Rampage.cpp
  7. +8
    -6
      src/simd_mask.hpp

+ 2
- 1
plugin.json View File

@@ -13,7 +13,8 @@
"slug": "EvenVCO",
"name": "EvenVCO",
"tags": [
"VCO"
"VCO",
"Polyphonic"
]
},
{


+ 81
- 75
src/ABC.cpp View File

@@ -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<channels_1; c+=4) b1[c/4] = b1[c/4] * simd::float_4(mult_B1);
} else {
for(int c=0; c<channels_1; c+=4) b1[c/4] = simd::float_4(5.f*mult_B1);
}
channelMask.apply(b1, channels_1);
if(inputs[B1_INPUT].isConnected()) {
load_input(inputs[B1_INPUT], b1, channels_B1);
for(int c=0; c<channels_1; c+=4) b1[c/4] *= simd::float_4(mult_B1);
} else {
for(int c=0; c<channels_1; c+=4) b1[c/4] = simd::float_4(5.f*mult_B1);
}
channelMask.apply(b1, channels_1);

if(inputs[C1_INPUT].isConnected()) {
load_input(inputs[C1_INPUT], c1, channels_C1);
for(int c=0; c<channels_1; c+=4) c1[c/4] = c1[c/4] * simd::float_4(mult_C1);
} else {
for(int c=0; c<channels_1; c+=4) c1[c/4] = simd::float_4(10.f*mult_C1);
if(inputs[C1_INPUT].isConnected()) {
load_input(inputs[C1_INPUT], c1, channels_C1);
for(int c=0; c<channels_1; c+=4) c1[c/4] *= simd::float_4(mult_C1);
} else {
for(int c=0; c<channels_1; c+=4) c1[c/4] = simd::float_4(10.f*mult_C1);
}
channelMask.apply(c1, channels_1);

for(int c=0; c<channels_1; c+=4) out1[c/4] = clip4(a1[c/4] * b1[c/4] + c1[c/4]);
}
channelMask.apply(c1, channels_1);

for(int c=0; c<channels_1; c+=4) out1[c/4] = clip4(a1[c/4] * b1[c/4] + c1[c/4]);
// process lower section

if(outputs[OUT2_OUTPUT].isConnected()) {

int channels_A2 = inputs[A2_INPUT].getChannels();
int channels_B2 = inputs[B2_INPUT].getChannels();
int channels_C2 = inputs[C2_INPUT].getChannels();

load_input(inputs[A2_INPUT], a2, channels_A2);
channelMask.apply(a2, channels_2);
channels_2 = MAX(channels_2, channels_A2);
channels_2 = MAX(channels_2, channels_B2);
channels_2 = MAX(channels_2, channels_C2);

if(inputs[B2_INPUT].isConnected()) {
load_input(inputs[B2_INPUT], b2, channels_B2);
for(int c=0; c<channels_2; c+=4) b2[c/4] = b2[c/4] * simd::float_4(mult_B2);
} else {
for(int c=0; c<channels_2; c+=4) b2[c/4] = simd::float_4(5.f*mult_B2);
}
channelMask.apply(b2, channels_2);
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());

if(inputs[C2_INPUT].isConnected()) {
load_input(inputs[C2_INPUT], c2, channels_C2);
for(int c=0; c<channels_2; c+=4) c2[c/4] = c2[c/4] * simd::float_4(mult_C2);
} else {
for(int c=0; c<channels_2; c+=4) c2[c/4] = simd::float_4(10.f*mult_C2);
}
channelMask.apply(c2, channels_2);
load_input(inputs[A2_INPUT], a2, channels_A2);
channelMask.apply(a2, channels_2);

if(inputs[B2_INPUT].isConnected()) {
load_input(inputs[B2_INPUT], b2, channels_B2);
for(int c=0; c<channels_2; c+=4) b2[c/4] *= simd::float_4(mult_B2);
} else {
for(int c=0; c<channels_2; c+=4) b2[c/4] = simd::float_4(5.f*mult_B2);
}
channelMask.apply(b2, channels_2);

for(int c=0; c<channels_2; c+=4) out2[c/4] = clip4(a2[c/4] * b2[c/4] + c2[c/4]);
if(inputs[C2_INPUT].isConnected()) {
load_input(inputs[C2_INPUT], c2, channels_C2);
for(int c=0; c<channels_2; c+=4) c2[c/4] *= simd::float_4(mult_C2);
} else {
for(int c=0; c<channels_2; c+=4) c2[c/4] = simd::float_4(10.f*mult_C2);
}
channelMask.apply(c2, channels_2);

for(int c=0; c<channels_2; c+=4) out2[c/4] = clip4(a2[c/4] * b2[c/4] + c2[c/4]);
};


// Set outputs
@@ -184,8 +181,8 @@ struct ABC : Module {
else {
for(int c=0; c<channels_1; c+=4) out2[c/4] += out1[c/4];
channels_2 = MAX(channels_1, channels_2);

}

if (outputs[OUT2_OUTPUT].isConnected()) {
outputs[OUT2_OUTPUT].setChannels(channels_2);
for(int c=0; c<channels_2; c+=4) out2[c/4].store(outputs[OUT2_OUTPUT].getVoltages(c));
@@ -198,19 +195,28 @@ struct ABC : Module {

if(channels_1==1) {
light_1 = out1[0].s[0];
lights[OUT1_LIGHT + 0].setSmoothBrightness(light_1 / 5.f, args.sampleTime);
lights[OUT1_LIGHT + 1].setSmoothBrightness(-light_1 / 5.f, args.sampleTime);
lights[OUT1_LIGHT + 2].setBrightness(0.f);
} else {
light_1 = outputs[OUT1_OUTPUT].getVoltageSum();
light_1 = 10.f;
lights[OUT1_LIGHT + 0].setBrightness(0.0f);
lights[OUT1_LIGHT + 1].setBrightness(0.0f);
lights[OUT1_LIGHT + 2].setBrightness(light_1);
}
lights[OUT1_LIGHT + 0].setSmoothBrightness(light_1 / 5.f, args.sampleTime);
lights[OUT1_LIGHT + 1].setSmoothBrightness(-light_1 / 5.f, args.sampleTime);

if(channels_2==1) {
light_2 = out2[0].s[0];
lights[OUT2_LIGHT + 0].setSmoothBrightness(light_2 / 5.f, args.sampleTime);
lights[OUT2_LIGHT + 1].setSmoothBrightness(-light_2 / 5.f, args.sampleTime);
lights[OUT2_LIGHT + 2].setBrightness(0.f);
} else {
light_2 = outputs[OUT2_OUTPUT].getVoltageSum();
light_2 = 10.f;
lights[OUT2_LIGHT + 0].setBrightness(0.0f);
lights[OUT2_LIGHT + 1].setBrightness(0.0f);
lights[OUT2_LIGHT + 2].setBrightness(light_2);
}
lights[OUT2_LIGHT + 0].setSmoothBrightness(light_2 / 5.f, args.sampleTime);
lights[OUT2_LIGHT + 1].setSmoothBrightness(-light_2 / 5.f, args.sampleTime);

}
};
@@ -238,8 +244,8 @@ struct ABCWidget : ModuleWidget {
addInput(createInput<PJ301MPort>(Vec(7, 279), module, ABC::C2_INPUT));
addOutput(createOutput<PJ301MPort>(Vec(7, 321), module, ABC::OUT2_OUTPUT));

addChild(createLight<MediumLight<GreenRedLight>>(Vec(37, 162), module, ABC::OUT1_LIGHT));
addChild(createLight<MediumLight<GreenRedLight>>(Vec(37, 329), module, ABC::OUT2_LIGHT));
addChild(createLight<MediumLight<RedGreenBlueLight>>(Vec(37, 162), module, ABC::OUT1_LIGHT));
addChild(createLight<MediumLight<RedGreenBlueLight>>(Vec(37, 329), module, ABC::OUT2_LIGHT));
}
};



+ 26
- 10
src/DualAtenuverter.cpp View File

@@ -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<PJ301MPort>(Vec(7, 319), module, DualAtenuverter::IN2_INPUT));
addOutput(createOutput<PJ301MPort>(Vec(43, 319), module, DualAtenuverter::OUT2_OUTPUT));

addChild(createLight<MediumLight<GreenRedLight>>(Vec(33, 143), module, DualAtenuverter::OUT1_POS_LIGHT));
addChild(createLight<MediumLight<GreenRedLight>>(Vec(33, 311), module, DualAtenuverter::OUT2_POS_LIGHT));
addChild(createLight<MediumLight<RedGreenBlueLight>>(Vec(33, 143), module, DualAtenuverter::OUT1_LIGHT));
addChild(createLight<MediumLight<RedGreenBlueLight>>(Vec(33, 311), module, DualAtenuverter::OUT2_LIGHT));
}
};



+ 0
- 18
src/EvenVCO.cpp View File

@@ -60,24 +60,6 @@ struct EvenVCO : Module {
for(int c=0; c<PORT_MAX_CHANNELS; c++) halfPhase[c] = false;
}

/*
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());
} else {
for(int c=0; c<numChannels; c+=4) v[c/4] = simd::float_4::load(in.getVoltages(c));
}
}
*/

inline void add_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());
} else {
for(int c=0; c<numChannels; c+=4) v[c/4] = simd::float_4::load(in.getVoltages(c));
}
}

void process(const ProcessArgs &args) override {

simd::float_4 pitch[4];


+ 2
- 2
src/PulseGenerator_4.hpp View File

@@ -14,7 +14,7 @@ struct PulseGenerator_4 {
}

/** Advances the state by `deltaTime`. Returns whether the pulse is in the HIGH state. */
simd::float_4 process(float deltaTime) {
inline simd::float_4 process(float deltaTime) {

simd::float_4 mask = (remaining > 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);


+ 108
- 77
src/Rampage.cpp View File

@@ -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<channels[part]; c+=4) {
riseCV[c/4] = param_rise;
fallCV[c/4] = param_fall;
cycle[c/4] = param_cycle;
in_trig[c/4] = param_trig;

}


// read inputs:

if(inputs[IN_A_INPUT + part].isConnected()) {
load_input(inputs[IN_A_INPUT + part], in, channels_in[part]);
channelMask.apply_all(in, channels_in[part]);
@@ -163,61 +180,46 @@ struct Rampage : Module {
}

if(inputs[TRIGG_A_INPUT + part].isConnected()) {
load_input(inputs[TRIGG_A_INPUT + part], in_trig, channels_trig[part]);
add_input(inputs[TRIGG_A_INPUT + part], in_trig, channels_trig[part]);
channelMask.apply_all(in_trig, channels_trig[part]);
} else {
memset(in_trig, 0, sizeof(in_trig));
}

for(int c=0; c<channels_trig[part]; c+=4) in_trig[c/4] = param_trig + in_trig[c/4]/2.0f;
channelMask.apply_all(in_trig, channels_trig[part] );
for(int c=0; c<channels[part]; c+=4) {
simd::float_4 trig_mask = trigger_4[part][c/4].process(in_trig[c/4]);
gate[part][c/4] = ifelse(trig_mask, simd::float_4::mask(), gate[part][c/4]);
in[c/4] = ifelse(gate[part][c/4], simd::float_4(10.0f), in[c/4]);
}
}

if(inputs[EXP_CV_A_INPUT + part].isConnected()) {
load_input(inputs[EXP_CV_A_INPUT + part], expCV, channels[part]);
for(int c=0; c<channels[part]; c+=4) riseCV[c/4] *= -1.0f;
for(int c=0; c<channels[part]; c+=4) {
riseCV[c/4] -= expCV[c/4];
fallCV[c/4] -= expCV[c/4];
}
}

load_input(inputs[RISE_CV_A_INPUT + part], riseCV, channels[part]);
for(int c=0; c<channels[part]; c+=4) {
riseCV[c/4] += expCV[c/4];
riseCV[c/4] *= 0.10f;
riseCV[c/4] += param_rise;
}
add_input(inputs[RISE_CV_A_INPUT + part], riseCV, channels[part]);
add_input(inputs[FALL_CV_A_INPUT + part], fallCV, channels[part]);
add_input(inputs[CYCLE_A_INPUT+part], cycle, channels[part]);
channelMask.apply(cycle, channels[part]); // check whether this is necessary

load_input(inputs[FALL_CV_A_INPUT + part], fallCV, channels[part]);
// start processing:
for(int c=0; c<channels[part]; c+=4) {
fallCV[c/4] += expCV[c/4];
fallCV[c/4] *= 0.10f;
fallCV[c/4] += param_fall;
}

load_input(inputs[CYCLE_A_INPUT], cycle, channels[part]);
// channelMask.apply_all(cycle, channels[part]);
for(int c=0; c<channels[part]; c+=4) {
cycle[c/4] += param_cycle;
}
channelMask.apply_all(cycle, channels[part]);
// process SchmittTriggers


for(int c=0; c<channels[part]; c+=4) {
simd::float_4 trig_mask = trigger_4[part][c/4].process(in_trig[c/4]/2.0);
gate[part][c/4] = ifelse(trig_mask, simd::float_4::mask(), gate[part][c/4]);
in[c/4] = ifelse(gate[part][c/4], simd::float_4(10.0f), in[c/4]);

simd::float_4 delta = in[c/4] - out[part][c/4];

// rise / fall branching

simd::float_4 delta_gt_0 = delta > 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<PJ301MPort>(Vec(67, 268), module, Rampage::FALL_CV_A_INPUT));
addInput(createInput<PJ301MPort>(Vec(38, 297), module, Rampage::EXP_CV_A_INPUT));
addInput(createInput<PJ301MPort>(Vec(102, 290), module, Rampage::CYCLE_A_INPUT));
addInput(createInput<PJ301MPort>(Vec(229, 30), module, Rampage::IN_B_INPUT));
addInput(createInput<PJ301MPort>(Vec(229, 30), module, Rampage::IN_B_INPUT));
addInput(createInput<PJ301MPort>(Vec(192, 37), module, Rampage::TRIGG_B_INPUT));
addInput(createInput<PJ301MPort>(Vec(176, 268), module, Rampage::RISE_CV_B_INPUT));
addInput(createInput<PJ301MPort>(Vec(237, 268), module, Rampage::FALL_CV_B_INPUT));
@@ -396,15 +427,15 @@ struct RampageWidget : ModuleWidget {
addOutput(createOutput<PJ301MPort>(Vec(89, 157), module, Rampage::MIN_OUTPUT));
addOutput(createOutput<PJ301MPort>(Vec(155, 157), module, Rampage::MAX_OUTPUT));

addChild(createLight<SmallLight<RedLight>>(Vec(132, 167), module, Rampage::COMPARATOR_LIGHT));
addChild(createLight<SmallLight<RedLight>>(Vec(123, 174), module, Rampage::MIN_LIGHT));
addChild(createLight<SmallLight<RedLight>>(Vec(141, 174), module, Rampage::MAX_LIGHT));
addChild(createLight<SmallLight<RedLight>>(Vec(126, 185), module, Rampage::OUT_A_LIGHT));
addChild(createLight<SmallLight<RedLight>>(Vec(138, 185), module, Rampage::OUT_B_LIGHT));
addChild(createLight<SmallLight<RedLight>>(Vec(18, 312), module, Rampage::RISING_A_LIGHT));
addChild(createLight<SmallLight<RedLight>>(Vec(78, 312), module, Rampage::FALLING_A_LIGHT));
addChild(createLight<SmallLight<RedLight>>(Vec(187, 312), module, Rampage::RISING_B_LIGHT));
addChild(createLight<SmallLight<RedLight>>(Vec(247, 312), module, Rampage::FALLING_B_LIGHT));
addChild(createLight<SmallLight<RedGreenBlueLight>>(Vec(132, 167), module, Rampage::COMPARATOR_LIGHT));
addChild(createLight<SmallLight<RedGreenBlueLight>>(Vec(123, 174), module, Rampage::MIN_LIGHT));
addChild(createLight<SmallLight<RedGreenBlueLight>>(Vec(141, 174), module, Rampage::MAX_LIGHT));
addChild(createLight<SmallLight<RedGreenBlueLight>>(Vec(126, 185), module, Rampage::OUT_A_LIGHT));
addChild(createLight<SmallLight<RedGreenBlueLight>>(Vec(138, 185), module, Rampage::OUT_B_LIGHT));
addChild(createLight<SmallLight<RedGreenBlueLight>>(Vec(18, 312), module, Rampage::RISING_A_LIGHT));
addChild(createLight<SmallLight<RedGreenBlueLight>>(Vec(78, 312), module, Rampage::FALLING_A_LIGHT));
addChild(createLight<SmallLight<RedGreenBlueLight>>(Vec(187, 312), module, Rampage::RISING_B_LIGHT));
addChild(createLight<SmallLight<RedGreenBlueLight>>(Vec(247, 312), module, Rampage::FALLING_B_LIGHT));
}
};



+ 8
- 6
src/simd_mask.hpp View File

@@ -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<numChannels; i++) v[i] = simd::float_4(in.getVoltage());
} else {
for(int c=0; c<numChannels; c+=4) v[c/4] = simd::float_4::load(in.getVoltages(c));
for(int c=0; c<inChannels; c+=4) v[c/4] = simd::float_4::load(in.getVoltages(c));
}
}

inline void add_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<numChannels; i++) v[i] += simd::float_4(in.getVoltage());
} else {
for(int c=0; c<numChannels; c+=4) v[c/4] += simd::float_4::load(in.getVoltages(c));
for(int c=0; c<inChannels; c+=4) v[c/4] += simd::float_4::load(in.getVoltages(c));
}
}



Loading…
Cancel
Save