Skip to content

Commit 19c7d58

Browse files
committed
supersaw: finish implementing ADSR envelope
1 parent a2a70de commit 19c7d58

1 file changed

Lines changed: 40 additions & 20 deletions

File tree

src/supersaw.cpp

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ struct Supersaw : Module {
1515
NOISE_DUR_PARAM,
1616
NOISE_MIX_PARAM,
1717
PULSE_WIDTH_PARAM,
18-
RISE_PARAM,
19-
FALL_PARAM,
18+
ATTACK_PARAM,
19+
DECAY_PARAM,
20+
SUSTAIN_PARAM,
21+
RELEASE_PARAM,
2022
ENV_TO_DUR_PARAM,
2123
ENV_TO_MIX_PARAM,
2224
ENV_TO_PW_PARAM,
@@ -29,7 +31,7 @@ struct Supersaw : Module {
2931
VOCT_INPUT,
3032
NOISE_DUR_CV_INPUT,
3133
PULSE_WIDTH_CV_INPUT,
32-
TRIGGER_INPUT,
34+
GATE_INPUT,
3335
INPUTS_LEN
3436
};
3537
enum OutputId {
@@ -48,12 +50,13 @@ struct Supersaw : Module {
4850
Oscillator osc2[MAX_POLY];
4951
Oscillator osc3[MAX_POLY];
5052
Oscillator osc4[MAX_POLY];
51-
ADEnvelope envelope;
53+
ADSREnvelope envelope;
5254
dsp::SchmittTrigger trigger;
5355
float noise_dur = 0.f;
5456
float noise_mix = 0.f;
5557
float last_noise = 0.f;
5658
float noise_time = 0.f;
59+
bool last_gate = false;
5760

5861
Supersaw() {
5962
config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
@@ -69,8 +72,10 @@ struct Supersaw : Module {
6972
configParam(NOISE_MIX_PARAM, 0.0, 0.5, 0.0, "Noise mix", "%", 0.0, 100.0);
7073
configParam(PULSE_WIDTH_PARAM, 0.0, 1.0, 0.5, "Pulse width");
7174
configInput(PULSE_WIDTH_CV_INPUT, "Pulse width CV");
72-
configParam(RISE_PARAM, 0.01, 5.0, 1.0, "Rise time", " s");
73-
configParam(FALL_PARAM, 0.01, 5.0, 1.0, "Fall time", " s");
75+
configParam(ATTACK_PARAM, 0.01, 5.0, 0.01, "Attack time", " s");
76+
configParam(DECAY_PARAM, 0.1, 5.0, 0.1, "Decay time", " s");
77+
configParam(SUSTAIN_PARAM, 0.0, 1.0, 1.0, "Sustain level");
78+
configParam(RELEASE_PARAM, 0.01, 5.0, 0.01, "Release time", " s");
7479
configSwitch(ENV_TO_DUR_PARAM, 0.0, 1.0, 0.0, "Env -> Noise duration", {"Off", "On"});
7580
configSwitch(ENV_TO_MIX_PARAM, 0.0, 1.0, 0.0, "Env -> Noise mix", {"Off", "On"});
7681
configSwitch(ENV_TO_PW_PARAM, 0.0, 1.0, 0.0, "Env -> Pulse width", {"Off", "On"});
@@ -83,7 +88,7 @@ struct Supersaw : Module {
8388
configOutput(WAVE_OUTPUT + i, "Wave " + std::to_string(i + 1));
8489
}
8590
configOutput(NOISE_OUTPUT, "Noise");
86-
configInput(TRIGGER_INPUT, "Trigger");
91+
configInput(GATE_INPUT, "Trigger");
8792
configOutput(ENV_OUTPUT, "Envelope");
8893
configOutput(VCA_OUTPUT, "VCA");
8994
}
@@ -109,19 +114,24 @@ struct Supersaw : Module {
109114
pulse_width = clamp(pulse_width + pulse_width_cv, 0.1f, 0.9f);
110115
noise_dur = clamp(noise_dur + noise_dur_cv, 0.f, 0.001f);
111116
float noise_mix = params[NOISE_MIX_PARAM].getValue();
112-
float rise_time = params[RISE_PARAM].getValue();
113-
float fall_time = params[FALL_PARAM].getValue();
117+
float attack_time = params[ATTACK_PARAM].getValue();
118+
float decay_time = params[DECAY_PARAM].getValue();
119+
float sustain_level = params[SUSTAIN_PARAM].getValue();
120+
float release_time = params[RELEASE_PARAM].getValue();
114121
bool env_to_dur = params[ENV_TO_DUR_PARAM].getValue() > 0.5;
115122
bool env_to_mix = params[ENV_TO_MIX_PARAM].getValue() > 0.5;
116123
bool env_to_pw = params[ENV_TO_PW_PARAM].getValue() > 0.5;
117124
float env_dur_att = params[ENV_DUR_ATT_PARAM].getValue();
118125
float env_mix_att = params[ENV_MIX_ATT_PARAM].getValue();
119126
float env_pw_att = params[ENV_PW_ATT_PARAM].getValue();
120127

121-
envelope.set_rise(rise_time);
122-
envelope.set_fall(fall_time);
123-
envelope.set_rise_shape(-0.5);
124-
envelope.set_fall_shape(-0.5);
128+
envelope.set_attack(attack_time);
129+
envelope.set_attack_shape(-0.5);
130+
envelope.set_decay(decay_time);
131+
envelope.set_decay_shape(-0.5);
132+
envelope.set_sustain(sustain_level);
133+
envelope.set_release(release_time);
134+
envelope.set_release_shape(-0.5);
125135

126136
if (env_to_dur) {
127137
noise_dur += envelope.env * env_dur_att * 0.001;
@@ -181,12 +191,18 @@ struct Supersaw : Module {
181191

182192
}
183193

184-
if (trigger.process(inputs[TRIGGER_INPUT].getVoltage())) {
185-
envelope.trigger();
194+
if (trigger.process(inputs[GATE_INPUT].getVoltage())) {
195+
envelope.retrigger();
196+
}
197+
198+
if (last_gate && !(inputs[GATE_INPUT].getVoltage() > 0.5)) {
199+
envelope.stage = envelope.RELEASE;
186200
}
187201

188202
envelope.process(args.sampleTime);
189203

204+
last_gate = inputs[GATE_INPUT].getVoltage();
205+
190206
for (int c = 0; c < channels; c++) {
191207
outputs[VCA_OUTPUT].setVoltage(clamp(outputs[SIGNAL_OUTPUT].getVoltage(c) * envelope.env, -10.f, 10.f), c);
192208
}
@@ -207,7 +223,7 @@ struct SupersawWidget : ModuleWidget {
207223
addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
208224
addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
209225

210-
float x_start = RACK_GRID_WIDTH * 2;
226+
float x_start = RACK_GRID_WIDTH;
211227
float y_start = RACK_GRID_WIDTH * 3;
212228
float dx = RACK_GRID_WIDTH * 2;
213229
float dy = RACK_GRID_WIDTH * 2;
@@ -254,12 +270,16 @@ struct SupersawWidget : ModuleWidget {
254270
}
255271
x -= dx * 3;
256272
y += dy;
257-
addParam(createParamCentered<RoundSmallBlackKnob>(Vec(x, y), module, Supersaw::RISE_PARAM));
273+
addParam(createParamCentered<RoundSmallBlackKnob>(Vec(x, y), module, Supersaw::ATTACK_PARAM));
258274
x += dx;
259-
addParam(createParamCentered<RoundSmallBlackKnob>(Vec(x, y), module, Supersaw::FALL_PARAM));
260-
x -= dx;
275+
addParam(createParamCentered<RoundSmallBlackKnob>(Vec(x, y), module, Supersaw::DECAY_PARAM));
276+
x += dx;
277+
addParam(createParamCentered<RoundSmallBlackKnob>(Vec(x, y), module, Supersaw::SUSTAIN_PARAM));
278+
x += dx;
279+
addParam(createParamCentered<RoundSmallBlackKnob>(Vec(x, y), module, Supersaw::RELEASE_PARAM));
280+
x -= dx * 3;
261281
y += dy;
262-
addInput(createInputCentered<PJ301MPort>(Vec(x, y), module, Supersaw::TRIGGER_INPUT));
282+
addInput(createInputCentered<PJ301MPort>(Vec(x, y), module, Supersaw::GATE_INPUT));
263283
x += dx;
264284
addOutput(createOutputCentered<PJ301MPort>(Vec(x, y), module, Supersaw::VCA_OUTPUT));
265285
x += dx;

0 commit comments

Comments
 (0)