BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

PolyOff8.cpp (7735B)


      1 
      2 #include "PolyOff8.hpp"
      3 
      4 #define OFFSET_FIRST "offset_first"
      5 
      6 json_t* PolyOff8::saveToJson(json_t* root) {
      7 	root = OutputRangeModule<BGModule>::saveToJson(root);
      8 	json_object_set_new(root, OFFSET_FIRST, json_boolean(_offsetFirst));
      9 	return root;
     10 }
     11 
     12 void PolyOff8::loadFromJson(json_t* root) {
     13 	OutputRangeModule<BGModule>::loadFromJson(root);
     14 	json_t* of = json_object_get(root, OFFSET_FIRST);
     15 	if (of) {
     16 		_offsetFirst = json_boolean_value(of);
     17 	}
     18 }
     19 
     20 void PolyOff8::processAll(const ProcessArgs& args) {
     21 	int cn = 1;
     22 	if (inputs[IN_INPUT].isConnected()) {
     23 		cn = clamp(inputs[IN_INPUT].getChannels(), 1, 8);
     24 		outputs[OUT_OUTPUT].setChannels(cn);
     25 
     26 		for (int c = 0; c < cn; ++c) {
     27 			float offset = clamp(params[OFFSET1_PARAM + 2 * c].getValue(), -1.0f, 1.0f);
     28 			if (inputs[CV1_INPUT + c].isConnected()) {
     29 				offset *= clamp(inputs[CV1_INPUT + c].getVoltage() / 5.0f, -1.0f, 1.0f);
     30 			}
     31 			offset += _rangeOffset;
     32 			offset *= _rangeScale;
     33 
     34 			float scale = clamp(params[SCALE1_PARAM + 2 * c].getValue(), -1.0f, 1.0f);
     35 
     36 			float out = inputs[IN_INPUT].getPolyVoltage(c);
     37 			if (_offsetFirst) {
     38 				out += offset;
     39 				out *= scale;
     40 			}
     41 			else {
     42 				out *= scale;
     43 				out += offset;
     44 			}
     45 			outputs[OUT_OUTPUT].setVoltage(clamp(out, -12.0f, 12.0f), c);
     46 		}
     47 	}
     48 	else {
     49 		cn = clamp(params[CHANNELS_PARAM].getValue(), 1.0f, 8.0f);
     50 		outputs[OUT_OUTPUT].setChannels(cn);
     51 
     52 		for (int c = 0; c < cn; ++c) {
     53 			float offset = clamp(params[OFFSET1_PARAM + 2 * c].getValue(), -1.0f, 1.0f);
     54 			offset += _rangeOffset;
     55 			offset *= _rangeScale;
     56 
     57 			float scale = clamp(params[SCALE1_PARAM + 2 * c].getValue(), -1.0f, 1.0f);
     58 
     59 			float out = inputs[CV1_INPUT + c].getVoltage();
     60 			if (_offsetFirst) {
     61 				out += offset;
     62 				out *= scale;
     63 			}
     64 			else {
     65 				out *= scale;
     66 				out += offset;
     67 			}
     68 			outputs[OUT_OUTPUT].setVoltage(clamp(out, -12.0f, 12.0f), c);
     69 		}
     70 	}
     71 
     72 	for (int c = 0; c < 8; ++c) {
     73 		lights[CHANNEL1_LIGHT + c].value = (c < cn) * 1.0f;
     74 	}
     75 }
     76 
     77 struct PolyOff8Widget : BGModuleWidget {
     78 	static constexpr int hp = 8;
     79 
     80 	PolyOff8Widget(PolyOff8* module) {
     81 		setModule(module);
     82 		box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
     83 		setPanel(box.size, "PolyOff8");
     84 		createScrews();
     85 
     86 		// generated by svg_widgets.rb
     87 		auto offset1ParamPosition = Vec(62.5, 33.0);
     88 		auto scale1ParamPosition = Vec(93.5, 33.0);
     89 		auto offset2ParamPosition = Vec(62.5, 68.0);
     90 		auto scale2ParamPosition = Vec(93.5, 68.0);
     91 		auto offset3ParamPosition = Vec(62.5, 103.0);
     92 		auto scale3ParamPosition = Vec(93.5, 103.0);
     93 		auto offset4ParamPosition = Vec(62.5, 138.0);
     94 		auto scale4ParamPosition = Vec(93.5, 138.0);
     95 		auto offset5ParamPosition = Vec(62.5, 173.0);
     96 		auto scale5ParamPosition = Vec(93.5, 173.0);
     97 		auto offset6ParamPosition = Vec(62.5, 208.0);
     98 		auto scale6ParamPosition = Vec(93.5, 208.0);
     99 		auto offset7ParamPosition = Vec(62.5, 243.0);
    100 		auto scale7ParamPosition = Vec(93.5, 243.0);
    101 		auto offset8ParamPosition = Vec(62.5, 278.0);
    102 		auto scale8ParamPosition = Vec(93.5, 278.0);
    103 		auto channelsParamPosition = Vec(23.0, 332.0);
    104 
    105 		auto cv1InputPosition = Vec(10.5, 29.0);
    106 		auto cv2InputPosition = Vec(10.5, 64.0);
    107 		auto cv3InputPosition = Vec(10.5, 99.0);
    108 		auto cv4InputPosition = Vec(10.5, 134.0);
    109 		auto cv5InputPosition = Vec(10.5, 169.0);
    110 		auto cv6InputPosition = Vec(10.5, 204.0);
    111 		auto cv7InputPosition = Vec(10.5, 239.0);
    112 		auto cv8InputPosition = Vec(10.5, 274.0);
    113 		auto inInputPosition = Vec(55.5, 322.0);
    114 
    115 		auto outOutputPosition = Vec(86.5, 322.0);
    116 
    117 		auto channel1LightPosition = Vec(46.8, 43.0);
    118 		auto channel2LightPosition = Vec(46.8, 78.0);
    119 		auto channel3LightPosition = Vec(46.8, 113.0);
    120 		auto channel4LightPosition = Vec(46.8, 148.0);
    121 		auto channel5LightPosition = Vec(46.8, 183.0);
    122 		auto channel6LightPosition = Vec(46.8, 218.0);
    123 		auto channel7LightPosition = Vec(46.8, 253.0);
    124 		auto channel8LightPosition = Vec(46.8, 288.0);
    125 		// end generated by svg_widgets.rb
    126 
    127 		addParam(createParam<Knob16>(offset1ParamPosition, module, PolyOff8::OFFSET1_PARAM));
    128 		addParam(createParam<Knob16>(scale1ParamPosition, module, PolyOff8::SCALE1_PARAM));
    129 		addParam(createParam<Knob16>(offset2ParamPosition, module, PolyOff8::OFFSET2_PARAM));
    130 		addParam(createParam<Knob16>(scale2ParamPosition, module, PolyOff8::SCALE2_PARAM));
    131 		addParam(createParam<Knob16>(offset3ParamPosition, module, PolyOff8::OFFSET3_PARAM));
    132 		addParam(createParam<Knob16>(scale3ParamPosition, module, PolyOff8::SCALE3_PARAM));
    133 		addParam(createParam<Knob16>(offset4ParamPosition, module, PolyOff8::OFFSET4_PARAM));
    134 		addParam(createParam<Knob16>(scale4ParamPosition, module, PolyOff8::SCALE4_PARAM));
    135 		addParam(createParam<Knob16>(offset5ParamPosition, module, PolyOff8::OFFSET5_PARAM));
    136 		addParam(createParam<Knob16>(scale5ParamPosition, module, PolyOff8::SCALE5_PARAM));
    137 		addParam(createParam<Knob16>(offset6ParamPosition, module, PolyOff8::OFFSET6_PARAM));
    138 		addParam(createParam<Knob16>(scale6ParamPosition, module, PolyOff8::SCALE6_PARAM));
    139 		addParam(createParam<Knob16>(offset7ParamPosition, module, PolyOff8::OFFSET7_PARAM));
    140 		addParam(createParam<Knob16>(scale7ParamPosition, module, PolyOff8::SCALE7_PARAM));
    141 		addParam(createParam<Knob16>(offset8ParamPosition, module, PolyOff8::OFFSET8_PARAM));
    142 		addParam(createParam<Knob16>(scale8ParamPosition, module, PolyOff8::SCALE8_PARAM));
    143 		addParam(createParam<Knob16>(channelsParamPosition, module, PolyOff8::CHANNELS_PARAM));
    144 
    145 		addInput(createInput<Port24>(cv1InputPosition, module, PolyOff8::CV1_INPUT));
    146 		addInput(createInput<Port24>(cv2InputPosition, module, PolyOff8::CV2_INPUT));
    147 		addInput(createInput<Port24>(cv3InputPosition, module, PolyOff8::CV3_INPUT));
    148 		addInput(createInput<Port24>(cv4InputPosition, module, PolyOff8::CV4_INPUT));
    149 		addInput(createInput<Port24>(cv5InputPosition, module, PolyOff8::CV5_INPUT));
    150 		addInput(createInput<Port24>(cv6InputPosition, module, PolyOff8::CV6_INPUT));
    151 		addInput(createInput<Port24>(cv7InputPosition, module, PolyOff8::CV7_INPUT));
    152 		addInput(createInput<Port24>(cv8InputPosition, module, PolyOff8::CV8_INPUT));
    153 		addInput(createInput<Port24>(inInputPosition, module, PolyOff8::IN_INPUT));
    154 
    155 		addOutput(createOutput<Port24>(outOutputPosition, module, PolyOff8::OUT_OUTPUT));
    156 
    157 		addChild(createLight<BGTinyLight<GreenLight>>(channel1LightPosition, module, PolyOff8::CHANNEL1_LIGHT));
    158 		addChild(createLight<BGTinyLight<GreenLight>>(channel2LightPosition, module, PolyOff8::CHANNEL2_LIGHT));
    159 		addChild(createLight<BGTinyLight<GreenLight>>(channel3LightPosition, module, PolyOff8::CHANNEL3_LIGHT));
    160 		addChild(createLight<BGTinyLight<GreenLight>>(channel4LightPosition, module, PolyOff8::CHANNEL4_LIGHT));
    161 		addChild(createLight<BGTinyLight<GreenLight>>(channel5LightPosition, module, PolyOff8::CHANNEL5_LIGHT));
    162 		addChild(createLight<BGTinyLight<GreenLight>>(channel6LightPosition, module, PolyOff8::CHANNEL6_LIGHT));
    163 		addChild(createLight<BGTinyLight<GreenLight>>(channel7LightPosition, module, PolyOff8::CHANNEL7_LIGHT));
    164 		addChild(createLight<BGTinyLight<GreenLight>>(channel8LightPosition, module, PolyOff8::CHANNEL8_LIGHT));
    165 	}
    166 
    167 	void contextMenu(Menu* menu) override {
    168 		OutputRangeOptionMenuItem::addOutputRangeOptionsToMenu(module, menu);
    169 
    170 		auto m = dynamic_cast<PolyOff8*>(module);
    171 		assert(m);
    172 
    173 		OptionsMenuItem* ooo = new OptionsMenuItem("Order of operations");
    174 		ooo->addItem(OptionMenuItem("Scale, then offset", [m]() { return !m->_offsetFirst; }, [m]() { m->_offsetFirst = false; }));
    175 		ooo->addItem(OptionMenuItem("Offset, then scale", [m]() { return m->_offsetFirst; }, [m]() { m->_offsetFirst = true; }));
    176 		OptionsMenuItem::addToMenu(ooo, menu);
    177 	}
    178 };
    179 
    180 Model* modelPolyOff8 = createModel<PolyOff8, PolyOff8Widget>("Bogaudio-PolyOff8", "POLYOFF8", "Polyphonic per-channel offset and scale", "Polyphonic");