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