| @@ -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; | |||
| } | |||