66#define ENV_MAX_VOLTAGE 10 .f
77#define MIN_TIME 0 .01f
88#define MAX_TIME 10 .f
9+ #define LAMBDA_BASE MAX_TIME / MIN_TIME
910
1011struct Funcgen : Module {
1112 enum ParamId {
@@ -32,7 +33,6 @@ struct Funcgen : Module {
3233 ENUMS (EOC_OUTPUT , CHANNEL_COUNT ),
3334 ENUMS (TAH_OUTPUT , CHANNEL_COUNT ),
3435 CASCADE_OUTPUT ,
35- CASCADE_EOC_OUTPUT ,
3636 MIN_OUTPUT ,
3737 MAX_OUTPUT ,
3838 AVG_OUTPUT ,
@@ -66,6 +66,7 @@ struct Funcgen : Module {
6666 };
6767 enum LightId {
6868 ENUMS (OUTPUT_LIGHT , CHANNEL_COUNT ),
69+ ENUMS (CASCADE_LIGHT , CHANNEL_COUNT ),
6970 LIGHTS_LEN
7071 };
7172 enum Stage {
@@ -74,15 +75,15 @@ struct Funcgen : Module {
7475 FALLING
7576 };
7677 enum Mode {
77- NORMAL ,
7878 CASCADE ,
7979 CHAOTIC_CASCADE ,
8080 };
8181
8282 Stage stage = IDLE ;
83- Mode mode = NORMAL ;
83+ Mode mode = CASCADE ;
8484
8585 Envelope envelope[CHANNEL_COUNT ];
86+ Envelope cm_envelope[CHANNEL_COUNT ];
8687
8788 float tah_value[CHANNEL_COUNT ];
8889
@@ -93,20 +94,18 @@ struct Funcgen : Module {
9394 dsp::SchmittTrigger trigger_all;
9495 dsp::SchmittTrigger trigger_all_push;
9596 dsp::SchmittTrigger tah_trigger[CHANNEL_COUNT ];
96- dsp::BooleanTrigger normal_mode_trigger;
9797 dsp::BooleanTrigger eoc_trigger[CHANNEL_COUNT ];
98+ dsp::BooleanTrigger cm_eoc_trigger[CHANNEL_COUNT ];
9899 dsp::PulseGenerator eoc_pulse[CHANNEL_COUNT ];
99- dsp::PulseGenerator cascade_eoc_pulse ;
100+ dsp::PulseGenerator cm_eoc_pulse[ CHANNEL_COUNT ] ;
100101
101- bool normal_mode = true ;
102102 int chaos_index = 0 ;
103103
104104 Funcgen () {
105105 config (PARAMS_LEN , INPUTS_LEN , OUTPUTS_LEN , LIGHTS_LEN );
106- configSwitch (MODE_PARAM , 0 .f , 2 .f , 0 .f , " Mode" , {" Normal " , " Cascade" , " Chaotic Cascade" });
106+ configSwitch (MODE_PARAM , 0 .f , 1 .f , 0 .f , " Mode" , {" Cascade" , " Chaotic Cascade" });
107107 configInput (TRIGGER_ALL_INPUT , " Trigger all" );
108108 configParam (TRIGGER_ALL_PARAM , 0 .f , 1 .f , 0 .f , " Trigger all" );
109- configOutput (CASCADE_EOC_OUTPUT , " Cascade EOC" );
110109 configOutput (CASCADE_OUTPUT , " Cascade" );
111110 for (int i = 0 ; i < CHANNEL_COUNT ; i++) {
112111 configParam (RISE_PARAM + i, MIN_TIME , MAX_TIME , 1 .f , " Rise time" , " s" );
@@ -156,16 +155,11 @@ struct Funcgen : Module {
156155
157156 void process (const ProcessArgs& args) override {
158157 float st = args.sampleTime ;
158+
159159 if (params[MODE_PARAM ].getValue () == 0 .f ) {
160- normal_mode = true ;
161- mode = NORMAL ;
162- }
163- else if (params[MODE_PARAM ].getValue () == 1 .f ) {
164- normal_mode = false ;
165160 mode = CASCADE ;
166161 }
167- else if (params[MODE_PARAM ].getValue () == 2 .f ) {
168- normal_mode = false ;
162+ else if (params[MODE_PARAM ].getValue () == 1 .f ) {
169163 mode = CHAOTIC_CASCADE ;
170164 }
171165
@@ -174,24 +168,26 @@ struct Funcgen : Module {
174168 float fall_time = params[FALL_PARAM + i].getValue ();
175169 envelope[i].set_rise (rise_time);
176170 envelope[i].set_fall (fall_time);
171+ cm_envelope[i].set_rise (rise_time);
172+ cm_envelope[i].set_fall (fall_time);
177173
178174 if (inputs[RISE_CV_INPUT ].isConnected ()) {
179175 rise_time = clamp (rise_time * inputs[RISE_CV_INPUT + i].getVoltage () / 10 .f , MIN_TIME , MAX_TIME );
180176 envelope[i].set_rise (rise_time);
177+ cm_envelope[i].set_rise (rise_time);
181178 }
182179
183180 if (inputs[FALL_CV_INPUT ].isConnected ()) {
184181 fall_time = clamp (fall_time * inputs[FALL_CV_INPUT + i].getVoltage () / 10 .f , MIN_TIME , MAX_TIME );
185182 envelope[i].set_fall (fall_time);
183+ cm_envelope[i].set_fall (fall_time);
186184 }
187185
188186 bool loop = params[LOOP_PARAM + i].getValue () > 0 .5f ;
189- envelope[i].set_loop (loop && mode == NORMAL );
187+ envelope[i].set_loop (loop);
190188
191- if (mode == NORMAL ) {
192- if (trigger[i].process (inputs[TRIGGER_INPUT + i].getVoltage ()) || push[i].process (params[PUSH_PARAM + i].getValue ())) {
193- envelope[i].retrigger ();
194- }
189+ if (trigger[i].process (inputs[TRIGGER_INPUT + i].getVoltage ()) || push[i].process (params[PUSH_PARAM + i].getValue ())) {
190+ envelope[i].retrigger ();
195191 }
196192
197193 if (tah_trigger[i].process (inputs[TAH_GATE_INPUT + i].getVoltage ())) {
@@ -206,81 +202,79 @@ struct Funcgen : Module {
206202 }
207203
208204 envelope[i].process (st);
205+ cm_envelope[i].process (st);
209206
210207 if (eoc_trigger[i].process (envelope[i].eoc )) {
211208 eoc_pulse[i].trigger (1e-3f );
212209 }
213210
211+ if (cm_eoc_trigger[i].process (cm_envelope[i].eoc )) {
212+ cm_eoc_pulse[i].trigger (1e-3f );
213+ }
214+
214215 outputs[FUNCTION_OUTPUT + i].setVoltage (envelope[i].env );
215216
216217 bool eoc = eoc_pulse[i].process (st);
218+ bool cm_eoc = cm_eoc_pulse[i].process (st);
217219 outputs[EOC_OUTPUT + i].setVoltage (eoc ? 10 .f : 0 .f );
218- if (eoc && mode == CASCADE ) {
219- envelope[(i + 1 ) % 4 ].retrigger ();
220+ if (mode == CASCADE ) {
221+ if (cm_eoc) {
222+ cm_envelope[(i + 1 ) % CHANNEL_COUNT ].retrigger ();
223+ }
220224 }
221- else if (eoc && mode == CHAOTIC_CASCADE ) {
222- envelope[chaos_index].retrigger ();
225+ else if (mode == CHAOTIC_CASCADE ) {
226+ if (cm_eoc) {
227+ cm_envelope[chaos_index].retrigger ();
228+ }
223229 }
224230 }
225231
226- if (mode == NORMAL ) {
227- if (trigger_all.process (inputs[TRIGGER_ALL_INPUT ].getVoltage ()) || trigger_all_push.process (params[TRIGGER_ALL_PARAM ].getValue ())) {
228- for (int i = 0 ; i < CHANNEL_COUNT ; i++) {
229- envelope[i].retrigger ();
230- }
232+ if (trigger_all.process (inputs[TRIGGER_ALL_INPUT ].getVoltage ()) || trigger_all_push.process (params[TRIGGER_ALL_PARAM ].getValue ())) {
233+ for (int i = 0 ; i < CHANNEL_COUNT ; i++) {
234+ envelope[i].retrigger ();
235+ }
236+ if (mode == CASCADE ) {
237+ cm_envelope[0 ].retrigger ();
238+ }
239+ else if (mode == CHAOTIC_CASCADE ) {
240+ cm_envelope[chaos_index].retrigger ();
231241 }
232242 }
233243
234244 float cascade_output = 0 .f ;
235245 if (mode == CASCADE ) {
236- cascade_output = std::max (envelope [0 ].env , envelope [1 ].env );
237- cascade_output = std::max (cascade_output, envelope [2 ].env );
238- cascade_output = std::max (cascade_output, envelope [3 ].env );
246+ cascade_output = std::max (cm_envelope [0 ].env , cm_envelope [1 ].env );
247+ cascade_output = std::max (cascade_output, cm_envelope [2 ].env );
248+ cascade_output = std::max (cascade_output, cm_envelope [3 ].env );
239249 }
240250 else if (mode == CHAOTIC_CASCADE ) {
241- cascade_output = envelope [chaos_index].env ;
242- if (eoc_pulse [chaos_index].process (st)) {
251+ cascade_output = cm_envelope [chaos_index].env ;
252+ if (cm_eoc_pulse [chaos_index].process (st)) {
243253 int last_index = chaos_index;
244254 while (last_index == chaos_index) {
245255 chaos_index = random::u32 () % CHANNEL_COUNT ;
246256 }
247257 for (int i = 0 ; i < CHANNEL_COUNT ; i++) {
248258 if (i != chaos_index) {
249- envelope [i].reset ();
259+ cm_envelope [i].reset ();
250260 }
251261 }
252262 }
253263 }
254264 outputs[CASCADE_OUTPUT ].setVoltage (cascade_output);
255265
256- if (mode == CASCADE ) {
257- outputs[CASCADE_EOC_OUTPUT ].setVoltage (outputs[EOC_OUTPUT + 3 ].getVoltage ());
258- }
259- else if (mode == CHAOTIC_CASCADE ) {
260- outputs[CASCADE_EOC_OUTPUT ].setVoltage (outputs[EOC_OUTPUT + chaos_index].getVoltage ());
261- }
262- else {
263- outputs[CASCADE_EOC_OUTPUT ].setVoltage (0 .f );
264- }
265-
266- if (normal_mode_trigger.process (normal_mode)) {
267- for (int i = 0 ; i < CHANNEL_COUNT ; i++) {
268- envelope[i].reset ();
269- }
270- }
271-
272266 if (cascade_trigger.process (inputs[CASCADE_TRIGGER_INPUT ].getVoltage () || cascade_push.process (params[CASCADE_TRIGGER_PARAM ].getValue ()))) {
273267 if (mode == CASCADE ) {
274- envelope [0 ].retrigger ();
275- envelope [1 ].reset ();
276- envelope [2 ].reset ();
277- envelope [3 ].reset ();
268+ cm_envelope [0 ].retrigger ();
269+ cm_envelope [1 ].reset ();
270+ cm_envelope [2 ].reset ();
271+ cm_envelope [3 ].reset ();
278272 }
279273 else if (mode == CHAOTIC_CASCADE ) {
280- envelope [chaos_index].retrigger ();
274+ cm_envelope [chaos_index].retrigger ();
281275 for (int i = 0 ; i < CHANNEL_COUNT ; i++) {
282276 if (i != chaos_index) {
283- envelope [i].reset ();
277+ cm_envelope [i].reset ();
284278 }
285279 }
286280 }
@@ -348,6 +342,7 @@ struct Funcgen : Module {
348342
349343 for (int i = 0 ; i < CHANNEL_COUNT ; i++) {
350344 lights[i].setBrightness (envelope[i].env / 10 .f );
345+ lights[CASCADE_LIGHT + i].setBrightness (cm_envelope[i].env / 10 .f );
351346 }
352347 }
353348};
@@ -418,13 +413,16 @@ struct FuncgenWidget : ModuleWidget {
418413 y = box.size .y - (RACK_GRID_WIDTH * 2 );
419414 addParam (createParamCentered<TL1105 >(Vec (x, y), module , Funcgen::CASCADE_TRIGGER_PARAM ));
420415 x += dx;
421- addParam (createParamCentered<CKSSThree >(Vec (x, y), module , Funcgen::MODE_PARAM ));
416+ addParam (createParamCentered<CKSS >(Vec (x, y), module , Funcgen::MODE_PARAM ));
422417 x += dx;
423418 addInput (createInputCentered<PJ301MPort>(Vec (x, y), module , Funcgen::CASCADE_TRIGGER_INPUT ));
424419 x += dx;
425420 addOutput (createOutputCentered<PJ301MPort>(Vec (x, y), module , Funcgen::CASCADE_OUTPUT ));
426421 x += dx;
427- addOutput (createOutputCentered<PJ301MPort>(Vec (x, y), module , Funcgen::CASCADE_EOC_OUTPUT ));
422+ addChild (createLightCentered<LargeLight<RedLight>>(Vec (x, y), module , Funcgen::CASCADE_LIGHT ));
423+ addChild (createLightCentered<LargeLight<GreenLight>>(Vec (x, y), module , Funcgen::CASCADE_LIGHT + 1 ));
424+ addChild (createLightCentered<LargeLight<BlueLight>>(Vec (x, y), module , Funcgen::CASCADE_LIGHT + 2 ));
425+ addChild (createLightCentered<LargeLight<YellowLight>>(Vec (x, y), module , Funcgen::CASCADE_LIGHT + 3 ));
428426 x += dx * 2 ;
429427 addInput (createInputCentered<PJ301MPort>(Vec (x, y), module , Funcgen::TRIGGER_ALL_INPUT ));
430428 x += dx;
0 commit comments