@@ -22,5 +22,5 @@ void init(rack::Plugin *p) { | |||
createModel<BranchesWidget>(plugin, "Branches", "Bernoulli Gate"); | |||
createModel<BlindsWidget>(plugin, "Blinds", "Quad VC-polarizer"); | |||
createModel<VeilsWidget>(plugin, "Veils", "Quad VCA"); | |||
createModel<FramesWidget>(plugin, "Frames", "Keyframer"); | |||
// createModel<FramesWidget>(plugin, "Frames", "Keyframer"); | |||
} |
@@ -36,50 +36,44 @@ struct Blinds : Module { | |||
float lights[4] = {}; | |||
float gainLights[4] = {}; | |||
Blinds(); | |||
Blinds() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
void step(); | |||
}; | |||
Blinds::Blinds() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
} | |||
static float getChannelOutput(const float *in, float gain, const float *cv, float mod, float *light) { | |||
gain += mod * fmaxf(getf(cv) / 5.0, 0.0); | |||
*light = gain * 5.0; | |||
return gain * getf(in, 5.0); | |||
static float processChannel(Input &in, Param &gain, Input &cv, Param &mod, float *light) { | |||
float g = gain.value + mod.value * cv.value / 5.0; | |||
*light = g * 5.0; | |||
return g * in.normalize(5.0); | |||
} | |||
void Blinds::step() { | |||
float out = 0.0; | |||
out += getChannelOutput(inputs[IN1_INPUT], params[GAIN1_PARAM], inputs[CV1_INPUT], params[MOD1_PARAM], &gainLights[0]); | |||
out += processChannel(inputs[IN1_INPUT], params[GAIN1_PARAM], inputs[CV1_INPUT], params[MOD1_PARAM], &gainLights[0]); | |||
lights[0] = out; | |||
if (outputs[OUT1_OUTPUT]) { | |||
*outputs[OUT1_OUTPUT] = out; | |||
if (outputs[OUT1_OUTPUT].active) { | |||
outputs[OUT1_OUTPUT].value = out; | |||
out = 0.0; | |||
} | |||
out += getChannelOutput(inputs[IN2_INPUT], params[GAIN2_PARAM], inputs[CV2_INPUT], params[MOD2_PARAM], &gainLights[1]); | |||
out += processChannel(inputs[IN2_INPUT], params[GAIN2_PARAM], inputs[CV2_INPUT], params[MOD2_PARAM], &gainLights[1]); | |||
lights[1] = out; | |||
if (outputs[OUT2_OUTPUT]) { | |||
*outputs[OUT2_OUTPUT] = out; | |||
if (outputs[OUT2_OUTPUT].active) { | |||
outputs[OUT2_OUTPUT].value = out; | |||
out = 0.0; | |||
} | |||
out += getChannelOutput(inputs[IN3_INPUT], params[GAIN3_PARAM], inputs[CV3_INPUT], params[MOD3_PARAM], &gainLights[2]); | |||
out += processChannel(inputs[IN3_INPUT], params[GAIN3_PARAM], inputs[CV3_INPUT], params[MOD3_PARAM], &gainLights[2]); | |||
lights[2] = out; | |||
if (outputs[OUT3_OUTPUT]) { | |||
*outputs[OUT3_OUTPUT] = out; | |||
if (outputs[OUT3_OUTPUT].active) { | |||
outputs[OUT3_OUTPUT].value = out; | |||
out = 0.0; | |||
} | |||
out += getChannelOutput(inputs[IN4_INPUT], params[GAIN4_PARAM], inputs[CV4_INPUT], params[MOD4_PARAM], &gainLights[3]); | |||
out += processChannel(inputs[IN4_INPUT], params[GAIN4_PARAM], inputs[CV4_INPUT], params[MOD4_PARAM], &gainLights[3]); | |||
lights[3] = out; | |||
if (outputs[OUT4_OUTPUT]) { | |||
*outputs[OUT4_OUTPUT] = out; | |||
if (outputs[OUT4_OUTPUT].active) { | |||
outputs[OUT4_OUTPUT].value = out; | |||
} | |||
} | |||
@@ -69,11 +69,7 @@ struct Braids : Module { | |||
}; | |||
Braids::Braids() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
Braids::Braids() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { | |||
memset(&osc, 0, sizeof(osc)); | |||
osc.Init(); | |||
memset(&jitter_source, 0, sizeof(jitter_source)); | |||
@@ -90,7 +86,7 @@ Braids::Braids() { | |||
void Braids::step() { | |||
// Trigger | |||
bool trig = getf(inputs[TRIG_INPUT]) >= 1.0; | |||
bool trig = inputs[TRIG_INPUT].value >= 1.0; | |||
if (!lastTrig && trig) { | |||
osc.Strike(); | |||
} | |||
@@ -98,10 +94,10 @@ void Braids::step() { | |||
// Render frames | |||
if (outputBuffer.empty()) { | |||
float fm = params[FM_PARAM] * getf(inputs[FM_INPUT]); | |||
float fm = params[FM_PARAM].value * inputs[FM_INPUT].value; | |||
// Set shape | |||
int shape = roundf(params[SHAPE_PARAM] * braids::MACRO_OSC_SHAPE_LAST_ACCESSIBLE_FROM_META); | |||
int shape = roundf(params[SHAPE_PARAM].value * braids::MACRO_OSC_SHAPE_LAST_ACCESSIBLE_FROM_META); | |||
if (settings.meta_modulation) { | |||
shape += roundf(fm / 10.0 * braids::MACRO_OSC_SHAPE_LAST_ACCESSIBLE_FROM_META); | |||
} | |||
@@ -111,14 +107,14 @@ void Braids::step() { | |||
osc.set_shape((braids::MacroOscillatorShape) settings.shape); | |||
// Set timbre/modulation | |||
float timbre = params[TIMBRE_PARAM] + params[MODULATION_PARAM] * getf(inputs[TIMBRE_INPUT]) / 5.0; | |||
float modulation = params[COLOR_PARAM] + getf(inputs[COLOR_INPUT]) / 5.0; | |||
float timbre = params[TIMBRE_PARAM].value + params[MODULATION_PARAM].value * inputs[TIMBRE_INPUT].value / 5.0; | |||
float modulation = params[COLOR_PARAM].value + inputs[COLOR_INPUT].value / 5.0; | |||
int16_t param1 = rescalef(clampf(timbre, 0.0, 1.0), 0.0, 1.0, 0, INT16_MAX); | |||
int16_t param2 = rescalef(clampf(modulation, 0.0, 1.0), 0.0, 1.0, 0, INT16_MAX); | |||
osc.set_parameters(param1, param2); | |||
// Set pitch | |||
float pitchV = getf(inputs[PITCH_INPUT]) + params[COARSE_PARAM] + params[FINE_PARAM] / 12.0; | |||
float pitchV = inputs[PITCH_INPUT].value + params[COARSE_PARAM].value + params[FINE_PARAM].value / 12.0; | |||
if (!settings.meta_modulation) | |||
pitchV += fm; | |||
int32_t pitch = (pitchV * 12.0 + 60) * 128; | |||
@@ -157,7 +153,7 @@ void Braids::step() { | |||
// Output | |||
if (!outputBuffer.empty()) { | |||
Frame<1> f = outputBuffer.shift(); | |||
setf(outputs[OUT_OUTPUT], 5.0 * f.samples[0]); | |||
outputs[OUT_OUTPUT].value = 5.0 * f.samples[0]; | |||
} | |||
} | |||
@@ -28,26 +28,20 @@ struct Branches : Module { | |||
bool outcome[2] = {}; | |||
float light[2] = {}; | |||
Branches(); | |||
Branches() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
void step(); | |||
float getOutput(int outputId); | |||
}; | |||
Branches::Branches() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
} | |||
static void computeChannel(const float *in, const float *p, float threshold, float mode, bool *lastGate, bool *outcome, float *out1, float *out2, float *light) { | |||
float out = getf(in); | |||
static void processChannel(Input &in, Input &p, Param &threshold, Param &mode, bool *lastGate, bool *outcome, Output &out1, Output &out2, float *light) { | |||
float out = in.value; | |||
bool gate = (out >= 1.0); | |||
if (gate && !*lastGate) { | |||
// trigger | |||
float r = randomf(); | |||
bool toss = (r < threshold + getf(p)); | |||
if (mode < 0.5) { | |||
bool toss = (r < threshold.value + p.value); | |||
if (mode.value < 0.5) { | |||
// direct mode | |||
*outcome = toss; | |||
} | |||
@@ -59,17 +53,13 @@ static void computeChannel(const float *in, const float *p, float threshold, flo | |||
*lastGate = gate; | |||
*light = *outcome ? out : -out; | |||
if (out1) { | |||
*out1 = *outcome ? 0.0 : out; | |||
} | |||
if (out2) { | |||
*out2 = *outcome ? out : 0.0; | |||
} | |||
out1.value = *outcome ? 0.0 : out; | |||
out2.value = *outcome ? out : 0.0; | |||
} | |||
void Branches::step() { | |||
computeChannel(inputs[IN1_INPUT], inputs[P1_INPUT], params[THRESHOLD1_PARAM], params[MODE1_PARAM], &lastGate[0], &outcome[0], outputs[OUT1A_OUTPUT], outputs[OUT1B_OUTPUT], &light[0]); | |||
computeChannel(inputs[IN2_INPUT] ? inputs[IN2_INPUT] : inputs[IN1_INPUT], inputs[P2_INPUT], params[THRESHOLD2_PARAM], params[MODE2_PARAM], &lastGate[1], &outcome[1], outputs[OUT2A_OUTPUT], outputs[OUT2B_OUTPUT], &light[1]); | |||
processChannel(inputs[IN1_INPUT], inputs[P1_INPUT], params[THRESHOLD1_PARAM], params[MODE1_PARAM], &lastGate[0], &outcome[0], outputs[OUT1A_OUTPUT], outputs[OUT1B_OUTPUT], &light[0]); | |||
processChannel(inputs[IN2_INPUT].active ? inputs[IN2_INPUT] : inputs[IN1_INPUT], inputs[P2_INPUT], params[THRESHOLD2_PARAM], params[MODE2_PARAM], &lastGate[1], &outcome[1], outputs[OUT2A_OUTPUT], outputs[OUT2B_OUTPUT], &light[1]); | |||
} | |||
@@ -51,11 +51,7 @@ struct Clouds : Module { | |||
}; | |||
Clouds::Clouds() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
Clouds::Clouds() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { | |||
const int memLen = 118784; | |||
const int ccmLen = 65536 - 128; | |||
block_mem = new uint8_t[memLen](); | |||
@@ -76,13 +72,13 @@ void Clouds::step() { | |||
// Get input | |||
if (!inputBuffer.full()) { | |||
Frame<2> inputFrame; | |||
inputFrame.samples[0] = getf(inputs[IN_L_INPUT]) * params[IN_GAIN_PARAM] / 5.0; | |||
inputFrame.samples[1] = inputs[IN_R_INPUT] ? getf(inputs[IN_R_INPUT]) * params[IN_GAIN_PARAM] / 5.0 : inputFrame.samples[0]; | |||
inputFrame.samples[0] = inputs[IN_L_INPUT].value * params[IN_GAIN_PARAM].value / 5.0; | |||
inputFrame.samples[1] = inputs[IN_R_INPUT].active ? inputs[IN_R_INPUT].value * params[IN_GAIN_PARAM].value / 5.0 : inputFrame.samples[0]; | |||
inputBuffer.push(inputFrame); | |||
} | |||
// Trigger | |||
if (getf(inputs[TRIG_INPUT]) >= 1.0) { | |||
if (inputs[TRIG_INPUT].value >= 1.0) { | |||
triggered = true; | |||
} | |||
@@ -115,13 +111,13 @@ void Clouds::step() { | |||
clouds::Parameters* p = processor->mutable_parameters(); | |||
p->trigger = triggered; | |||
p->gate = triggered; | |||
p->freeze = (getf(inputs[FREEZE_INPUT]) >= 1.0); | |||
p->position = clampf(params[POSITION_PARAM] + getf(inputs[POSITION_INPUT]) / 5.0, 0.0, 1.0); | |||
p->size = clampf(params[SIZE_PARAM] + getf(inputs[SIZE_INPUT]) / 5.0, 0.0, 1.0); | |||
p->pitch = clampf((params[PITCH_PARAM] + getf(inputs[PITCH_INPUT])) * 12.0, -48.0, 48.0); | |||
p->density = clampf(params[DENSITY_PARAM] + getf(inputs[DENSITY_INPUT]) / 5.0, 0.0, 1.0); | |||
p->texture = clampf(params[TEXTURE_PARAM] + getf(inputs[TEXTURE_INPUT]) / 5.0, 0.0, 1.0); | |||
float blend = clampf(params[BLEND_PARAM] + getf(inputs[BLEND_INPUT]) / 5.0, 0.0, 1.0); | |||
p->freeze = (inputs[FREEZE_INPUT].value >= 1.0); | |||
p->position = clampf(params[POSITION_PARAM].value + inputs[POSITION_INPUT].value / 5.0, 0.0, 1.0); | |||
p->size = clampf(params[SIZE_PARAM].value + inputs[SIZE_INPUT].value / 5.0, 0.0, 1.0); | |||
p->pitch = clampf((params[PITCH_PARAM].value + inputs[PITCH_INPUT].value) * 12.0, -48.0, 48.0); | |||
p->density = clampf(params[DENSITY_PARAM].value + inputs[DENSITY_INPUT].value / 5.0, 0.0, 1.0); | |||
p->texture = clampf(params[TEXTURE_PARAM].value + inputs[TEXTURE_INPUT].value / 5.0, 0.0, 1.0); | |||
float blend = clampf(params[BLEND_PARAM].value + inputs[BLEND_INPUT].value / 5.0, 0.0, 1.0); | |||
p->dry_wet = blend; | |||
p->stereo_spread = 0.0; | |||
p->feedback = 0.0; | |||
@@ -151,8 +147,8 @@ void Clouds::step() { | |||
// Set output | |||
if (!outputBuffer.empty()) { | |||
Frame<2> outputFrame = outputBuffer.shift(); | |||
setf(outputs[OUT_L_OUTPUT], 5.0 * outputFrame.samples[0]); | |||
setf(outputs[OUT_R_OUTPUT], 5.0 * outputFrame.samples[1]); | |||
outputs[OUT_L_OUTPUT].value = 5.0 * outputFrame.samples[0]; | |||
outputs[OUT_R_OUTPUT].value = 5.0 * outputFrame.samples[1]; | |||
} | |||
} | |||
@@ -102,11 +102,7 @@ struct Elements : Module { | |||
}; | |||
Elements::Elements() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
Elements::Elements() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { | |||
part = new elements::Part(); | |||
// In the Mutable Instruments code, Part doesn't initialize itself, so zero it here. | |||
memset(part, 0, sizeof(*part)); | |||
@@ -124,8 +120,8 @@ void Elements::step() { | |||
// Get input | |||
if (!inputBuffer.full()) { | |||
Frame<2> inputFrame; | |||
inputFrame.samples[0] = getf(inputs[BLOW_INPUT]) / 5.0; | |||
inputFrame.samples[1] = getf(inputs[STRIKE_INPUT]) / 5.0; | |||
inputFrame.samples[0] = inputs[BLOW_INPUT].value / 5.0; | |||
inputFrame.samples[1] = inputs[STRIKE_INPUT].value / 5.0; | |||
inputBuffer.push(inputFrame); | |||
} | |||
@@ -153,12 +149,12 @@ void Elements::step() { | |||
// Set patch from parameters | |||
elements::Patch* p = part->mutable_patch(); | |||
p->exciter_envelope_shape = params[CONTOUR_PARAM]; | |||
p->exciter_bow_level = params[BOW_PARAM]; | |||
p->exciter_blow_level = params[BLOW_PARAM]; | |||
p->exciter_strike_level = params[STRIKE_PARAM]; | |||
p->exciter_envelope_shape = params[CONTOUR_PARAM].value; | |||
p->exciter_bow_level = params[BOW_PARAM].value; | |||
p->exciter_blow_level = params[BLOW_PARAM].value; | |||
p->exciter_strike_level = params[STRIKE_PARAM].value; | |||
#define BIND(_p, _m, _i) clampf(params[_p] + 3.3*quadraticBipolar(params[_m])*getf(inputs[_i])/5.0, 0.0, 0.9995) | |||
#define BIND(_p, _m, _i) clampf(params[_p].value + 3.3*quadraticBipolar(params[_m].value)*inputs[_i].value/5.0, 0.0, 0.9995) | |||
p->exciter_bow_timbre = BIND(BOW_TIMBRE_PARAM, BOW_TIMBRE_MOD_PARAM, BOW_TIMBRE_MOD_INPUT); | |||
p->exciter_blow_meta = BIND(FLOW_PARAM, FLOW_MOD_PARAM, FLOW_MOD_INPUT); | |||
@@ -169,14 +165,14 @@ void Elements::step() { | |||
p->resonator_brightness = BIND(BRIGHTNESS_PARAM, BRIGHTNESS_MOD_PARAM, BRIGHTNESS_MOD_INPUT); | |||
p->resonator_damping = BIND(DAMPING_PARAM, DAMPING_MOD_PARAM, DAMPING_MOD_INPUT); | |||
p->resonator_position = BIND(POSITION_PARAM, POSITION_MOD_PARAM, POSITION_MOD_INPUT); | |||
p->space = clampf(params[SPACE_PARAM] + params[SPACE_MOD_PARAM]*getf(inputs[SPACE_MOD_INPUT])/5.0, 0.0, 2.0); | |||
p->space = clampf(params[SPACE_PARAM].value + params[SPACE_MOD_PARAM].value*inputs[SPACE_MOD_INPUT].value/5.0, 0.0, 2.0); | |||
// Get performance inputs | |||
elements::PerformanceState performance; | |||
performance.note = 12.0*getf(inputs[NOTE_INPUT]) + roundf(params[COARSE_PARAM]) + params[FINE_PARAM] + 69.0; | |||
performance.modulation = 3.3*quarticBipolar(params[FM_PARAM]) * 49.5 * getf(inputs[FM_INPUT])/5.0; | |||
performance.gate = params[PLAY_PARAM] >= 1.0 || getf(inputs[GATE_INPUT]) >= 1.0; | |||
performance.strength = clampf(1.0 - getf(inputs[STRENGTH_INPUT])/5.0, 0.0, 1.0); | |||
performance.note = 12.0*inputs[NOTE_INPUT].value + roundf(params[COARSE_PARAM].value) + params[FINE_PARAM].value + 69.0; | |||
performance.modulation = 3.3*quarticBipolar(params[FM_PARAM].value) * 49.5 * inputs[FM_INPUT].value/5.0; | |||
performance.gate = params[PLAY_PARAM].value >= 1.0 || inputs[GATE_INPUT].value >= 1.0; | |||
performance.strength = clampf(1.0 - inputs[STRENGTH_INPUT].value/5.0, 0.0, 1.0); | |||
// Generate audio | |||
part->Process(performance, blow, strike, main, aux, 16); | |||
@@ -204,8 +200,8 @@ void Elements::step() { | |||
// Set output | |||
if (!outputBuffer.empty()) { | |||
Frame<2> outputFrame = outputBuffer.shift(); | |||
setf(outputs[AUX_OUTPUT], 5.0 * outputFrame.samples[0]); | |||
setf(outputs[MAIN_OUTPUT], 5.0 * outputFrame.samples[1]); | |||
outputs[AUX_OUTPUT].value = 5.0 * outputFrame.samples[0]; | |||
outputs[MAIN_OUTPUT].value = 5.0 * outputFrame.samples[1]; | |||
} | |||
} | |||
@@ -36,17 +36,11 @@ struct Frames : Module { | |||
float lights[1] = {}; | |||
Frames(); | |||
Frames() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
void step(); | |||
}; | |||
Frames::Frames() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
} | |||
void Frames::step() { | |||
} | |||
@@ -32,56 +32,36 @@ struct Kinks : Module { | |||
float sample = 0.0; | |||
float lights[3] = {}; | |||
Kinks(); | |||
Kinks() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
void step(); | |||
}; | |||
Kinks::Kinks() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
} | |||
void Kinks::step() { | |||
// Gaussian noise generator | |||
float noise = 2.0 * randomNormal(); | |||
// S&H | |||
float trig = getf(inputs[TRIG_INPUT]); | |||
float trig = inputs[TRIG_INPUT].value; | |||
float dtrig = (trig - lastTrig) * gSampleRate; | |||
if (dtrig > DTRIG) { | |||
sample = getf(inputs[SH_INPUT], noise); | |||
sample = inputs[SH_INPUT].normalize(noise); | |||
} | |||
lastTrig = trig; | |||
// lights | |||
lights[0] = getf(inputs[SIGN_INPUT]); | |||
lights[1] = getf(inputs[LOGIC_A_INPUT]) + getf(inputs[LOGIC_B_INPUT]); | |||
lights[0] = inputs[SIGN_INPUT].value; | |||
lights[1] = inputs[LOGIC_A_INPUT].value + inputs[LOGIC_B_INPUT].value; | |||
lights[2] = sample; | |||
// outputs | |||
if (outputs[INVERT_OUTPUT]) { | |||
*outputs[INVERT_OUTPUT] = -getf(inputs[SIGN_INPUT]); | |||
} | |||
if (outputs[HALF_RECTIFY_OUTPUT]) { | |||
*outputs[HALF_RECTIFY_OUTPUT] = fmaxf(0.0, getf(inputs[SIGN_INPUT])); | |||
} | |||
if (outputs[FULL_RECTIFY_OUTPUT]) { | |||
*outputs[FULL_RECTIFY_OUTPUT] = fabsf(getf(inputs[SIGN_INPUT])); | |||
} | |||
if (outputs[MAX_OUTPUT]) { | |||
*outputs[MAX_OUTPUT] = fmaxf(getf(inputs[LOGIC_A_INPUT]), getf(inputs[LOGIC_B_INPUT])); | |||
} | |||
if (outputs[MIN_OUTPUT]) { | |||
*outputs[MIN_OUTPUT] = fminf(getf(inputs[LOGIC_A_INPUT]), getf(inputs[LOGIC_B_INPUT])); | |||
} | |||
if (outputs[NOISE_OUTPUT]) { | |||
*outputs[NOISE_OUTPUT] = noise; | |||
} | |||
if (outputs[SH_OUTPUT]) { | |||
*outputs[SH_OUTPUT] = sample; | |||
} | |||
outputs[INVERT_OUTPUT].value = -inputs[SIGN_INPUT].value; | |||
outputs[HALF_RECTIFY_OUTPUT].value = fmaxf(0.0, inputs[SIGN_INPUT].value); | |||
outputs[FULL_RECTIFY_OUTPUT].value = fabsf(inputs[SIGN_INPUT].value); | |||
outputs[MAX_OUTPUT].value = fmaxf(inputs[LOGIC_A_INPUT].value, inputs[LOGIC_B_INPUT].value); | |||
outputs[MIN_OUTPUT].value = fminf(inputs[LOGIC_A_INPUT].value, inputs[LOGIC_B_INPUT].value); | |||
outputs[NOISE_OUTPUT].value = noise; | |||
outputs[SH_OUTPUT].value = sample; | |||
} | |||
@@ -25,28 +25,22 @@ struct Links : Module { | |||
}; | |||
float lights[3] = {}; | |||
Links(); | |||
Links() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
void step(); | |||
}; | |||
Links::Links() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
} | |||
void Links::step() { | |||
float in1 = getf(inputs[A1_INPUT]); | |||
float in2 = getf(inputs[B1_INPUT]) + getf(inputs[B2_INPUT]); | |||
float in3 = getf(inputs[C1_INPUT]) + getf(inputs[C2_INPUT]) + getf(inputs[C3_INPUT]); | |||
setf(outputs[A1_OUTPUT], in1); | |||
setf(outputs[A2_OUTPUT], in1); | |||
setf(outputs[A3_OUTPUT], in1); | |||
setf(outputs[B1_OUTPUT], in2); | |||
setf(outputs[B2_OUTPUT], in2); | |||
setf(outputs[C1_OUTPUT], in3); | |||
float in1 = inputs[A1_INPUT].value; | |||
float in2 = inputs[B1_INPUT].value + inputs[B2_INPUT].value; | |||
float in3 = inputs[C1_INPUT].value + inputs[C2_INPUT].value + inputs[C3_INPUT].value; | |||
outputs[A1_OUTPUT].value = in1; | |||
outputs[A2_OUTPUT].value = in1; | |||
outputs[A3_OUTPUT].value = in1; | |||
outputs[B1_OUTPUT].value = in2; | |||
outputs[B2_OUTPUT].value = in2; | |||
outputs[C1_OUTPUT].value = in3; | |||
lights[0] = in1 / 5.0; | |||
lights[1] = in2 / 5.0; | |||
@@ -95,11 +95,7 @@ struct Rings : Module { | |||
}; | |||
Rings::Rings() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
Rings::Rings() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { | |||
memset(&strummer, 0, sizeof(strummer)); | |||
memset(&part, 0, sizeof(part)); | |||
memset(&string_synth, 0, sizeof(string_synth)); | |||
@@ -118,21 +114,21 @@ void Rings::step() { | |||
// Get input | |||
if (!inputBuffer.full()) { | |||
Frame<1> f; | |||
f.samples[0] = getf(inputs[IN_INPUT]) / 5.0; | |||
f.samples[0] = inputs[IN_INPUT].value / 5.0; | |||
inputBuffer.push(f); | |||
} | |||
if (!strum) { | |||
strum = getf(inputs[STRUM_INPUT]) >= 1.0; | |||
strum = inputs[STRUM_INPUT].value >= 1.0; | |||
} | |||
// Polyphony / model | |||
if (polyphonyTrigger.process(params[POLYPHONY_PARAM])) { | |||
if (polyphonyTrigger.process(params[POLYPHONY_PARAM].value)) { | |||
polyphonyMode = (polyphonyMode + 1) % 3; | |||
} | |||
lights[0] = (float)polyphonyMode; | |||
if (modelTrigger.process(params[RESONATOR_PARAM])) { | |||
if (modelTrigger.process(params[RESONATOR_PARAM].value)) { | |||
model = (model + 1) % 3; | |||
} | |||
lights[1] = (float)model; | |||
@@ -157,26 +153,26 @@ void Rings::step() { | |||
// Patch | |||
rings::Patch patch; | |||
float structure = params[STRUCTURE_PARAM] + 3.3*quadraticBipolar(params[STRUCTURE_MOD_PARAM])*getf(inputs[STRUCTURE_MOD_INPUT])/5.0; | |||
float structure = params[STRUCTURE_PARAM].value + 3.3*quadraticBipolar(params[STRUCTURE_MOD_PARAM].value)*inputs[STRUCTURE_MOD_INPUT].value/5.0; | |||
patch.structure = clampf(structure, 0.0, 0.9995); | |||
patch.brightness = clampf(params[BRIGHTNESS_PARAM] + 3.3*quadraticBipolar(params[BRIGHTNESS_MOD_PARAM])*getf(inputs[BRIGHTNESS_MOD_INPUT])/5.0, 0.0, 1.0); | |||
patch.damping = clampf(params[DAMPING_PARAM] + 3.3*quadraticBipolar(params[DAMPING_MOD_PARAM])*getf(inputs[DAMPING_MOD_INPUT])/5.0, 0.0, 0.9995); | |||
patch.position = clampf(params[POSITION_PARAM] + 3.3*quadraticBipolar(params[POSITION_MOD_PARAM])*getf(inputs[POSITION_MOD_INPUT])/5.0, 0.0, 0.9995); | |||
patch.brightness = clampf(params[BRIGHTNESS_PARAM].value + 3.3*quadraticBipolar(params[BRIGHTNESS_MOD_PARAM].value)*inputs[BRIGHTNESS_MOD_INPUT].value/5.0, 0.0, 1.0); | |||
patch.damping = clampf(params[DAMPING_PARAM].value + 3.3*quadraticBipolar(params[DAMPING_MOD_PARAM].value)*inputs[DAMPING_MOD_INPUT].value/5.0, 0.0, 0.9995); | |||
patch.position = clampf(params[POSITION_PARAM].value + 3.3*quadraticBipolar(params[POSITION_MOD_PARAM].value)*inputs[POSITION_MOD_INPUT].value/5.0, 0.0, 0.9995); | |||
// Performance | |||
rings::PerformanceState performance_state; | |||
performance_state.note = 12.0*getf(inputs[PITCH_INPUT], 1/12.0); | |||
float transpose = params[FREQUENCY_PARAM]; | |||
performance_state.note = 12.0*inputs[PITCH_INPUT].normalize(1/12.0); | |||
float transpose = params[FREQUENCY_PARAM].value; | |||
// Quantize transpose if pitch input is connected | |||
if (inputs[PITCH_INPUT]) { | |||
if (inputs[PITCH_INPUT].active) { | |||
transpose = roundf(transpose); | |||
} | |||
performance_state.tonic = 12.0 + clampf(transpose, 0, 60.0); | |||
performance_state.fm = clampf(48.0 * 3.3*quarticBipolar(params[FREQUENCY_MOD_PARAM]) * getf(inputs[FREQUENCY_MOD_INPUT], 1.0)/5.0, -48.0, 48.0); | |||
performance_state.fm = clampf(48.0 * 3.3*quarticBipolar(params[FREQUENCY_MOD_PARAM].value) * inputs[FREQUENCY_MOD_INPUT].normalize(1.0)/5.0, -48.0, 48.0); | |||
performance_state.internal_exciter = !inputs[IN_INPUT]; | |||
performance_state.internal_strum = !inputs[STRUM_INPUT]; | |||
performance_state.internal_note = !inputs[PITCH_INPUT]; | |||
performance_state.internal_exciter = !inputs[IN_INPUT].active; | |||
performance_state.internal_strum = !inputs[STRUM_INPUT].active; | |||
performance_state.internal_note = !inputs[PITCH_INPUT].active; | |||
// TODO | |||
// "Normalized to a step detector on the V/OCT input and a transient detector on the IN input." | |||
@@ -218,14 +214,14 @@ void Rings::step() { | |||
if (!outputBuffer.empty()) { | |||
Frame<2> outputFrame = outputBuffer.shift(); | |||
// "Note that you need to insert a jack into each output to split the signals: when only one jack is inserted, both signals are mixed together." | |||
if (outputs[ODD_OUTPUT] && outputs[EVEN_OUTPUT]) { | |||
setf(outputs[ODD_OUTPUT], clampf(outputFrame.samples[0], -1.0, 1.0)*5.0); | |||
setf(outputs[EVEN_OUTPUT], clampf(outputFrame.samples[1], -1.0, 1.0)*5.0); | |||
if (outputs[ODD_OUTPUT].active && outputs[EVEN_OUTPUT].active) { | |||
outputs[ODD_OUTPUT].value = clampf(outputFrame.samples[0], -1.0, 1.0)*5.0; | |||
outputs[EVEN_OUTPUT].value = clampf(outputFrame.samples[1], -1.0, 1.0)*5.0; | |||
} | |||
else { | |||
float v = clampf(outputFrame.samples[0] + outputFrame.samples[1], -1.0, 1.0)*5.0; | |||
setf(outputs[ODD_OUTPUT], v); | |||
setf(outputs[EVEN_OUTPUT], v); | |||
outputs[ODD_OUTPUT].value = v; | |||
outputs[EVEN_OUTPUT].value = v; | |||
} | |||
} | |||
} | |||
@@ -27,26 +27,20 @@ struct Shades : Module { | |||
float lights[3] = {}; | |||
Shades(); | |||
Shades() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
void step(); | |||
}; | |||
Shades::Shades() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
} | |||
static float getChannelOutput(const float *in, float gain, float mode) { | |||
float out = getf(in, 5.0); | |||
if ((int)roundf(mode) == 1) { | |||
static float getChannelOutput(Input &in, Param &gain, Param &mode) { | |||
float out = in.normalize(5.0); | |||
if ((int)roundf(mode.value) == 1) { | |||
// attenuverter | |||
out *= 2.0*gain - 1.0; | |||
out *= 2.0*gain.value - 1.0; | |||
} | |||
else { | |||
// attenuator | |||
out *= gain; | |||
out *= gain.value; | |||
} | |||
return out; | |||
} | |||
@@ -55,22 +49,22 @@ void Shades::step() { | |||
float out = 0.0; | |||
out += getChannelOutput(inputs[IN1_INPUT], params[GAIN1_PARAM], params[MODE1_PARAM]); | |||
lights[0] = out / 5.0; | |||
if (outputs[OUT1_OUTPUT]) { | |||
*outputs[OUT1_OUTPUT] = out; | |||
if (outputs[OUT1_OUTPUT].active) { | |||
outputs[OUT1_OUTPUT].value = out; | |||
out = 0.0; | |||
} | |||
out += getChannelOutput(inputs[IN2_INPUT], params[GAIN2_PARAM], params[MODE2_PARAM]); | |||
lights[1] = out / 5.0; | |||
if (outputs[OUT2_OUTPUT]) { | |||
*outputs[OUT2_OUTPUT] = out; | |||
if (outputs[OUT2_OUTPUT].active) { | |||
outputs[OUT2_OUTPUT].value = out; | |||
out = 0.0; | |||
} | |||
out += getChannelOutput(inputs[IN3_INPUT], params[GAIN3_PARAM], params[MODE3_PARAM]); | |||
lights[2] = out / 5.0; | |||
if (outputs[OUT3_OUTPUT]) { | |||
*outputs[OUT3_OUTPUT] = out; | |||
if (outputs[OUT3_OUTPUT].active) { | |||
outputs[OUT3_OUTPUT].value = out; | |||
} | |||
} | |||
@@ -83,11 +83,7 @@ struct Sheep : Module { | |||
}; | |||
Sheep::Sheep() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
Sheep::Sheep() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { | |||
memset(&generator, 0, sizeof(generator)); | |||
generator.Init(); | |||
generator.set_sync(false); | |||
@@ -96,14 +92,14 @@ Sheep::Sheep() { | |||
void Sheep::step() { | |||
tides::GeneratorMode mode = generator.mode(); | |||
if (modeTrigger.process(params[BANK_PARAM])) { | |||
if (modeTrigger.process(params[BANK_PARAM].value)) { | |||
mode = (tides::GeneratorMode) (((int)mode - 1 + 3) % 3); | |||
generator.set_mode(mode); | |||
} | |||
lights[0] = (float)mode; | |||
tides::GeneratorRange range = generator.range(); | |||
if (rangeTrigger.process(params[RANGE_PARAM])) { | |||
if (rangeTrigger.process(params[RANGE_PARAM].value)) { | |||
range = (tides::GeneratorRange) (((int)range - 1 + 3) % 3); | |||
generator.set_range(range); | |||
} | |||
@@ -114,18 +110,18 @@ void Sheep::step() { | |||
frame = 0; | |||
// Pitch | |||
float pitch = params[FREQUENCY_PARAM]; | |||
pitch += 12.0 * getf(inputs[PITCH_INPUT]); | |||
pitch += params[FM_PARAM] * getf(inputs[FM_INPUT], 0.1) / 5.0; | |||
float pitch = params[FREQUENCY_PARAM].value; | |||
pitch += 12.0 * inputs[PITCH_INPUT].value; | |||
pitch += params[FM_PARAM].value * inputs[FM_INPUT].normalize(0.1) / 5.0; | |||
pitch += 60.0; | |||
// Scale to the global sample rate | |||
pitch += log2f(48000.0 / gSampleRate) * 12.0; | |||
generator.set_pitch(clampf(pitch * 0x80, -0x8000, 0x7fff)); | |||
// Slope, smoothness, pitch | |||
int16_t shape = clampf(params[ROW_PARAM] + getf(inputs[ROW_INPUT]) / 5.0, -1.0, 1.0) * 0x7fff; | |||
int16_t slope = clampf(params[COLUMN_PARAM] + getf(inputs[COLUMN_INPUT]) / 5.0, -1.0, 1.0) * 0x7fff; | |||
int16_t smoothness = clampf(params[SMOOTHNESS_PARAM] + getf(inputs[SMOOTHNESS_INPUT]) / 5.0, -1.0, 1.0) * 0x7fff; | |||
int16_t shape = clampf(params[ROW_PARAM].value + inputs[ROW_INPUT].value / 5.0, -1.0, 1.0) * 0x7fff; | |||
int16_t slope = clampf(params[COLUMN_PARAM].value + inputs[COLUMN_INPUT].value / 5.0, -1.0, 1.0) * 0x7fff; | |||
int16_t smoothness = clampf(params[SMOOTHNESS_PARAM].value + inputs[SMOOTHNESS_INPUT].value / 5.0, -1.0, 1.0) * 0x7fff; | |||
generator.set_shape(shape); | |||
generator.set_slope(slope); | |||
generator.set_smoothness(smoothness); | |||
@@ -133,23 +129,23 @@ void Sheep::step() { | |||
// Sync | |||
// Slight deviation from spec here. | |||
// Instead of toggling sync by holding the range button, just enable it if the clock port is plugged in. | |||
generator.set_sync(inputs[BANK_INPUT]); | |||
generator.set_sync(inputs[BANK_INPUT].active); | |||
// Generator | |||
generator.Process(); | |||
} | |||
// Level | |||
uint16_t level = clampf(getf(inputs[LEVEL_INPUT], 8.0) / 8.0, 0.0, 1.0) * 0xffff; | |||
uint16_t level = clampf(inputs[LEVEL_INPUT].normalize(8.0) / 8.0, 0.0, 1.0) * 0xffff; | |||
if (level < 32) | |||
level = 0; | |||
uint8_t gate = 0; | |||
if (getf(inputs[FREEZE_INPUT]) >= 0.7) | |||
if (inputs[FREEZE_INPUT].value >= 0.7) | |||
gate |= tides::CONTROL_FREEZE; | |||
if (getf(inputs[SYNC_INPUT]) >= 0.7) | |||
if (inputs[SYNC_INPUT].value >= 0.7) | |||
gate |= tides::CONTROL_GATE; | |||
if (getf(inputs[BANK_INPUT]) >= 0.7) | |||
if (inputs[BANK_INPUT].value >= 0.7) | |||
gate |= tides::CONTROL_CLOCK; | |||
if (!(lastGate & tides::CONTROL_CLOCK) && (gate & tides::CONTROL_CLOCK)) | |||
gate |= tides::CONTROL_GATE_RISING; | |||
@@ -168,10 +164,10 @@ void Sheep::step() { | |||
float unif = rescalef(uni, 0, 0xffff, 0.0, 8.0); | |||
float bif = rescalef(bi, -0x8000, 0x7fff, -5.0, 5.0); | |||
setf(outputs[BIT_OUTPUT], sample.flags & tides::FLAG_END_OF_ATTACK ? 0.0 : 5.0); | |||
setf(outputs[SUB_OUTPUT], sample.flags & tides::FLAG_END_OF_RELEASE ? 0.0 : 5.0); | |||
setf(outputs[UNI_OUTPUT], unif); | |||
setf(outputs[BI_OUTPUT], bif); | |||
outputs[BIT_OUTPUT].value = sample.flags & tides::FLAG_END_OF_ATTACK ? 0.0 : 5.0; | |||
outputs[SUB_OUTPUT].value = sample.flags & tides::FLAG_END_OF_RELEASE ? 0.0 : 5.0; | |||
outputs[UNI_OUTPUT].value = unif; | |||
outputs[BI_OUTPUT].value = bif; | |||
lights[1] = (sample.flags & tides::FLAG_END_OF_ATTACK ? -unif : unif) / 8.0; | |||
} | |||
@@ -31,17 +31,11 @@ struct Streams : Module { | |||
NUM_OUTPUTS | |||
}; | |||
Streams(); | |||
Streams() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
void step(); | |||
}; | |||
Streams::Streams() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
} | |||
void Streams::step() { | |||
} | |||
@@ -81,11 +81,7 @@ struct Tides : Module { | |||
}; | |||
Tides::Tides() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
Tides::Tides() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { | |||
memset(&generator, 0, sizeof(generator)); | |||
generator.Init(); | |||
generator.set_sync(false); | |||
@@ -94,14 +90,14 @@ Tides::Tides() { | |||
void Tides::step() { | |||
tides::GeneratorMode mode = generator.mode(); | |||
if (modeTrigger.process(params[MODE_PARAM])) { | |||
if (modeTrigger.process(params[MODE_PARAM].value)) { | |||
mode = (tides::GeneratorMode) (((int)mode - 1 + 3) % 3); | |||
generator.set_mode(mode); | |||
} | |||
lights[0] = (float)mode; | |||
tides::GeneratorRange range = generator.range(); | |||
if (rangeTrigger.process(params[RANGE_PARAM])) { | |||
if (rangeTrigger.process(params[RANGE_PARAM].value)) { | |||
range = (tides::GeneratorRange) (((int)range - 1 + 3) % 3); | |||
generator.set_range(range); | |||
} | |||
@@ -112,18 +108,18 @@ void Tides::step() { | |||
frame = 0; | |||
// Pitch | |||
float pitch = params[FREQUENCY_PARAM]; | |||
pitch += 12.0 * getf(inputs[PITCH_INPUT]); | |||
pitch += params[FM_PARAM] * getf(inputs[FM_INPUT], 0.1) / 5.0; | |||
float pitch = params[FREQUENCY_PARAM].value; | |||
pitch += 12.0 * inputs[PITCH_INPUT].value; | |||
pitch += params[FM_PARAM].value * inputs[FM_INPUT].normalize(0.1) / 5.0; | |||
pitch += 60.0; | |||
// Scale to the global sample rate | |||
pitch += log2f(48000.0 / gSampleRate) * 12.0; | |||
generator.set_pitch(clampf(pitch * 0x80, -0x8000, 0x7fff)); | |||
// Slope, smoothness, pitch | |||
int16_t shape = clampf(params[SHAPE_PARAM] + getf(inputs[SHAPE_INPUT]) / 5.0, -1.0, 1.0) * 0x7fff; | |||
int16_t slope = clampf(params[SLOPE_PARAM] + getf(inputs[SLOPE_INPUT]) / 5.0, -1.0, 1.0) * 0x7fff; | |||
int16_t smoothness = clampf(params[SMOOTHNESS_PARAM] + getf(inputs[SMOOTHNESS_INPUT]) / 5.0, -1.0, 1.0) * 0x7fff; | |||
int16_t shape = clampf(params[SHAPE_PARAM].value + inputs[SHAPE_INPUT].value / 5.0, -1.0, 1.0) * 0x7fff; | |||
int16_t slope = clampf(params[SLOPE_PARAM].value + inputs[SLOPE_INPUT].value / 5.0, -1.0, 1.0) * 0x7fff; | |||
int16_t smoothness = clampf(params[SMOOTHNESS_PARAM].value + inputs[SMOOTHNESS_INPUT].value / 5.0, -1.0, 1.0) * 0x7fff; | |||
generator.set_shape(shape); | |||
generator.set_slope(slope); | |||
generator.set_smoothness(smoothness); | |||
@@ -131,23 +127,23 @@ void Tides::step() { | |||
// Sync | |||
// Slight deviation from spec here. | |||
// Instead of toggling sync by holding the range button, just enable it if the clock port is plugged in. | |||
generator.set_sync(inputs[CLOCK_INPUT]); | |||
generator.set_sync(inputs[CLOCK_INPUT].active); | |||
// Generator | |||
generator.Process(); | |||
} | |||
// Level | |||
uint16_t level = clampf(getf(inputs[LEVEL_INPUT], 8.0) / 8.0, 0.0, 1.0) * 0xffff; | |||
uint16_t level = clampf(inputs[LEVEL_INPUT].normalize(8.0) / 8.0, 0.0, 1.0) * 0xffff; | |||
if (level < 32) | |||
level = 0; | |||
uint8_t gate = 0; | |||
if (getf(inputs[FREEZE_INPUT]) >= 0.7) | |||
if (inputs[FREEZE_INPUT].value >= 0.7) | |||
gate |= tides::CONTROL_FREEZE; | |||
if (getf(inputs[TRIG_INPUT]) >= 0.7) | |||
if (inputs[TRIG_INPUT].value >= 0.7) | |||
gate |= tides::CONTROL_GATE; | |||
if (getf(inputs[CLOCK_INPUT]) >= 0.7) | |||
if (inputs[CLOCK_INPUT].value >= 0.7) | |||
gate |= tides::CONTROL_CLOCK; | |||
if (!(lastGate & tides::CONTROL_CLOCK) && (gate & tides::CONTROL_CLOCK)) | |||
gate |= tides::CONTROL_GATE_RISING; | |||
@@ -166,10 +162,10 @@ void Tides::step() { | |||
float unif = rescalef(uni, 0, 0xffff, 0.0, 8.0); | |||
float bif = rescalef(bi, -0x8000, 0x7fff, -5.0, 5.0); | |||
setf(outputs[HIGH_OUTPUT], sample.flags & tides::FLAG_END_OF_ATTACK ? 0.0 : 5.0); | |||
setf(outputs[LOW_OUTPUT], sample.flags & tides::FLAG_END_OF_RELEASE ? 0.0 : 5.0); | |||
setf(outputs[UNI_OUTPUT], unif); | |||
setf(outputs[BI_OUTPUT], bif); | |||
outputs[HIGH_OUTPUT].value = sample.flags & tides::FLAG_END_OF_ATTACK ? 0.0 : 5.0; | |||
outputs[LOW_OUTPUT].value = sample.flags & tides::FLAG_END_OF_RELEASE ? 0.0 : 5.0; | |||
outputs[UNI_OUTPUT].value = unif; | |||
outputs[BI_OUTPUT].value = bif; | |||
lights[1] = (sample.flags & tides::FLAG_END_OF_ATTACK ? -unif : unif) / 8.0; | |||
} | |||
@@ -35,60 +35,54 @@ struct Veils : Module { | |||
float lights[4] = {}; | |||
Veils(); | |||
Veils() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
void step(); | |||
}; | |||
Veils::Veils() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
} | |||
static float getChannelOutput(float *in, float gain, float *cv, float response) { | |||
float out = getf(in) * gain; | |||
static float processChannel(Input &in, Param &gain, Input &cv, Param &response) { | |||
float out = in.value * gain.value; | |||
if (out == 0.0) | |||
return 0.0; | |||
if (cv) { | |||
float linear = fmaxf(getf(cv) / 5.0, 0.0); | |||
if (cv.active) { | |||
float linear = fmaxf(cv.value / 5.0, 0.0); | |||
if (linear == 0.0) | |||
return 0.0; | |||
const float ex = 200.0; | |||
float exponential = rescalef(powf(ex, linear), 1.0, ex, 0.0, 1.0); | |||
out *= crossf(exponential, linear, response); | |||
out *= crossf(exponential, linear, response.value); | |||
} | |||
return out; | |||
} | |||
void Veils::step() { | |||
float out = 0.0; | |||
out += getChannelOutput(inputs[IN1_INPUT], params[GAIN1_PARAM], inputs[CV1_INPUT], params[RESPONSE1_PARAM]); | |||
out += processChannel(inputs[IN1_INPUT], params[GAIN1_PARAM], inputs[CV1_INPUT], params[RESPONSE1_PARAM]); | |||
lights[0] = out; | |||
if (outputs[OUT1_OUTPUT]) { | |||
*outputs[OUT1_OUTPUT] = out; | |||
if (outputs[OUT1_OUTPUT].active) { | |||
outputs[OUT1_OUTPUT].value = out; | |||
out = 0.0; | |||
} | |||
out += getChannelOutput(inputs[IN2_INPUT], params[GAIN2_PARAM], inputs[CV2_INPUT], params[RESPONSE2_PARAM]); | |||
out += processChannel(inputs[IN2_INPUT], params[GAIN2_PARAM], inputs[CV2_INPUT], params[RESPONSE2_PARAM]); | |||
lights[1] = out; | |||
if (outputs[OUT2_OUTPUT]) { | |||
*outputs[OUT2_OUTPUT] = out; | |||
if (outputs[OUT2_OUTPUT].active) { | |||
outputs[OUT2_OUTPUT].value = out; | |||
out = 0.0; | |||
} | |||
out += getChannelOutput(inputs[IN3_INPUT], params[GAIN3_PARAM], inputs[CV3_INPUT], params[RESPONSE3_PARAM]); | |||
out += processChannel(inputs[IN3_INPUT], params[GAIN3_PARAM], inputs[CV3_INPUT], params[RESPONSE3_PARAM]); | |||
lights[2] = out; | |||
if (outputs[OUT3_OUTPUT]) { | |||
*outputs[OUT3_OUTPUT] = out; | |||
if (outputs[OUT3_OUTPUT].active) { | |||
outputs[OUT3_OUTPUT].value = out; | |||
out = 0.0; | |||
} | |||
out += getChannelOutput(inputs[IN4_INPUT], params[GAIN4_PARAM], inputs[CV4_INPUT], params[RESPONSE4_PARAM]); | |||
out += processChannel(inputs[IN4_INPUT], params[GAIN4_PARAM], inputs[CV4_INPUT], params[RESPONSE4_PARAM]); | |||
lights[3] = out; | |||
if (outputs[OUT4_OUTPUT]) { | |||
*outputs[OUT4_OUTPUT] = out; | |||
if (outputs[OUT4_OUTPUT].active) { | |||
outputs[OUT4_OUTPUT].value = out; | |||
} | |||
} | |||
@@ -64,11 +64,7 @@ struct Warps : Module { | |||
}; | |||
Warps::Warps() { | |||
params.resize(NUM_PARAMS); | |||
inputs.resize(NUM_INPUTS); | |||
outputs.resize(NUM_OUTPUTS); | |||
Warps::Warps() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { | |||
memset(&modulator, 0, sizeof(modulator)); | |||
modulator.Init(96000.0f); | |||
@@ -78,7 +74,7 @@ Warps::Warps() { | |||
void Warps::step() { | |||
// State trigger | |||
warps::Parameters *p = modulator.mutable_parameters(); | |||
if (stateTrigger.process(params[STATE_PARAM])) { | |||
if (stateTrigger.process(params[STATE_PARAM].value)) { | |||
p->carrier_shape = (p->carrier_shape + 1) % 4; | |||
} | |||
lights[0] = p->carrier_shape; | |||
@@ -87,25 +83,25 @@ void Warps::step() { | |||
if (++frame >= 60) { | |||
frame = 0; | |||
p->channel_drive[0] = clampf(params[LEVEL1_PARAM] + getf(inputs[LEVEL1_INPUT]) / 5.0, 0.0, 1.0); | |||
p->channel_drive[1] = clampf(params[LEVEL2_PARAM] + getf(inputs[LEVEL2_INPUT]) / 5.0, 0.0, 1.0); | |||
p->modulation_algorithm = clampf(params[ALGORITHM_PARAM] / 8.0 + getf(inputs[ALGORITHM_INPUT]) / 5.0, 0.0, 1.0); | |||
p->channel_drive[0] = clampf(params[LEVEL1_PARAM].value + inputs[LEVEL1_INPUT].value / 5.0, 0.0, 1.0); | |||
p->channel_drive[1] = clampf(params[LEVEL2_PARAM].value + inputs[LEVEL2_INPUT].value / 5.0, 0.0, 1.0); | |||
p->modulation_algorithm = clampf(params[ALGORITHM_PARAM].value / 8.0 + inputs[ALGORITHM_INPUT].value / 5.0, 0.0, 1.0); | |||
lights[1] = p->modulation_algorithm * 8.0; | |||
p->modulation_parameter = clampf(params[TIMBRE_PARAM] + getf(inputs[TIMBRE_INPUT]) / 5.0, 0.0, 1.0); | |||
p->modulation_parameter = clampf(params[TIMBRE_PARAM].value + inputs[TIMBRE_INPUT].value / 5.0, 0.0, 1.0); | |||
p->frequency_shift_pot = params[ALGORITHM_PARAM] / 8.0; | |||
p->frequency_shift_cv = clampf(getf(inputs[ALGORITHM_INPUT]) / 5.0, -1.0, 1.0); | |||
p->frequency_shift_pot = params[ALGORITHM_PARAM].value / 8.0; | |||
p->frequency_shift_cv = clampf(inputs[ALGORITHM_INPUT].value / 5.0, -1.0, 1.0); | |||
p->phase_shift = p->modulation_algorithm; | |||
p->note = 60.0 * params[LEVEL1_PARAM] + 12.0 * getf(inputs[LEVEL1_INPUT], 2.0) + 12.0; | |||
p->note = 60.0 * params[LEVEL1_PARAM].value + 12.0 * inputs[LEVEL1_INPUT].normalize(2.0) + 12.0; | |||
p->note += log2f(96000.0 / gSampleRate) * 12.0; | |||
modulator.Process(inputFrames, outputFrames, 60); | |||
} | |||
inputFrames[frame].l = clampf(getf(inputs[CARRIER_INPUT]) / 16.0 * 0x8000, -0x8000, 0x7fff); | |||
inputFrames[frame].r = clampf(getf(inputs[MODULATOR_INPUT]) / 16.0 * 0x8000, -0x8000, 0x7fff); | |||
setf(outputs[MODULATOR_OUTPUT], (float)outputFrames[frame].l / 0x8000 * 5.0); | |||
setf(outputs[AUX_OUTPUT], (float)outputFrames[frame].r / 0x8000 * 5.0); | |||
inputFrames[frame].l = clampf(inputs[CARRIER_INPUT].value / 16.0 * 0x8000, -0x8000, 0x7fff); | |||
inputFrames[frame].r = clampf(inputs[MODULATOR_INPUT].value / 16.0 * 0x8000, -0x8000, 0x7fff); | |||
outputs[MODULATOR_OUTPUT].value = (float)outputFrames[frame].l / 0x8000 * 5.0; | |||
outputs[AUX_OUTPUT].value = (float)outputFrames[frame].r / 0x8000 * 5.0; | |||
} | |||