<|start_filename|>src/CHOKE.cpp<|end_filename|>
#include "plugin.hpp"



using namespace std;


struct CHOKE : Module {
	enum ParamIds {
		PAN_PARAM,
		NUM_PARAMS 
	};
	enum InputIds {
		TRIG1_INPUT,
		TRIG2_INPUT,
		IN1_INPUT,
		IN2_INPUT,
		NUM_INPUTS
	};
	enum OutputIds {
		OUT_OUTPUT,
		NUM_OUTPUTS
	};
	enum LightIds {
		L1_LIGHT,
		L2_LIGHT,
		NUM_LIGHTS
	};
	
	bool play = false;
	dsp::SchmittTrigger tr1Trigger;
	dsp::SchmittTrigger tr2Trigger;

CHOKE()  { 
		config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
		configParam(PAN_PARAM, -1.0f, 1.0f, 0.0f, "Mix");
configInput(TRIG1_INPUT, "Select signal 1 trigger");
configInput(TRIG2_INPUT, "Select signal 2 trigger");
configInput(IN1_INPUT, "Signal 1");
configInput(IN2_INPUT, "Signal 2");
configOutput(OUT_OUTPUT, "Signal");
configBypass(IN1_INPUT, OUT_OUTPUT);
}


void process(const ProcessArgs &args) override {

	if (tr1Trigger.process(inputs[TRIG1_INPUT].getVoltage()))
		{
		play = false ;

		};
	if (tr2Trigger.process(inputs[TRIG2_INPUT].getVoltage()))
		{
		play = true ;

		};
	if (play) 
		outputs[OUT_OUTPUT].setVoltage(inputs[IN2_INPUT].getVoltage()*(1-clamp(-params[PAN_PARAM].getValue(),0.0f,1.0f)));
			else outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage()*(1-clamp(params[PAN_PARAM].getValue(),0.0f,1.0f))); 
		
	lights[L1_LIGHT].setBrightness(!play);
	lights[L2_LIGHT].setBrightness(play);
}
};



struct CHOKEWidget : ModuleWidget {
	CHOKEWidget(CHOKE *module) {
	setModule(module);
	
	setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CHOKE.svg")));


	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));

 	addParam(createParam<Trimpot>(Vec(6, 298), module, CHOKE::PAN_PARAM));

	addInput(createInput<PJ301MPort>(Vec(3, 61), module, CHOKE::IN1_INPUT));
	addInput(createInput<PJ301MPort>(Vec(3, 91), module, CHOKE::TRIG1_INPUT));

	addInput(createInput<PJ301MPort>(Vec(3, 181), module, CHOKE::IN2_INPUT));
	addInput(createInput<PJ301MPort>(Vec(3, 211), module, CHOKE::TRIG2_INPUT));

	addChild(createLight<LargeLight<BlueLight>>(Vec(8, 136), module, CHOKE::L1_LIGHT));
	addChild(createLight<LargeLight<BlueLight>>(Vec(8, 256), module, CHOKE::L2_LIGHT));


	addOutput(createOutput<PJ301MPort>(Vec(3, 321), module, CHOKE::OUT_OUTPUT));

}
};


Model *modelCHOKE = createModel<CHOKE, CHOKEWidget>("CHOKE");


<|start_filename|>src/DISTO.cpp<|end_filename|>

#include "plugin.hpp"



struct DISTO : Module {
	enum ParamIds {
		FOLD_PARAM,
		GAIN_PARAM,
		NUM_PARAMS
	};
	enum InputIds {
		IN_INPUT,
		GAIN_INPUT,
		FOLD_INPUT,
		NUM_INPUTS
		
	};
	enum OutputIds {
		X_OUTPUT,
		NUM_OUTPUTS
	};


	float x = 0;
	float y = 0;
	int length = 0;
	float fold_gain ;
	int fold_affi ;
	float gain_gain ;
	int gain_affi ;

	DISTO(){
		config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
		configParam(GAIN_PARAM, 0.0f, 10.0f, 0.2f, "Gain");
		configParam(FOLD_PARAM, 0.0f, 10.0f, 0.0f, "Fold");
		configInput(IN_INPUT, "Signal");
		configInput(GAIN_INPUT, "Gain control");
		configInput(FOLD_INPUT, "Fold control");
		configOutput(X_OUTPUT, "Signal");
		configBypass(IN_INPUT, X_OUTPUT);
}


void process(const ProcessArgs &args) override {

	if (inputs[FOLD_INPUT].isConnected()) {
		fold_affi =true; fold_gain = clamp(inputs[FOLD_INPUT].getVoltage(),-0.001,10.001) ;} 
	 else {fold_affi =false; fold_gain = params[FOLD_PARAM].getValue() ;}

	if (inputs[GAIN_INPUT].isConnected()) {
		gain_affi =true; gain_gain = clamp(inputs[GAIN_INPUT].getVoltage(),-0.001,10.001) ;} 
	 else {gain_affi =false; gain_gain = params[GAIN_PARAM].getValue() ;}

//////////DISTO
	x=inputs[IN_INPUT].getVoltage()*5.0f*gain_gain;

	if (abs(x)>5) y = clamp((abs(x)-5)/2.2f,0.0f,58.0f); else y=0;

	for (int i =0; i<100; i++) {	if (x<-5.0f) x=-5.0f+(-x-5.0f)*fold_gain/5.0; 
					if (x>5.0f) x=5.0f-(x-5.0f)*fold_gain/5.0;
					if ((x>=-5.0) & (x<=5.0)) i=1000; if (i==99) x=0;}
	

	//float fold;
        //const float bias = (x < 0) ? -5.f : 5.f;
        //int phase = int((x + bias) / 10.f);
        //bool isEven = !(phase & 1);
        //if (isEven) {
        //    fold = x - 10.f * phase;
        //} else {
        //    fold = -x + 10.f * phase;
        //}

 	//x = ((int(x/5.0)%2)*2-1)*(x%5) + (int(x/5.0)%2)*5.0 ;

	//int xa ; float xb, xc;
	//xa=int(x/5.0) ;
	//xb=int(xa-2.0*int(xa/2.0)) ;
	//if (xb == 0) xc = (x-5*xa) ; else xc= xb*5.0 - abs(xb)*(x-5*xa) ;                //+5.0*(2*xb-1) ;

	outputs[X_OUTPUT].setVoltage(x);                      //clamp(x,-5.0f,5.0f); 

}
};

struct cachecl : SvgScrew {
	cachecl() {
		setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/distocach.svg")));
		box.size = sw->box.size;
	}
};

struct DISTODisplay : TransparentWidget {
	DISTO *module;

		float bu[10] = {};
	int ind = 0;
		

	DISTODisplay() {

	}
void draw(const DrawArgs &args) override {
		for (int i = 0 ; i<5 ; i++){
			if (bu[i]>=27)
			{//nvgStrokeColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff));
			nvgBeginPath(args.vg);
			nvgCircle(args.vg, 0,0, bu[i]);
			nvgFillColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xaa));
			nvgGlobalCompositeOperation(args.vg, NVG_LIGHTER);
			nvgFill(args.vg);
			nvgClosePath(args.vg);
			}
		}
}

void drawLayer(const DrawArgs &args, int layer) override {


float xxxx = module ? module->y : 1.0f;

for (int i = 4 ; i>0 ; i--){bu[i] = bu[i-1] ;}
		bu[0] = xxxx ;
if (layer ==1) {
		for (int i = 0 ; i<5 ; i++){
			if (bu[i]<27)
			{//nvgStrokeColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff));
			nvgBeginPath(args.vg);
			nvgCircle(args.vg, 0,0, bu[i]);
			nvgFillColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xaa));
			nvgGlobalCompositeOperation(args.vg, NVG_LIGHTER);
			nvgFill(args.vg);
			nvgClosePath(args.vg);
			}else
{//nvgStrokeColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff));
			nvgBeginPath(args.vg);
			nvgCircle(args.vg, 0,0, 27);
			nvgFillColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xaa));
			nvgGlobalCompositeOperation(args.vg, NVG_LIGHTER);
			nvgFill(args.vg);
			nvgClosePath(args.vg);
			}
		}
		//nvgStroke(args.vg);
	}
Widget::drawLayer(args, layer);
};
};

struct MOGAINDisplay : TransparentWidget {
	DISTO *module;

	MOGAINDisplay() {
		
	}
	
	void draw(const DrawArgs &args) override {
//nvgGlobalTint(args.vg, color::WHITE);
float gainX = module ? module->gain_gain : 1.0f;
//int affich = module ? module->gain_affi : 0;
float d=8;

		//if (affich==1) {
		float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ;
		float yy = d*cos((gainX*0.17+0.15)*M_PI) ;
		float xx0 = (d-6)*sin(-(gainX*0.17+0.15)*M_PI) ;
		float yy0 = (d-6)*cos((gainX*0.17+0.15)*M_PI) ;

			//nvgBeginPath(args.vg);
			//nvgCircle(args.vg, 0,0, d);
			//nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff));
			//nvgFill(args.vg);	
		
			nvgStrokeWidth(args.vg,2);
			nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88));
			{
				nvgBeginPath(args.vg);
				nvgMoveTo(args.vg, xx0,yy0);
				nvgLineTo(args.vg, xx,yy);
				nvgClosePath(args.vg);
			}
			nvgStroke(args.vg);
		//}

	}
};

struct MOFOLDDisplay : TransparentWidget {
	DISTO *module;

	MOFOLDDisplay() {
		
	}
	
	void draw(const DrawArgs &args) override {
//nvgGlobalTint(args.vg, color::WHITE);
float gainX = module ? module->fold_gain : 1.0f;
//int affich = module ? module->fold_affi : 0;
float d=8;

		//if (affich==1) {
		float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ;
		float yy = d*cos((gainX*0.17+0.15)*M_PI) ;
		float xx0 = (d-6)*sin(-(gainX*0.17+0.15)*M_PI) ;
		float yy0 = (d-6)*cos((gainX*0.17+0.15)*M_PI) ;

		
			//nvgBeginPath(args.vg);
			//nvgCircle(args.vg, 0,0, d);
			//nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff));
			//nvgFill(args.vg);	
		
			nvgStrokeWidth(args.vg,2);
			nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88));
			{
				nvgBeginPath(args.vg);
				nvgMoveTo(args.vg, xx0,yy0);
				nvgLineTo(args.vg, xx,yy);
				nvgClosePath(args.vg);
			}
			nvgStroke(args.vg);
		//}

	}
};

struct DISTOWidget : ModuleWidget {
	DISTOWidget(DISTO *module){
		setModule(module);
		setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/DISTO.svg")));


	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 0)));
	addChild(createWidget<ScrewSilver>(Vec(15, 365)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));

	{
		DISTODisplay *distdisplay = new DISTODisplay();
			distdisplay->box.pos = Vec(60, 170);
			distdisplay->module = module ;	
		addChild(distdisplay);
	}

	addInput(createInput<PJ301MPort>(Vec(15, 321), module, DISTO::IN_INPUT));

	addInput(createInput<PJ301MPort>(Vec(47, 321), module, DISTO::GAIN_INPUT));
	addParam(createParam<cfTrimpot>(Vec(50.4, 284), module, DISTO::GAIN_PARAM));
	{
		MOGAINDisplay *gaindisplay = new MOGAINDisplay();
		gaindisplay->box.pos = Vec(59.4, 293);
		gaindisplay->module = module;
		addChild(gaindisplay);
	}
	addInput(createInput<PJ301MPort>(Vec(80, 321), module, DISTO::FOLD_INPUT));
	addParam(createParam<cfTrimpot>(Vec(83.4, 284), module, DISTO::FOLD_PARAM)); 
	{
		MOFOLDDisplay *folddisplay = new MOFOLDDisplay();
		folddisplay->box.pos = Vec(92.4, 293);
		folddisplay->module = module;
		addChild(folddisplay);
	}
	addOutput(createOutput<PJ301MPort>(Vec(80, 31), module, DISTO::X_OUTPUT)); 
		addChild(createWidget<cachecl>(Vec(0, 0)));
}
};

Model *modelDISTO = createModel<DISTO, DISTOWidget>("DISTO");

<|start_filename|>src/VARIABLE.cpp<|end_filename|>
#include "plugin.hpp"





using namespace std;


struct VARIABLE : Module {
	enum ParamIds {
		PREV_PARAM,
		NEXT_PARAM,
		HOLD_PARAM,
		NUM_PARAMS 
	};
	enum InputIds {
		IN_INPUT,
		TRIG_INPUT,
		NUM_INPUTS
	};
	enum OutputIds {
		OUT_OUTPUT,
		NUM_OUTPUTS
	};
	enum LightIds {
		HOLD_LIGHT,
		NUM_LIGHTS
	};
	

	bool lock = false ;
	bool plugged = false ;
	float value = 0;
	dsp::SchmittTrigger trigTrigger;
	dsp::SchmittTrigger holdTrigger;
	dsp::SchmittTrigger nextTrigger;
	dsp::SchmittTrigger prevTrigger;

VARIABLE(){ 
	config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
	configButton(PREV_PARAM, "-1");
	configButton(NEXT_PARAM, "+1");
	configButton(HOLD_PARAM, "Hold value");
	configInput(IN_INPUT,"Value");
	configInput(TRIG_INPUT,"Value hold trigger");
	configOutput(OUT_OUTPUT,"Value");
}


	
json_t *dataToJson() override {
		json_t *rootJ = json_object();
		
		json_object_set_new(rootJ, "loc", json_integer(lock));
		json_object_set_new(rootJ, "plu", json_integer(plugged));
		json_object_set_new(rootJ, "val", json_real(value));
		return rootJ;
		}

void dataFromJson(json_t *rootJ) override {
		
		json_t *locJ = json_object_get(rootJ, "loc");
		if (locJ)
			lock = json_integer_value(locJ);

		json_t *pluJ = json_object_get(rootJ, "plu");
		if (pluJ)
			plugged = json_integer_value(pluJ);

		json_t *valJ = json_object_get(rootJ, "val");
		if (valJ)
			value = json_real_value(valJ);
	
	}




void process(const ProcessArgs &args) override {

	if (inputs[IN_INPUT].isConnected() & !plugged) {plugged = true; lock = false;}
	if (!inputs[IN_INPUT].isConnected()) {plugged = false;}

	if (inputs[IN_INPUT].isConnected() & !lock) value = inputs[IN_INPUT].getVoltage();


		if ( ( holdTrigger.process(params[HOLD_PARAM].getValue()) or trigTrigger.process(inputs[TRIG_INPUT].getVoltage()) ) & inputs[IN_INPUT].isConnected()) 
			{
			value = inputs[IN_INPUT].getVoltage();
			lock = true;
			}
	

		if (nextTrigger.process(params[NEXT_PARAM].getValue()))
			{
			if ((value<0)&(value!=int(value))) value = int(value) ; else value = int(value+1);
			}
				
			
		if (prevTrigger.process(params[PREV_PARAM].getValue()))
			{
			if ((value>=0)&(value!=int(value))) value = int(value) ; else value = int(value-1);
			} 

		
	lights[HOLD_LIGHT].setBrightness(lock) ;
	outputs[OUT_OUTPUT].setVoltage(value) ;
		
}
};
struct upButton : app::SvgSwitch {
	upButton() {
		momentary = true;
		addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/upButton.svg")));
		addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/upButtonDown.svg")));
	}
};
struct downButton : app::SvgSwitch {
	downButton() {
		momentary = true;
		addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/downButton.svg")));
		addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/downButtonDown.svg")));
	};
};

struct VARIABLEDisplay : TransparentWidget {
	VARIABLE *module;

	int frame = 0;
	

	VARIABLEDisplay() {
    		
	};
	
	void drawLayer(const DrawArgs &args, int layer) override {
if (layer ==1) {
std::shared_ptr<Font> font = APP->window->loadFont(asset::plugin(pluginInstance, "res/LEDCalculator.ttf"));
float val = module ? module->value : 0;
		std::string to_display = "";
		std::string fileDesc = "";
		if (val>=0) 
			fileDesc = "+" + std::to_string(val); else fileDesc = std::to_string(val);
		for (int i=0; i<9; i++) to_display = to_display + fileDesc[i];
		nvgFontSize(args.vg, 24);
		nvgFontFaceId(args.vg, font->handle);
		nvgTextLetterSpacing(args.vg, 0);
		nvgFillColor(args.vg, nvgRGBA(0x4c, 0xc7, 0xf3, 0xff));
		nvgRotate(args.vg, -M_PI / 2.0f);	
		nvgTextBox(args.vg, 5, 5,350, to_display.c_str(), NULL);
	}
Widget::drawLayer(args, layer);
}
};


struct VARIABLEWidget : ModuleWidget {
	VARIABLEWidget(VARIABLE *module){
		setModule(module);
		setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/VARIABLE.svg")));


	
	{
		VARIABLEDisplay *gdisplay = new VARIABLEDisplay();
		gdisplay->box.pos = Vec(18, 268);
		gdisplay->box.size = Vec(130, 250);
		gdisplay->module = module;
		addChild(gdisplay);
	}


	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));

	addInput(createInput<PJ301MPort>(Vec(3, 31), module, VARIABLE::IN_INPUT));
	addInput(createInput<PJ301MPort>(Vec(3, 96), module, VARIABLE::TRIG_INPUT));
	addParam(createParam<LEDButton>(Vec(6, 66+3), module, VARIABLE::HOLD_PARAM));
		addChild(createLight<MediumLight<BlueLight>>(Vec(6+4.4, 69+4.4), module, VARIABLE::HOLD_LIGHT));

	addOutput(createOutput<PJ301MPort>(Vec(3, 321), module, VARIABLE::OUT_OUTPUT));

	addParam(createParam<upButton>(Vec(6, 296+2), module, VARIABLE::PREV_PARAM));
	addParam(createParam<downButton>(Vec(6, 276+2), module, VARIABLE::NEXT_PARAM));
}
};

Model *modelVARIABLE = createModel<VARIABLE, VARIABLEWidget>("VARIABLE");


<|start_filename|>src/plugin.hpp<|end_filename|>
#include "rack.hpp"

using namespace rack;


extern Plugin *pluginInstance;

struct cfBigKnob : RoundKnob {
	cfBigKnob() {
		setSvg(Svg::load(asset::plugin(pluginInstance,"res/cfBigKnob.svg")));
		bg->setSvg(Svg::load(asset::plugin(pluginInstance,"res/cfBigKnob-bg.svg")));
	}

};

struct cfTrimpot : RoundKnob {
	cfTrimpot() {
		setSvg(Svg::load(asset::plugin(pluginInstance,"res/cfTrimpot.svg")));
		bg->setSvg(Svg::load(asset::plugin(pluginInstance,"res/cfTrimpot-bg.svg")));
	}

};

////////////////////
// module widgets
////////////////////

extern Model *modelMETRO;
extern Model *modelEACH;
extern Model *modeltrSEQ;
extern Model *modelLEDSEQ;
extern Model *modelL3DS3Q;
extern Model *modelSLIDERSEQ;
extern Model *modelPLAYER;
extern Model *modelPLAY;
extern Model *modelMONO;
extern Model *modelSTEREO;
extern Model *modelSUB;
extern Model *modelMASTER;
extern Model *modelVARIABLE;
extern Model *modelALGEBRA;
extern Model *modelFUNKTION;
extern Model *modelCHOKE;
extern Model *modelFOUR;
extern Model *modelSTEPS;
extern Model *modelPEAK;
extern Model *modelCUTS;
extern Model *modelBUFFER;
extern Model *modelDISTO;
extern Model *modelCUBE;
extern Model *modelPATCH;
extern Model *modelLABEL;
extern Model *modelDAVE;


<|start_filename|>src/DAVE.cpp<|end_filename|>
#include "plugin.hpp"


struct DAVE : Module {
	enum ParamIds {
		
		NUM_PARAMS
	};
	enum InputIds {

		NUM_INPUTS
	};
	enum OutputIds {

		NUM_OUTPUTS
	};


	DAVE() {
		config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
	}

};



struct DAVEWidget : ModuleWidget {
	DAVEWidget(DAVE *module) {
setModule(module);
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/DAVE.svg")));
}
};


Model *modelDAVE = createModel<DAVE, DAVEWidget>("DAVE");


<|start_filename|>src/FOUR.cpp<|end_filename|>
#include "plugin.hpp"


struct FOUR : Module {
	enum ParamIds {
       		ENUMS(S_PARAM,4),
        	ENUMS(M_PARAM,4),
		NUM_PARAMS
	};
	enum InputIds {
		ENUMS(TRM_INPUT,4),
		ENUMS(TRS_INPUT,4),
		ENUMS(IN_INPUT,4),
		NUM_INPUTS
	};
	enum OutputIds {
		ENUMS(OUT_OUTPUT,4),
		NUM_OUTPUTS
	};
    enum LightIds {
		ENUMS(M_LIGHT,4),
		ENUMS(S_LIGHT,4),
		NUM_LIGHTS
	};


bool muteState[8] = {};
int solo = 0;
int cligno = 0;

dsp::SchmittTrigger muteTrigger[8];
dsp::SchmittTrigger soloTrigger[8];


	FOUR() {
		config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
	for (int i = 0; i < 4; i++) {
		configButton(M_PARAM + i,"Mute "+std::to_string(i+1));
		configButton(S_PARAM + i,"Solo "+std::to_string(i+1));
		configInput(IN_INPUT+i,"Number "+std::to_string(i+1));
		configInput(TRM_INPUT+i,"Mute trigger "+std::to_string(i+1));
		configInput(TRS_INPUT+i,"Solo trigger "+std::to_string(i+1));
		configOutput(OUT_OUTPUT+i,"Number "+std::to_string(i+1));
	}
	onReset();
}

void onReset() override {
		for (int i = 0; i < 4; i++) {
			muteState[i] = true;
			muteState[i+4] = false;
		}
		solo = 0;
		
		
	}

void onRandomize() override {
		for (int i = 0; i < 8; i++) {
			muteState[i] = (random::uniform() < 0.5);
		}
	}

json_t *dataToJson() override {
		json_t *rootJ = json_object();
		
		// states
		json_t *mutestatesJ = json_array();
		for (int i = 0; i < 8; i++) {
			json_t *mutestateJ = json_boolean(muteState[i]);
			json_array_append_new(mutestatesJ, mutestateJ);
			}
		json_object_set_new(rootJ, "mutestates", mutestatesJ);

		// solo
		json_object_set_new(rootJ, "solo", json_integer(solo));
		return rootJ;
		}

void dataFromJson(json_t *rootJ) override {
		
		// states
		json_t *mutestatesJ = json_object_get(rootJ, "mutestates");
		if (mutestatesJ) {
			for (int i = 0; i < 8; i++) {
				json_t *mutestateJ = json_array_get(mutestatesJ, i);
				if (mutestateJ)
					muteState[i] = json_boolean_value(mutestateJ);
			}
		}
		// solo
		json_t *soloJ = json_object_get(rootJ, "solo");
		if (soloJ)
			solo = json_integer_value(soloJ);
	
	}





void process(const ProcessArgs &args) override {
		
	for (int i = 0; i < 4; i++) {
	
		if (soloTrigger[i].process(params[S_PARAM + i].getValue())+soloTrigger[i+4].process(inputs[TRS_INPUT + i].getVoltage()))
			{
			muteState[i+4] ^= true;
			solo = (i+1)*muteState[i+4];
			};		
		if (solo==i+1)
		{
			float in = inputs[IN_INPUT + i].getVoltage();
			outputs[OUT_OUTPUT + i].setVoltage(in);
			
		} else {muteState[i+4] = false;lights[S_LIGHT + i].setBrightness(0);outputs[OUT_OUTPUT + i].setVoltage(0.0);}
		if (muteState[i+4]==true)
		{
			cligno = cligno + 1;
			if (cligno ==10000) {lights[S_LIGHT + i].setBrightness(!lights[S_LIGHT + i].getBrightness());cligno =0;}
		}		
	}

	for (int i = 0; i < 4; i++) {
		if (muteTrigger[i].process(params[M_PARAM + i].getValue())+muteTrigger[i+4].process(inputs[TRM_INPUT + i].getVoltage()))
			muteState[i] ^= true;
		float in = inputs[IN_INPUT + i].getVoltage();
		if (solo == 0) outputs[OUT_OUTPUT + i].setVoltage(muteState[i] ? in : 0.0);
		lights[M_LIGHT + i].setBrightness(muteState[i]);
	}

	
}
};

struct FOURWidget : ModuleWidget {
	FOURWidget(FOUR *module) {
		setModule(module);
		setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/FOUR.svg")));

	int y = 56;


	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 0)));
	addChild(createWidget<ScrewSilver>(Vec(15, 365)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));

	for (int i = 0; i < 4; i++) {

	  addInput(createInput<PJ301MPort>(Vec(15, y), module, FOUR::IN_INPUT + i));

	  addInput(createInput<PJ301MPort>(Vec(21, y+25), module, FOUR::TRS_INPUT + i));
        	addParam(createParam<LEDButton>(Vec(45, y+4), module, FOUR::S_PARAM + i));
		addChild(createLight<MediumLight<BlueLight>>(Vec(45+4.4, y+8.4), module, FOUR::S_LIGHT + i));

	  addInput(createInput<PJ301MPort>(Vec(46, y+31), module, FOUR::TRM_INPUT + i));
   		addParam(createParam<LEDButton>(Vec(70, y+4), module, FOUR::M_PARAM + i));
 		addChild(createLight<MediumLight<BlueLight>>(Vec(70+4.4, y+8.4), module, FOUR::M_LIGHT + i));

	  addOutput(createOutput<PJ301MPort>(Vec(95, y), module, FOUR::OUT_OUTPUT + i));

	  y = y + 75 ;
	}
	
}
};

Model *modelFOUR = createModel<FOUR, FOURWidget>("FOUR");

<|start_filename|>src/PATCH.cpp<|end_filename|>
#include "plugin.hpp"


struct PATCH : Module {

	enum ParamIds {
		NUM_PARAMS
	};
	enum InputIds {
		L_INPUT,
		R_INPUT,
		M1_INPUT,
		M2_INPUT,
		M3_INPUT,
		ENUMS(IN_INPUT,8),
		NUM_INPUTS
	};
	enum OutputIds {
		L_OUTPUT,
		R_OUTPUT,
		M1_OUTPUT,
		M2_OUTPUT,
		M3_OUTPUT,
		ENUMS(OUT_OUTPUT,8),
		NUM_OUTPUTS
	};
   	enum LightIds {
		NUM_LIGHTS
	};






PATCH() {
		config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS,NUM_LIGHTS);
};


void process(const ProcessArgs &args) override {

	outputs[L_OUTPUT].setVoltage(inputs[L_INPUT].getVoltage());
	outputs[R_OUTPUT].setVoltage(inputs[R_INPUT].getVoltage());

	outputs[M1_OUTPUT].setVoltage(inputs[M1_INPUT].getVoltage()+inputs[M2_INPUT].getVoltage()+inputs[M3_INPUT].getVoltage());
	outputs[M2_OUTPUT].setVoltage(inputs[M1_INPUT].getVoltage()+inputs[M2_INPUT].getVoltage()+inputs[M3_INPUT].getVoltage());
	outputs[M3_OUTPUT].setVoltage(inputs[M1_INPUT].getVoltage()+inputs[M2_INPUT].getVoltage()+inputs[M3_INPUT].getVoltage());

	for (int i = 0; i < 8; i++) {
		if (inputs[IN_INPUT + i].isConnected()) outputs[OUT_OUTPUT + i].setVoltage(inputs[IN_INPUT + i].getVoltage());
			else outputs[OUT_OUTPUT + i].setVoltage(0);	
		}
	
};
};



struct PATCHWidget : ModuleWidget {
	PATCHWidget(PATCH *module) {
	setModule(module);
	setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/PATCH.svg")));


	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 0)));
	addChild(createWidget<ScrewSilver>(Vec(15, 365)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));

	addInput(createInput<PJ301MPort>(Vec(10, 171), module, PATCH::L_INPUT));
	addInput(createInput<PJ301MPort>(Vec(40, 171), module, PATCH::R_INPUT));
	addOutput(createOutput<PJ301MPort>(Vec(70, 171), module, PATCH::L_OUTPUT));
	addOutput(createOutput<PJ301MPort>(Vec(100, 171), module, PATCH::R_OUTPUT));

	addInput(createInput<PJ301MPort>(Vec(15, 61), module, PATCH::M1_INPUT));
	addInput(createInput<PJ301MPort>(Vec(55, 41), module, PATCH::M2_INPUT));
	addInput(createInput<PJ301MPort>(Vec(95, 71), module, PATCH::M3_INPUT));

	addOutput(createOutput<PJ301MPort>(Vec(40, 121), module, PATCH::M1_OUTPUT));
	addOutput(createOutput<PJ301MPort>(Vec(55, 81), module, PATCH::M2_OUTPUT));
	addOutput(createOutput<PJ301MPort>(Vec(80, 111), module, PATCH::M3_OUTPUT));

for (int i = 0; i < 8; i++) {

	addInput(createInput<PJ301MPort>(Vec(10+(i-4*floor(i/4))*30, 231+60*floor(i/4)), module, PATCH::IN_INPUT + i));
	addOutput(createOutput<PJ301MPort>(Vec(10+(i-4*floor(i/4))*30, 261+60*floor(i/4)), module, PATCH::OUT_OUTPUT + i));

	
}
}
	
};

Model *modelPATCH = createModel<PATCH, PATCHWidget>("PATCH");


<|start_filename|>src/PEAK.cpp<|end_filename|>
#include "plugin.hpp"


struct PEAK : Module {
	enum ParamIds {
		TRESHOLD_PARAM,
        	GAIN_PARAM,
		NUM_PARAMS
	};
	enum InputIds {
		LIN1_INPUT,
		IN1_INPUT,
		IN2_INPUT,
		NUM_INPUTS
	};
	enum OutputIds {
		OUT1_OUTPUT,
		OUT2_OUTPUT,
		NUM_OUTPUTS
	};
    enum LightIds {
		TRESHOLD_LIGHT,
		OVER_LIGHT,
		NUM_LIGHTS
	};
float max_GAIN = 1.0 ;
int affich = 1 ;
int reman_t = 0;
int reman_o = 0;
int sensiv = 10000;


	PEAK() {
		config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
		configParam(GAIN_PARAM, 0.0f, 10.0f, 1.0f, "Gain");
		configParam(TRESHOLD_PARAM, 0.0f, 10.0f, 10.0f, "Treshold");
		configInput(IN1_INPUT,"Left");
		configInput(IN2_INPUT,"Right");
		configOutput(OUT1_OUTPUT,"Left");
		configOutput(OUT2_OUTPUT,"Right");
}


void process(const ProcessArgs &args) override {

	max_GAIN = roundf(params[GAIN_PARAM].getValue()*10);

	affich = round(max_GAIN);

	if (inputs[IN1_INPUT].isConnected())
	{

        if (inputs[IN1_INPUT].getVoltage() > params[TRESHOLD_PARAM].getValue())
        	{
            	outputs[OUT1_OUTPUT].setVoltage((max_GAIN/10.0*(params[TRESHOLD_PARAM].getValue() + ((inputs[IN1_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue())/(1+(inputs[IN1_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue()))))));
            	reman_t = sensiv;
        	}
        else if (inputs[IN1_INPUT].getVoltage() < 0-params[TRESHOLD_PARAM].getValue())
        	{
            	outputs[OUT1_OUTPUT].setVoltage((max_GAIN/10.0*(0-(params[TRESHOLD_PARAM].getValue() - ((inputs[IN1_INPUT].getVoltage()+params[TRESHOLD_PARAM].getValue())/(1+(-inputs[IN1_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue())))))));
            	reman_t = sensiv;
        	}
        	else 
		{
          	  outputs[OUT1_OUTPUT].setVoltage((max_GAIN*inputs[IN1_INPUT].getVoltage())/10.0);
       		}

        if (outputs[OUT1_OUTPUT].getVoltage() >10) reman_o=sensiv;
        
	}
	else
	{
	outputs[OUT1_OUTPUT].setVoltage(max_GAIN/10);
        lights[TRESHOLD_LIGHT].setBrightness(0.0);
        lights[OVER_LIGHT].setBrightness(0.0);
	}



	if (inputs[IN2_INPUT].isConnected())
	{

        if (inputs[IN2_INPUT].getVoltage() > params[TRESHOLD_PARAM].getValue())
        	{
            	outputs[OUT2_OUTPUT].setVoltage((max_GAIN/10.0*(params[TRESHOLD_PARAM].getValue() + ((inputs[IN2_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue())/(1+(inputs[IN2_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue()))))));
            	reman_t = sensiv;
        	}
        else if (inputs[IN2_INPUT].getVoltage() < 0-params[TRESHOLD_PARAM].getValue())
        	{
            	outputs[OUT2_OUTPUT].setVoltage((max_GAIN/10.0*(0-(params[TRESHOLD_PARAM].getValue() - ((inputs[IN2_INPUT].getVoltage()+params[TRESHOLD_PARAM].getValue())/(1+(-inputs[IN2_INPUT].getVoltage()-params[TRESHOLD_PARAM].getValue())))))));
            	reman_t = sensiv;
        	}
        	else 
		{
          	  outputs[OUT2_OUTPUT].setVoltage((max_GAIN*inputs[IN2_INPUT].getVoltage())/10.0);
       		}

        if (outputs[OUT2_OUTPUT].getVoltage() >10) reman_o=sensiv;
        
	}
	else
	{
	outputs[OUT2_OUTPUT].setVoltage(max_GAIN/10);
        lights[TRESHOLD_LIGHT].setBrightness(0.0);
        lights[OVER_LIGHT].setBrightness(0.0);
	}


	if (reman_t >0) 
	{
	reman_t--;
	lights[TRESHOLD_LIGHT].setBrightness(1);
	} 
	else lights[TRESHOLD_LIGHT].setBrightness(0.0);

	if (reman_o >0) 
	{
	reman_o--;
	lights[OVER_LIGHT].setBrightness(1);
	} 
	else lights[OVER_LIGHT].setBrightness(0.0);
};
};

struct NumbDisplayWidget : TransparentWidget {
PEAK *module;
//  float *value=0;
  

  NumbDisplayWidget() {
    
  };

	void drawLayer(const DrawArgs &args, int layer) override {
if (layer ==1) {
std::shared_ptr<Font> font = APP->window->loadFont(asset::plugin(pluginInstance, "res/Segment7Standard.ttf"));
int st = module ? module->affich : 0;
    // Background
    NVGcolor backgroundColor = nvgRGB(0x44, 0x44, 0x44);
    NVGcolor borderColor = nvgRGB(0x10, 0x10, 0x10);
    nvgBeginPath(args.vg);
    nvgRoundedRect(args.vg, 0.0, 0.0, box.size.x, box.size.y, 4.0);
    nvgFillColor(args.vg, backgroundColor);
    nvgFill(args.vg);
    nvgStrokeWidth(args.vg, 1.0);
    nvgStrokeColor(args.vg, borderColor);
    nvgStroke(args.vg);

    nvgFontSize(args.vg, 18);
    nvgFontFaceId(args.vg, font->handle);
    nvgTextLetterSpacing(args.vg, 2.5);

    std::string to_display = std::to_string(st);
    if (st<10) to_display = '0' + to_display;
if (st<100) to_display = ' ' + to_display;


    Vec textPos = Vec(6.0f, 17.0f);

    NVGcolor textColor = nvgRGB(0xdf, 0xd2, 0x2c);
    nvgFillColor(args.vg, nvgTransRGBA(textColor, 16));
    nvgText(args.vg, textPos.x, textPos.y, "~~~", NULL);

    textColor = nvgRGB(0xda, 0xe9, 0x29);

    nvgFillColor(args.vg, nvgTransRGBA(textColor, 16));
    nvgText(args.vg, textPos.x, textPos.y, "\\\\\\", NULL);


    textColor = nvgRGB(0x28, 0xb0, 0xf3);
    nvgFillColor(args.vg, textColor);
    nvgText(args.vg, textPos.x, textPos.y, to_display.c_str(), NULL);
    nvgFillColor(args.vg, textColor);
    nvgText(args.vg, textPos.x+1, textPos.y, " . ", NULL);
    nvgText(args.vg, textPos.x+1, textPos.y-1, " . ", NULL);

  }
Widget::drawLayer(args, layer);
}
};


struct PEAKWidget : ModuleWidget {
	PEAKWidget(PEAK *module) {
setModule(module);
		setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/PEAK.svg")));

	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 0)));
	addChild(createWidget<ScrewSilver>(Vec(15, 365)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));

    	addParam(createParam<RoundLargeBlackKnob>(Vec(27, 97), module, PEAK::GAIN_PARAM));
 		addChild(createLight<MediumLight<BlueLight>>(Vec(42.4, 141.4), module, PEAK::OVER_LIGHT));

	addParam(createParam<RoundLargeBlackKnob>(Vec(27, 227), module, PEAK::TRESHOLD_PARAM));
		addChild(createLight<MediumLight<BlueLight>>(Vec(42.4, 211.4), module, PEAK::TRESHOLD_LIGHT));

	addInput(createInput<PJ301MPort>(Vec(11, 308), module, PEAK::IN1_INPUT));

	addOutput(createOutput<PJ301MPort>(Vec(54, 308), module, PEAK::OUT1_OUTPUT));

	addInput(createInput<PJ301MPort>(Vec(11, 334), module, PEAK::IN2_INPUT));

	addOutput(createOutput<PJ301MPort>(Vec(54, 334), module, PEAK::OUT2_OUTPUT));

NumbDisplayWidget *display = new NumbDisplayWidget();
	display->box.pos = Vec(20,56);
	display->box.size = Vec(50, 20);
	//display->value = &module->affich;
	display->module = module;
	addChild(display);

	
}
};
Model *modelPEAK = createModel<PEAK, PEAKWidget>("PEAK");


<|start_filename|>src/STEREO.cpp<|end_filename|>
#include "plugin.hpp"



struct STEREO : Module {
	enum ParamIds {
		PAN_PARAM,
	        GAIN_PARAM,
	        SOLO_PARAM,
		ON_PARAM,
		NUM_PARAMS
	};
	enum InputIds {
		SOLOT_INPUT,
		ONT_INPUT,
		PAN_INPUT,
		GAIN_INPUT,
		EXTSOLO_INPUT,
		LEFT_INPUT,
		RIGHT_INPUT,
		PANPOT_INPUT,
		IN1_INPUT,
		IN2_INPUT,
		NUM_INPUTS
	};
	enum OutputIds {
		EXTSOLO_OUTPUT,
		LEFT_OUTPUT,
		RIGHT_OUTPUT,
		TLEFT_OUTPUT,
		TRIGHT_OUTPUT,
		NUM_OUTPUTS
	};
    enum LightIds {
		SOLO_LIGHT,
		ON_LIGHT,
		ENUMS(LEVEL_LIGHTS, 11),
		NUM_LIGHTS
	};


float SIGNAL1 = 0.0 ;
float SIGNAL2 = 0.0 ;
bool ON_STATE = false ;
bool SOLO_STATE = false ;
bool soloed = false;
int lightState[11] = {};
int cligno =0;
int retard =0;
int retard2 =0;
dsp::SchmittTrigger onTrigger;
dsp::SchmittTrigger oninTrigger;
dsp::SchmittTrigger soloTrigger;
dsp::SchmittTrigger soloinTrigger;
float or_gain ;
int or_affi ;
float orp_gain ;
int orp_affi ;

	STEREO() {
		config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
		configButton(SOLO_PARAM, "Solo");
		configParam(PAN_PARAM, -1.0f, 1.0f, 0.0f, "Pan");
		configButton(ON_PARAM, "On/off");
		configParam(GAIN_PARAM, 0.0f, 10.0f, 5.0f, "Gain");
		configInput(SOLOT_INPUT,"Solo trigger");
		configInput(ONT_INPUT,"On/off trigger");
		configInput(PAN_INPUT,"Pan control");
		configInput(GAIN_INPUT,"Gain control");
		configInput(EXTSOLO_INPUT,"Solo link");
		configInput(LEFT_INPUT,"Left link");
		configInput(RIGHT_INPUT,"Right link");
		configInput(IN1_INPUT,"Signal left");
		configInput(IN2_INPUT,"Signal right");
		configOutput(EXTSOLO_OUTPUT,"Solo link");
		configOutput(LEFT_OUTPUT,"Left link");
		configOutput(RIGHT_OUTPUT,"Right link");
		configOutput(TLEFT_OUTPUT,"Aux left");
		configOutput(TRIGHT_OUTPUT,"Aux right");
		configBypass(LEFT_INPUT, LEFT_OUTPUT);
		configBypass(RIGHT_INPUT, RIGHT_OUTPUT);
		configBypass(EXTSOLO_INPUT, EXTSOLO_OUTPUT);
		onReset();
	}


void onReset() override {
			ON_STATE = true;
			SOLO_STATE = false;
			}

json_t *dataToJson() override {
		json_t *rootJ = json_object();
		// solo
		json_object_set_new(rootJ, "solostate", json_integer(SOLO_STATE));

		// solo
		json_object_set_new(rootJ, "onstate", json_integer(ON_STATE));
		return rootJ;
		}

void dataFromJson(json_t *rootJ) override {
		// solo
		json_t *solostateJ = json_object_get(rootJ, "solostate");
		if (solostateJ)
			SOLO_STATE = json_integer_value(solostateJ);

		// solo
		json_t *onstateJ = json_object_get(rootJ, "onstate");
		if (onstateJ)
			ON_STATE = json_integer_value(onstateJ);
	
	}




void process(const ProcessArgs &args) override {

        SIGNAL1 = inputs[IN1_INPUT].getVoltage() ;
	SIGNAL2 = inputs[IN2_INPUT].getVoltage() ;

	if (!inputs[GAIN_INPUT].isConnected()) {
		SIGNAL1 = SIGNAL1 * params[GAIN_PARAM].getValue()/5.0 ;
		SIGNAL2 = SIGNAL2 * params[GAIN_PARAM].getValue()/5.0 ;
		or_affi =0;or_gain=params[GAIN_PARAM].getValue() ;
		}
		else {
		SIGNAL1 = SIGNAL1 * clamp(inputs[GAIN_INPUT].getVoltage()/5.0,0.0f,2.0f) ;
		SIGNAL2 = SIGNAL2 * clamp(inputs[GAIN_INPUT].getVoltage()/5.0,0.0f,2.0f) ;
		or_affi=1;or_gain=clamp(inputs[GAIN_INPUT].getVoltage(),0.0f,10.0f);
		}

	if (onTrigger.process(params[ON_PARAM].getValue())+oninTrigger.process(inputs[ONT_INPUT].getVoltage()))
			{if (ON_STATE == 0) ON_STATE = 1; else ON_STATE = 0;}

	if (inputs[EXTSOLO_INPUT].getVoltage() == 0) soloed = 0;
	if (inputs[EXTSOLO_INPUT].getVoltage() == 10) soloed = 1;

	if (soloTrigger.process(params[SOLO_PARAM].getValue())+soloinTrigger.process(inputs[SOLOT_INPUT].getVoltage()))
			{if (SOLO_STATE == 0) {SOLO_STATE = 1;} else {SOLO_STATE = 0;soloed=0;}}

	if ((!SOLO_STATE and !soloed) and (retard > 0)) retard = 0; else if (retard < 1000) retard = retard + 1;


	outputs[EXTSOLO_OUTPUT].setVoltage(round(10*retard/1000));

	if (!SOLO_STATE) {SIGNAL1 = SIGNAL1 * ON_STATE ; SIGNAL2 = SIGNAL2 * ON_STATE ;}
	if (soloed and !SOLO_STATE) {SIGNAL1 = 0; SIGNAL2 = 0;}
	

	if (!inputs[PAN_INPUT].isConnected()) {
			outputs[LEFT_OUTPUT].setVoltage(inputs[LEFT_INPUT].getVoltage() + SIGNAL1*(1-clamp(params[PAN_PARAM].getValue(),0.0f,1.0f)));
			outputs[RIGHT_OUTPUT].setVoltage(inputs[RIGHT_INPUT].getVoltage() + SIGNAL2*(1-clamp(-params[PAN_PARAM].getValue(),0.0f,1.0f)));
			outputs[TLEFT_OUTPUT].setVoltage(SIGNAL1*(1-clamp(params[PAN_PARAM].getValue(),0.0f,1.0f)));
			outputs[TRIGHT_OUTPUT].setVoltage(SIGNAL2*(1-clamp(-params[PAN_PARAM].getValue(),0.0f,1.0f)));
			orp_affi = 0;orp_gain = params[PAN_PARAM].getValue()*5+5;
		} else {
			outputs[LEFT_OUTPUT].setVoltage(inputs[LEFT_INPUT].getVoltage() + SIGNAL1*(1-(clamp(inputs[PAN_INPUT].getVoltage(),5.0f,10.0f)-5)/5));
			outputs[RIGHT_OUTPUT].setVoltage(inputs[RIGHT_INPUT].getVoltage() + SIGNAL2*(1-(clamp(inputs[PAN_INPUT].getVoltage(),0.0f,5.0f)+5)/5));
			outputs[TLEFT_OUTPUT].setVoltage(SIGNAL1*(1-(clamp(inputs[PAN_INPUT].getVoltage(),5.0f,10.0f)-5)/5));
			outputs[TRIGHT_OUTPUT].setVoltage(SIGNAL2*(1-(clamp(inputs[PAN_INPUT].getVoltage(),0.0f,5.0f)+5)/5));
			orp_affi = 1;orp_gain = clamp(inputs[PAN_INPUT].getVoltage(),0.0f,10.0f);
		}

	if (ON_STATE==1) lights[ON_LIGHT].setBrightness(1); else lights[ON_LIGHT].setBrightness(0);
	
	if (SOLO_STATE==1) {if (cligno == 0) cligno =20000; else cligno=cligno-1;} else cligno = 0;
	if (cligno>5000) lights[SOLO_LIGHT].setBrightness(1); else lights[SOLO_LIGHT].setBrightness(0);

	for (int i = 0; i < 11; i++) {
		if (std::max(SIGNAL1,SIGNAL2)> i) {if (i<10) lightState[i]=5000;else lightState[i]=20000;}
	}
	for (int i = 0; i < 11; i++) {
		if (lightState[i]> 0) {lightState[i]=lightState[i]-1;lights[LEVEL_LIGHTS + i].setBrightness(1);} else lights[LEVEL_LIGHTS + i].setBrightness(0);
	}
};
};


struct SMODisplay : TransparentWidget {
	STEREO *module;

	SMODisplay() {
		
	}
	
	void draw(const DrawArgs &args) override {
//nvgGlobalTint(args.vg, color::WHITE);
float gainX = module ? module->or_gain : 1.0f;
//int affich = module ? module->or_affi : 0;
float d=18;

		//if (affich==1) {
		float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ;
		float yy = d*cos((gainX*0.17+0.15)*M_PI) ;

		
			//nvgBeginPath(args.vg);
			//nvgCircle(args.vg, 0,0, d);
			//nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff));
			//nvgFill(args.vg);	
		
			nvgStrokeWidth(args.vg,2);
			nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88));
			{
				nvgBeginPath(args.vg);
				nvgMoveTo(args.vg, 0,0);
				nvgLineTo(args.vg, xx,yy);
				nvgClosePath(args.vg);
			}
			nvgStroke(args.vg);
		//}

	}
};

struct SMOPDisplay : TransparentWidget {
	STEREO *module;

	SMOPDisplay() {
		
	}
	
	void draw(const DrawArgs &args) override {
//nvgGlobalTint(args.vg, color::WHITE);
float gainX = module ? module->orp_gain : 1.0f;
//int affich = module ? module->orp_affi : 0;
float d=8;

		//if (affich==1) {
		float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ;
		float yy = d*cos((gainX*0.17+0.15)*M_PI) ;
		float xx0 = (d-6)*sin(-(gainX*0.17+0.15)*M_PI) ;
		float yy0 = (d-6)*cos((gainX*0.17+0.15)*M_PI) ;
		
			//nvgBeginPath(args.vg);
			//nvgCircle(args.vg, 0,0, d);
			//nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff));
			//nvgFill(args.vg);	
		
			nvgStrokeWidth(args.vg,2);
			nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88));
			{
				nvgBeginPath(args.vg);
				nvgMoveTo(args.vg, xx0,yy0);
				nvgLineTo(args.vg, xx,yy);
				nvgClosePath(args.vg);
			}
			nvgStroke(args.vg);
		//}

	}
};


struct STEREOWidget : ModuleWidget {
	STEREOWidget(STEREO *module){
		setModule(module);
		setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/STEREO.svg")));


	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 0)));
	addChild(createWidget<ScrewSilver>(Vec(15, 365)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));


	addParam(createParam<cfTrimpot>(Vec(38, 127), module, STEREO::PAN_PARAM));
	addInput(createInput<PJ301MPort>(Vec(11, 131), module, STEREO::PAN_INPUT));
	{
		SMOPDisplay *pdisplay = new SMOPDisplay();
		pdisplay->box.pos = Vec(47, 136);
		pdisplay->module = module;
		addChild(pdisplay);

	}

    	addParam(createParam<cfBigKnob>(Vec(27, 247), module, STEREO::GAIN_PARAM));
	addInput(createInput<PJ301MPort>(Vec(11, 281), module, STEREO::GAIN_INPUT));
	{
		SMODisplay *display = new SMODisplay();
		display->box.pos = Vec(45, 265);
		display->module = module;
		addChild(display);
	}


   	addParam(createParam<LEDButton>(Vec(38, 167), module, STEREO::SOLO_PARAM));
 	addChild(createLight<MediumLight<BlueLight>>(Vec(42.4, 171.4), module, STEREO::SOLO_LIGHT));
	addInput(createInput<PJ301MPort>(Vec(11, 171), module, STEREO::SOLOT_INPUT));

     	addParam(createParam<LEDButton>(Vec(38, 208), module, STEREO::ON_PARAM));
	addChild(createLight<MediumLight<BlueLight>>(Vec(42.4, 212.4), module, STEREO::ON_LIGHT));
	addInput(createInput<PJ301MPort>(Vec(11, 211), module, STEREO::ONT_INPUT));
    

	addInput(createInput<PJ301MPort>(Vec(11, 308), module, STEREO::IN1_INPUT));
	addInput(createInput<PJ301MPort>(Vec(11, 334), module, STEREO::IN2_INPUT));
	
	addOutput(createOutput<PJ301MPort>(Vec(54, 31), module, STEREO::EXTSOLO_OUTPUT));
	addOutput(createOutput<PJ301MPort>(Vec(54, 61), module, STEREO::LEFT_OUTPUT));
	addOutput(createOutput<PJ301MPort>(Vec(54, 91), module, STEREO::RIGHT_OUTPUT));

	addInput(createInput<PJ301MPort>(Vec(11, 31), module, STEREO::EXTSOLO_INPUT));
	addInput(createInput<PJ301MPort>(Vec(11, 61), module, STEREO::LEFT_INPUT));
	addInput(createInput<PJ301MPort>(Vec(11, 91), module, STEREO::RIGHT_INPUT));

	addOutput(createOutput<PJ301MPort>(Vec(54, 308), module, STEREO::TLEFT_OUTPUT));
	addOutput(createOutput<PJ301MPort>(Vec(54, 334), module, STEREO::TRIGHT_OUTPUT));

	for (int i = 0; i < 11; i++) {
		if (i<10) addChild(createLight<MediumLight<BlueLight>>(Vec(70, 242-i*12), module, STEREO::LEVEL_LIGHTS + i));
			else addChild(createLight<MediumLight<RedLight>>(Vec(70, 242-i*12), module, STEREO::LEVEL_LIGHTS + i));
	}
	
	
}
};

Model *modelSTEREO = createModel<STEREO, STEREOWidget>("STEREO");


<|start_filename|>src/CUBE.cpp<|end_filename|>

#include "plugin.hpp"



struct CUBE : Module {
	enum ParamIds {
		
		NUM_PARAMS
	};
	enum InputIds {
		X_INPUT,
		Y_INPUT,
		NUM_INPUTS
		
	};
	enum OutputIds {
		X_OUTPUT,
		NUM_OUTPUTS
	};

	float frameX = 0.0;
	float frameY = 0.0;

	float xx[12] = {-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0};
	float yy[12] = {-1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0};
	float zz[12] = {-1.0,-1.0,-1.0,-1.0, 1.0, 1.0, 1.0, 1.0};

	float x[8] = {};
	float y[8] = {};
	float z[8] = {};

	float d = 0.0;
	float theta= 0.0 ;
	float gainX = 1.0;
	float gainY = 1.0;
	

	CUBE() {
		config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
		configInput(X_INPUT, "X speed control");
		configInput(Y_INPUT, "Y speed control");
		configOutput(X_OUTPUT, "Result");
}


void process(const ProcessArgs &args) override {
	gainX = 0.5f; gainY = 0.5f;
	if (inputs[X_INPUT].isConnected()) gainX=inputs[X_INPUT].getVoltage();
	if (inputs[Y_INPUT].isConnected()) gainY=inputs[Y_INPUT].getVoltage();

       	for(int i=0; i<8; i++)
        	{
			d = sqrt(yy[i]*yy[i] + zz[i]*zz[i]);
			theta = atan2(yy[i],zz[i])+frameX;
			x[i] = xx[i]; 
			y[i] = d * sin(theta); 
			z[i] = d * cos(theta);

			d = sqrt(x[i]*x[i] + z[i]*z[i]);
			theta = atan2(x[i],z[i])+frameY;
			x[i] = d * sin(theta); 
			y[i] = y[i]; 
			z[i] = d * cos(theta);
        	}
		
	if (frameX<100) frameX=frameX+gainX* args.sampleTime; else frameX=0;
	if (frameY<100) frameY=frameY+gainY* args.sampleTime; else frameY=0;


	outputs[X_OUTPUT].setVoltage(z[0]*5.0);
};
};

struct CUBEDisplay : TransparentWidget {
	CUBE *module;


	CUBEDisplay() {

	}
	
	void drawLayer(const DrawArgs &args, int layer) override {

if (module) {
if (layer ==1) {
		nvgStrokeColor(args.vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff));
		{
			nvgBeginPath(args.vg);
			nvgMoveTo(args.vg, module->x[0]*20,module->y[0]*20);
			nvgLineTo(args.vg, module->x[1]*20,module->y[1]*20);
			nvgLineTo(args.vg, module->x[2]*20,module->y[2]*20);
			nvgLineTo(args.vg, module->x[3]*20,module->y[3]*20);
			nvgClosePath(args.vg);
		}
		nvgStroke(args.vg);

		{
			nvgBeginPath(args.vg);
			nvgMoveTo(args.vg, module->x[4]*20,module->y[4]*20);
			nvgLineTo(args.vg, module->x[5]*20,module->y[5]*20);
			nvgLineTo(args.vg, module->x[6]*20,module->y[6]*20);
			nvgLineTo(args.vg, module->x[7]*20,module->y[7]*20);
			nvgClosePath(args.vg);
		}
		nvgStroke(args.vg);

		{
			nvgBeginPath(args.vg);
			nvgMoveTo(args.vg, module->x[0]*20,module->y[0]*20);
			nvgLineTo(args.vg, module->x[4]*20,module->y[4]*20);
			nvgClosePath(args.vg);
		}
		nvgStroke(args.vg);

		{
			nvgBeginPath(args.vg);
			nvgMoveTo(args.vg, module->x[1]*20,module->y[1]*20);
			nvgLineTo(args.vg, module->x[5]*20,module->y[5]*20);
			nvgClosePath(args.vg);
		}
		nvgStroke(args.vg);

		{
			nvgBeginPath(args.vg);
			nvgMoveTo(args.vg, module->x[2]*20,module->y[2]*20);
			nvgLineTo(args.vg, module->x[6]*20,module->y[6]*20);
			nvgClosePath(args.vg);
		}
		nvgStroke(args.vg);

		{
			nvgBeginPath(args.vg);
			nvgMoveTo(args.vg, module->x[3]*20,module->y[3]*20);
			nvgLineTo(args.vg, module->x[7]*20,module->y[7]*20);
			nvgClosePath(args.vg);
		}
		nvgStroke(args.vg);

	};};
Widget::drawLayer(args, layer);
}
};



struct CUBEWidget : ModuleWidget {
	CUBEWidget(CUBE *module) {
		setModule(module);
		setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CUBE.svg")));

	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 0)));
	addChild(createWidget<ScrewSilver>(Vec(15, 365)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));

	{
		CUBEDisplay *display = new CUBEDisplay();
		display->box.pos = Vec(60, 120);
		display->module = module;
		addChild(display);
	}

	addInput(createInput<PJ301MPort>(Vec(15, 321), module, CUBE::X_INPUT));
	addInput(createInput<PJ301MPort>(Vec(47, 321), module, CUBE::Y_INPUT));
	addOutput(createOutput<PJ301MPort>(Vec(80, 321), module, CUBE::X_OUTPUT));       
	
}
};

Model *modelCUBE = createModel<CUBE, CUBEWidget>("CUBE");

<|start_filename|>src/ALGEBRA.cpp<|end_filename|>
#include "plugin.hpp"



using namespace std;


struct ALGEBRA : Module {
	enum ParamIds {
		ENUMS(OP_PARAM, 6),
		NUM_PARAMS
	};
	enum InputIds {
		IN1_INPUT,
		IN2_INPUT,
		NUM_INPUTS
	};
	enum OutputIds {
		OUT_OUTPUT,
		NUM_OUTPUTS
	};
	enum LightIds {
		NUM_LIGHTS
	};

	int OP_STATE = 0 ;
	dsp::SchmittTrigger trTrigger[6];

ALGEBRA() { 
	config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
	configInput(IN1_INPUT,"a");
	configInput(IN2_INPUT,"b");
	configOutput(OUT_OUTPUT,"Result");
configButton(OP_PARAM + 0,"+");
configButton(OP_PARAM + 1,"-");
configButton(OP_PARAM + 2,"x");
configButton(OP_PARAM + 3,"/");
configButton(OP_PARAM + 4,"Max");
configButton(OP_PARAM + 5,"Min");
configBypass(IN1_INPUT, OUT_OUTPUT);

}

	
json_t *dataToJson() override {
		json_t *rootJ = json_object();
		

		json_object_set_new(rootJ, "opstate", json_integer(OP_STATE));
		return rootJ;
		}

void dataFromJson(json_t *rootJ) override {
		

		json_t *opstateJ = json_object_get(rootJ, "opstate");
		if (opstateJ)
			OP_STATE = json_integer_value(opstateJ);
	
	}





void process(const ProcessArgs &args) override {
	for (int i=0; i<6; i++) {
		if (trTrigger[i].process(params[OP_PARAM+i].getValue())) OP_STATE= i;
	}

	if (OP_STATE==0) outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage() + inputs[IN2_INPUT].getVoltage());
	if (OP_STATE==1) outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage() - inputs[IN2_INPUT].getVoltage());
	if (OP_STATE==2) outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage() * inputs[IN2_INPUT].getVoltage());
	if ((OP_STATE==3) & (inputs[IN2_INPUT].getVoltage()!=0)) outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage() / inputs[IN2_INPUT].getVoltage());
	if (OP_STATE==4) {
			if (inputs[IN1_INPUT].getVoltage()>=inputs[IN2_INPUT].getVoltage())	outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage());
				else outputs[OUT_OUTPUT].setVoltage(inputs[IN2_INPUT].getVoltage());
			}
	if (OP_STATE==5) {
			if (inputs[IN1_INPUT].getVoltage()<=inputs[IN2_INPUT].getVoltage())	outputs[OUT_OUTPUT].setVoltage(inputs[IN1_INPUT].getVoltage());
				else outputs[OUT_OUTPUT].setVoltage(inputs[IN2_INPUT].getVoltage());
			}

}
};

struct plusButton : app::SvgSwitch {
	plusButton() {
		momentary = true;
		shadow->opacity = 0;
		addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/plusButton.svg")));
	}
};


struct ALGDisplay : TransparentWidget {
	ALGEBRA *module;
	std::string fileDesc = "+";
	int numero =0;
	int frame = 0;
	 

	ALGDisplay() {
		
	};

	void draw(const DrawArgs &args) override {
std::shared_ptr<Font> font = APP->window->loadFont(asset::plugin(pluginInstance, "res/ArialBlack.ttf"));

//	if (font) {
			nvgFontFaceId(args.vg, font->handle);
			nvgFontSize(args.vg, 20);
			nvgTextLetterSpacing(args.vg, 0);
			nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff));	
			nvgTextBox(args.vg, 5, 5,350, fileDesc.c_str(), NULL);
//		}
	}

	void drawLayer(const DrawArgs &args, int layer) override {
std::shared_ptr<Font> font = APP->window->loadFont(asset::plugin(pluginInstance, "res/ArialBlack.ttf"));
//	if (font) {
		if (layer ==1) {
			float val = module ? module->OP_STATE : 0;

			if (val==numero){
				nvgFontFaceId(args.vg, font->handle);
				nvgFontSize(args.vg, 20);
				nvgTextLetterSpacing(args.vg, 0);
				nvgFillColor(args.vg, nvgRGBA(0x4c, 0xc7, 0xf3, 0xff));	
				nvgTextBox(args.vg, 5, 5,350, fileDesc.c_str(), NULL);
				}
			}
//		}
	Widget::drawLayer(args, layer);
	}
};

struct ALGEBRAWidget : ModuleWidget {
	ALGEBRAWidget(ALGEBRA *module){
		setModule(module);
		setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/ALGEBRA.svg")));

	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));


	addInput(createInput<PJ301MPort>(Vec(3, 31), module, ALGEBRA::IN1_INPUT));
	addInput(createInput<PJ301MPort>(Vec(3, 95), module, ALGEBRA::IN2_INPUT));

	int i = 0;
     		addParam(createParam<plusButton>(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); i=i+1;
    		addParam(createParam<plusButton>(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); i=i+1;
     		addParam(createParam<plusButton>(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); i=i+1;
     		addParam(createParam<plusButton>(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); i=i+1;
     		addParam(createParam<plusButton>(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i)); i=i+1;
     		addParam(createParam<plusButton>(Vec(6, i*24+136), module, ALGEBRA::OP_PARAM + i));
		
	


	addOutput(createOutput<PJ301MPort>(Vec(3, 321), module, ALGEBRA::OUT_OUTPUT));

	{
		ALGDisplay *plusdisplay = new ALGDisplay();
		plusdisplay->box.pos = Vec(6, 145);
		plusdisplay->module = module;
		plusdisplay->fileDesc = "+";
		plusdisplay->numero = 0;
		addChild(plusdisplay);
	}
	{
		ALGDisplay *moinsdisplay = new ALGDisplay();
		moinsdisplay->box.pos = Vec(9, 145+24-1);
		moinsdisplay->module = module;
		moinsdisplay->fileDesc = "-";
		moinsdisplay->numero = 1;
		addChild(moinsdisplay);
	}
	{
		ALGDisplay *foisdisplay = new ALGDisplay();
		foisdisplay->box.pos = Vec(6, 145+24*2-1);
		foisdisplay->module = module;
		foisdisplay->fileDesc = "x";
		foisdisplay->numero = 2;
		addChild(foisdisplay);
	}
	{
		ALGDisplay *divdisplay = new ALGDisplay();
		divdisplay->box.pos = Vec(9, 145+24*3);
		divdisplay->module = module;
		divdisplay->fileDesc = "/";
		divdisplay->numero = 3;
		addChild(divdisplay);
	}
	{
		ALGDisplay *maxdisplay = new ALGDisplay();
		maxdisplay->box.pos = Vec(4, 145+24*4);
		maxdisplay->module = module;
		maxdisplay->fileDesc = "M";
		maxdisplay->numero = 4;
		addChild(maxdisplay);
	}
	{
		ALGDisplay *mindisplay = new ALGDisplay();
		mindisplay->box.pos = Vec(4, 145+24*5-1);
		mindisplay->module = module;
		mindisplay->fileDesc = "m";
		mindisplay->numero = 5;
		addChild(mindisplay);
	}
	
}
};


Model *modelALGEBRA = createModel<ALGEBRA, ALGEBRAWidget>("ALGEBRA");


<|start_filename|>src/METRO.cpp<|end_filename|>
#include "plugin.hpp"


struct METRO : Module {
	enum ParamIds {
		BPM_PARAM,
		RST_PARAM,
		BEAT_PARAM,
		ON_PARAM,
		NUM_PARAMS
	};
	enum InputIds {
		ON_INPUT,
		BPM_INPUT,
		NUM_INPUTS
	};
	enum OutputIds {
		OUT_OUTPUT,
		MES_OUTPUT,
		BEAT_OUTPUT,
		START_OUTPUT,
		NUM_OUTPUTS
	};
    enum LightIds {
		ON_LIGHT,
		MES_LIGHT,
		BEAT_LIGHT,
		NUM_LIGHTS
	};

int max_METRO = 120 ;
int beatl = 0 ;
int mesl = 0 ;
int beats = 0 ;
int mess = 0 ;
int strt = 0 ;
int note ;
float toc_phase = 0.f;
uint32_t toc = 0u;
dsp::SchmittTrigger onTrigger;
dsp::SchmittTrigger oninTrigger;
dsp::SchmittTrigger rstTrigger;
bool ON_STATE = false;
float or_gain ;
int or_affi ;

	METRO() {
		config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
		configButton(BEAT_PARAM, "Beat");
		configButton(RST_PARAM, "Reset");
		configButton(ON_PARAM, "Start/stop");
		configParam(BPM_PARAM, 0.0f, 301.0f, 120.1f, "BPM");
		configInput(ON_INPUT,"Start/stop trigger");
		configInput(BPM_INPUT,"BPM control");
		configOutput(START_OUTPUT,"Start/reset");
		configOutput(OUT_OUTPUT,"12 ppn");
		configOutput(BEAT_OUTPUT,"Audio ticks per note");
onReset();
}



void onReset() override {
			ON_STATE = true;
			
			}

json_t *dataToJson() override {
		json_t *rootJ = json_object();

		// on
		json_object_set_new(rootJ, "onstate", json_integer(ON_STATE));
		return rootJ;
		}

void dataFromJson(json_t *rootJ) override {

		// on
		json_t *onstateJ = json_object_get(rootJ, "onstate");
		if (onstateJ)
			ON_STATE = json_integer_value(onstateJ);
	
	}



void process(const ProcessArgs &args) override {

	if (!inputs[BPM_INPUT].isConnected()) {
		max_METRO = floor(params[BPM_PARAM].getValue());
		or_affi = 0;
		or_gain = max_METRO/30.0;
	} else {
		max_METRO = round(clamp(inputs[BPM_INPUT].getVoltage() *30,0.0f,300.0f));
		or_affi = 1;
		or_gain = max_METRO/30.0;
	}

	float bpm = max_METRO ;
	bool toced = false;

	if (onTrigger.process(params[ON_PARAM].getValue())+oninTrigger.process(inputs[ON_INPUT].getVoltage()))
			{if (ON_STATE == 0) {ON_STATE = 1; strt = 5;} else ON_STATE = 0;}

	lights[ON_LIGHT].setBrightness(ON_STATE) ;

	
	if (rstTrigger.process(params[RST_PARAM].getValue()))
		{toc = 47u;toc_phase = 1.f; strt = 5;}
	

	if (ON_STATE) {
		toc_phase += ((bpm / 60.f) * args.sampleTime) * 12.f;
		
		if(toc_phase >= 1.f) {
			toced = true;
			toc = (toc+1u) % 48u ;
			toc_phase -= 1.f;
			}

		if(toced) {
			if (toc % 12u ? 0 : 1) beatl = 4000;
			if (toc % 48u ? 0 : 1) mesl = 5000;
			if (toc % 12u ? 0 : 1) beats = 200;
			if (toc % 48u ? 0 : 1) mess = 200;
			note =5;
			}

		if (beatl>0) {
			lights[BEAT_LIGHT].setBrightness(1); 
			beatl = beatl -1;
		} else {
			lights[BEAT_LIGHT].setBrightness(0);
			}

		if (mesl>0) {
			lights[MES_LIGHT].setBrightness(1); 
			mesl = mesl -1;
		} else {
			lights[MES_LIGHT].setBrightness(0);
			}


		if (beats>0) {
			beats = beats -1;
			outputs[BEAT_OUTPUT].setVoltage(2.5 * (beats- 150*round(beats/150))/150);
		} else {
			outputs[BEAT_OUTPUT].setVoltage(0.0);
			}

		if (mess>0) { 
			mess = mess -1;
			outputs[BEAT_OUTPUT].setVoltage(5.0 * (mess- 150*round(mess/150))/150);
			}

	} else {toc = 47u;toc_phase = 1.f;outputs[OUT_OUTPUT].setVoltage(0.f);}
    

	if (strt > 0) {outputs[START_OUTPUT].setVoltage(10.f);strt=strt-1;} else outputs[START_OUTPUT].setVoltage(0.f);
	if (note > 0) {outputs[OUT_OUTPUT].setVoltage(10.f);note=note-1;} else outputs[OUT_OUTPUT].setVoltage(0.f);
}
};

struct NumDisplayWidget : TransparentWidget {
	METRO *module;



  NumDisplayWidget() {
    
  };

	void drawLayer(const DrawArgs &args, int layer) override {
if (layer ==1) {
  std::shared_ptr<Font> font = APP->window->loadFont(asset::plugin(pluginInstance, "res/Segment7Standard.ttf"));
	int val = module ? module->max_METRO : 120;
    // Background
    NVGcolor backgroundColor = nvgRGB(0x44, 0x44, 0x44);
    NVGcolor borderColor = nvgRGB(0x10, 0x10, 0x10);
    nvgBeginPath(args.vg);
    nvgRoundedRect(args.vg, 0.0, 0.0, box.size.x, box.size.y, 4.0);
    nvgFillColor(args.vg, backgroundColor);
    nvgFill(args.vg);
    nvgStrokeWidth(args.vg, 1.0);
    nvgStrokeColor(args.vg, borderColor);
    nvgStroke(args.vg);

    nvgFontSize(args.vg, 18);
    nvgFontFaceId(args.vg, font->handle);
    nvgTextLetterSpacing(args.vg, 2.5);

    std::string to_display = std::to_string(val);


    while(to_display.length()<3) to_display = ' ' + to_display;

    Vec textPos = Vec(6.0f, 17.0f);

    NVGcolor textColor = nvgRGB(0xdf, 0xd2, 0x2c);
    nvgFillColor(args.vg, nvgTransRGBA(textColor, 16));
    nvgText(args.vg, textPos.x, textPos.y, "~~~", NULL);

    textColor = nvgRGB(0xda, 0xe9, 0x29);

    nvgFillColor(args.vg, nvgTransRGBA(textColor, 16));
    nvgText(args.vg, textPos.x, textPos.y, "\\\\\\", NULL);


    textColor = nvgRGB(0x28, 0xb0, 0xf3);
    nvgFillColor(args.vg, textColor);
    nvgText(args.vg, textPos.x, textPos.y, to_display.c_str(), NULL);
  }
Widget::drawLayer(args, layer);
}
};

struct METROPOTDisplay : TransparentWidget {
	METRO *module;

	METROPOTDisplay() {
		
	}
	
	void draw(const DrawArgs &args) override {

float gainX = module ? module->or_gain : 1.0f;
//int affich = module ? module->or_affi : 0;
float d=18;
		//if (affich==1) {
		float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ;
		float yy = d*cos((gainX*0.17+0.15)*M_PI) ;

		
			//nvgBeginPath(args.vg);
			//nvgCircle(args.vg, 0,0, d);
			//nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff));
			//nvgFill(args.vg);	
		
			nvgStrokeWidth(args.vg,2);
			nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88));
			{
				nvgBeginPath(args.vg);
				nvgMoveTo(args.vg, 0,0);
				nvgLineTo(args.vg, xx,yy);
				nvgClosePath(args.vg);
			}
			nvgStroke(args.vg);
		//}

	}
};


struct METROWidget : ModuleWidget {
	METROWidget(METRO *module) {
		setModule(module);
		setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/METRO.svg")));

	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 0)));
	addChild(createWidget<ScrewSilver>(Vec(15, 365)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));

	addParam(createParam<cfBigKnob>(Vec(27, 107), module, METRO::BPM_PARAM));
	addInput(createInput<PJ301MPort>(Vec(11, 141), module, METRO::BPM_INPUT));
	{
		METROPOTDisplay *display = new METROPOTDisplay();
		display->box.pos = Vec(45, 125);
		display->module = module;
		addChild(display);
	}

     	addParam(createParam<LEDButton>(Vec(38, 167), module, METRO::ON_PARAM));
	addChild(createLight<MediumLight<BlueLight>>(Vec(42.4, 171.4), module, METRO::ON_LIGHT));
	addInput(createInput<PJ301MPort>(Vec(11, 171), module, METRO::ON_INPUT));

     	addParam(createParam<LEDButton>(Vec(38, 197), module, METRO::RST_PARAM));
	addChild(createLight<MediumLight<BlueLight>>(Vec(42.4, 201.4), module, METRO::MES_LIGHT));

     	addParam(createParam<LEDButton>(Vec(38, 227), module, METRO::BEAT_PARAM));
	addChild(createLight<MediumLight<BlueLight>>(Vec(42.4, 231.4), module, METRO::BEAT_LIGHT));
	addOutput(createOutput<PJ301MPort>(Vec(54, 265), module, METRO::BEAT_OUTPUT));

	addOutput(createOutput<PJ301MPort>(Vec(11, 321), module, METRO::START_OUTPUT));
	addOutput(createOutput<PJ301MPort>(Vec(54, 321), module, METRO::OUT_OUTPUT));

	NumDisplayWidget *display = new NumDisplayWidget();
	display->box.pos = Vec(20,56);
	display->box.size = Vec(50, 20);
	display->module = module;
	addChild(display);

	
}
};

Model *modelMETRO = createModel <METRO, METROWidget>("METRO");

<|start_filename|>src/SUB.cpp<|end_filename|>
#include "plugin.hpp"



struct SUB : Module {
	enum ParamIds {
	        GAIN_PARAM,
		GAIN2_PARAM,
	        LINK_PARAM,
		NUM_PARAMS
	};
	enum InputIds {
		GAIN_INPUT,
		GAIN2_INPUT,
		M1_INPUT,
		M2_INPUT,
		IN1_INPUT,
		IN2_INPUT,
		NUM_INPUTS
	};
	enum OutputIds {
		M1_OUTPUT,
		OUT1_OUTPUT,
		M2_OUTPUT,
		OUT2_OUTPUT,
		NUM_OUTPUTS
	};
    enum LightIds {
		LINK_LIGHT,
		NUM_LIGHTS
	};


float SIGNAL = 0.0 ;
float SIGNAL2 = 0.0 ;
float or_gain ;
float or2_gain ;
int or_affi ;
int or2_affi ;
bool LINK_STATE = false ;
dsp::SchmittTrigger linkTrigger;


	SUB() {
		config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
		configButton(LINK_PARAM, "Link");
		configParam(GAIN_PARAM, 0.0f, 1.0f, 0.0f, "Send 1");
		configParam(GAIN2_PARAM, 0.0f, 1.0f, 0.0f, "Send 2");

		configInput(GAIN_INPUT,"Send 1 control");
		configInput(GAIN2_INPUT,"Send 2 control");
		configInput(M1_INPUT,"A1");
		configInput(M2_INPUT,"A2");
		configInput(IN1_INPUT,"B1");
		configInput(IN2_INPUT,"B2");

		configOutput(M1_OUTPUT,"A1+B1xSend1");
		configOutput(OUT1_OUTPUT,"B1 thru");
		configOutput(M2_OUTPUT,"A2+B2xSend2");
		configOutput(OUT2_OUTPUT,"B2 thru");
		onReset();
}


void onReset() override {
			LINK_STATE = false;
			}

json_t *dataToJson() override {
		json_t *rootJ = json_object();
		// solo
		json_object_set_new(rootJ, "linkstate", json_integer(LINK_STATE));

		return rootJ;
		}

void dataFromJson(json_t *rootJ) override {
		// solo
		json_t *linkstateJ = json_object_get(rootJ, "linkstate");
		if (linkstateJ)
			LINK_STATE = json_integer_value(linkstateJ);

	
	}




void process(const ProcessArgs &args) override {

	if (linkTrigger.process(params[LINK_PARAM].getValue()))
			{LINK_STATE=!LINK_STATE;}
	lights[LINK_LIGHT].setBrightness(LINK_STATE);


        SIGNAL = inputs[IN1_INPUT].getVoltage() ;

	outputs[OUT1_OUTPUT].setVoltage(SIGNAL);

	if (!inputs[GAIN_INPUT].isConnected())
		{SIGNAL = SIGNAL * params[GAIN_PARAM].getValue();or_affi=0; or_gain=params[GAIN_PARAM].getValue()*10.0;}
		else {SIGNAL = SIGNAL * clamp(inputs[GAIN_INPUT].getVoltage()/10.0f,0.0f,1.0f) ; or_affi=1;or_gain=clamp(inputs[GAIN_INPUT].getVoltage(),0.0f,10.0f);}

	outputs[M1_OUTPUT].setVoltage(inputs[M1_INPUT].getVoltage() + SIGNAL);


        SIGNAL2 = inputs[IN2_INPUT].getVoltage() ;

	outputs[OUT2_OUTPUT].setVoltage(SIGNAL2);

	if (!LINK_STATE) {
		if (!inputs[GAIN2_INPUT].isConnected()) 
			{SIGNAL2 = SIGNAL2 * params[GAIN2_PARAM].getValue();or2_affi=0;or2_gain=params[GAIN2_PARAM].getValue()*10.0;}
			else {SIGNAL2 = SIGNAL2 * clamp(inputs[GAIN2_INPUT].getVoltage()/10.0f,0.0f,1.0f) ; or2_affi=1;or2_gain=clamp(inputs[GAIN2_INPUT].getVoltage(),0.0f,10.0f);}
	} else {
		if (!inputs[GAIN_INPUT].isConnected())
			{SIGNAL2 = SIGNAL2 * params[GAIN_PARAM].getValue() ;or2_affi=1;or2_gain=clamp(params[GAIN_PARAM].getValue()*10.0,0.0f,10.0f);}
		else {SIGNAL2 = SIGNAL2 * clamp(inputs[GAIN_INPUT].getVoltage()/10.0f,0.0f,1.0f) ; or2_affi=1;or2_gain=clamp(inputs[GAIN_INPUT].getVoltage(),0.0f,10.0f);}
	}

	outputs[M2_OUTPUT].setVoltage(inputs[M2_INPUT].getVoltage() + SIGNAL2);


}
};

struct MDisplay : TransparentWidget {
	SUB *module;

	MDisplay() {
		
	}
	
	void draw(const DrawArgs &args) override {
//nvgGlobalTint(args.vg, color::WHITE);
float gainX = module ? module->or_gain : 1.0f;
//int affich = module ? module->or_affi : 0;
float d=18;

		//if (affich==1) {
		float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ;
		float yy = d*cos((gainX*0.17+0.15)*M_PI) ;

		
			//nvgBeginPath(args.vg);
			//nvgCircle(args.vg, 0,0, d);
			//nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff));
			//nvgFill(args.vg);	
		
			nvgStrokeWidth(args.vg,2);
			nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88));
			{
				nvgBeginPath(args.vg);
				nvgMoveTo(args.vg, 0,0);
				nvgLineTo(args.vg, xx,yy);
				nvgClosePath(args.vg);
			}
			nvgStroke(args.vg);
		//}

	}
};

struct MSDisplay : TransparentWidget {
	SUB *module;

	MSDisplay() {
		
	}
	
	void draw(const DrawArgs &args) override {
//nvgGlobalTint(args.vg, color::WHITE);
float gainX = module ? module->or2_gain : 1.0f;
//int affich = module ? module->or2_affi : 0;
float d=18;

		//if (affich==1) {
		float xx = d*sin(-(gainX*0.17+0.15)*M_PI) ;
		float yy = d*cos((gainX*0.17+0.15)*M_PI) ;

		
			//nvgBeginPath(args.vg);
			//nvgCircle(args.vg, 0,0, d);
			//nvgFillColor(args.vg, nvgRGBA(0x00, 0x00, 0x00, 0xff));
			//nvgFill(args.vg);	
		
			nvgStrokeWidth(args.vg,2);
			nvgStrokeColor(args.vg, nvgRGBA(0xff, 0xff, 0xff, 0x88));
			{
				nvgBeginPath(args.vg);
				nvgMoveTo(args.vg, 0,0);
				nvgLineTo(args.vg, xx,yy);
				nvgClosePath(args.vg);
			}
			nvgStroke(args.vg);
		//}

	}
};


struct SUBWidget : ModuleWidget {
	SUBWidget(SUB *module){
		setModule(module);
		setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SUB.svg")));

	addChild(createWidget<ScrewSilver>(Vec(15, 0)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 0)));
	addChild(createWidget<ScrewSilver>(Vec(15, 365)));
	addChild(createWidget<ScrewSilver>(Vec(box.size.x-30, 365)));

     	addParam(createParam<LEDButton>(Vec(22, 179), module, SUB::LINK_PARAM));
	addChild(createLight<MediumLight<BlueLight>>(Vec(26.5, 182.5), module, SUB::LINK_LIGHT));


    	addParam(createParam<cfBigKnob>(Vec(27, 247), module, SUB::GAIN2_PARAM));
	addInput(createInput<PJ301MPort>(Vec(11, 281), module, SUB::GAIN2_INPUT));
	{
		MSDisplay *display2 = new MSDisplay();
		display2->box.pos = Vec(45, 265);
		display2->module = module;
		addChild(display2);
	}

    

	addInput(createInput<PJ301MPort>(Vec(11, 321), module, SUB::IN2_INPUT));

	addOutput(createOutput<PJ301MPort>(Vec(54, 321), module, SUB::OUT2_OUTPUT));
	

	addOutput(createOutput<PJ301MPort>(Vec(54, 61+152), module, SUB::M2_OUTPUT));


	addInput(createInput<PJ301MPort>(Vec(11, 61+152), module, SUB::M2_INPUT));



    	addParam(createParam<cfBigKnob>(Vec(27, 247-182), module, SUB::GAIN_PARAM));
	addInput(createInput<PJ301MPort>(Vec(11, 281-182), module, SUB::GAIN_INPUT));
	{
		MDisplay *display = new MDisplay();
		display->box.pos = Vec(45, 265-182);
		display->module = module;
		addChild(display);
	}

    

	addInput(createInput<PJ301MPort>(Vec(11, 321-182), module, SUB::IN1_INPUT));

	addOutput(createOutput<PJ301MPort>(Vec(54, 321-182), module, SUB::OUT1_OUTPUT));
	

	addOutput(createOutput<PJ301MPort>(Vec(54, 31), module, SUB::M1_OUTPUT));


	addInput(createInput<PJ301MPort>(Vec(11, 31), module, SUB::M1_INPUT));

	
}
};

Model *modelSUB = createModel<SUB, SUBWidget>("SUB");
