BogaudioModules

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

Offset.cpp (3058B)


      1 
      2 #include "Offset.hpp"
      3 
      4 #define OFFSET_FIRST "offset_first"
      5 
      6 json_t* Offset::saveToJson(json_t* root) {
      7 	root = DisableOutputLimitModule::saveToJson(root);
      8 	json_object_set_new(root, OFFSET_FIRST, json_boolean(_offsetFirst));
      9 	return root;
     10 }
     11 
     12 void Offset::loadFromJson(json_t* root) {
     13 	DisableOutputLimitModule::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 int Offset::channels() {
     21 	return inputs[IN_INPUT].getChannels();
     22 }
     23 
     24 void Offset::processChannel(const ProcessArgs& args, int c) {
     25 	float offset = knobValue(params[OFFSET_PARAM], inputs[OFFSET_INPUT], c);
     26 	offset *= 10.0f;
     27 
     28 	float scale = knobValue(params[SCALE_PARAM], inputs[SCALE_INPUT], c);
     29 	scale = scale < 0.0f ? -pow(scale, 2.0f) : pow(scale, 2.0f);
     30 	scale *= 10.0;
     31 
     32 	float out = inputs[IN_INPUT].getVoltage(c);
     33 	if (_offsetFirst) {
     34 		out += offset;
     35 		out *= scale;
     36 	}
     37 	else {
     38 		out *= scale;
     39 		out += offset;
     40 	}
     41 	if (!_disableOutputLimit) {
     42 		out = clamp(out, -12.0f, 12.0f);
     43 	}
     44 	outputs[OUT_OUTPUT].setChannels(_channels);
     45 	outputs[OUT_OUTPUT].setVoltage(out, c);
     46 }
     47 
     48 float Offset::knobValue(Param& knob, Input& cv, int c) const {
     49 	float v = knob.getValue();
     50 	if (cv.isConnected()) {
     51 		v *= clamp(cv.getPolyVoltage(c) / 10.0f, -1.0f, 1.0f);
     52 	}
     53 	return v;
     54 }
     55 
     56 struct OffsetWidget : DisableOutputLimitModuleWidget {
     57 	static constexpr int hp = 3;
     58 
     59 	OffsetWidget(Offset* module) {
     60 		setModule(module);
     61 		box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
     62 		setPanel(box.size, "Offset");
     63 		createScrews();
     64 
     65 		// generated by svg_widgets.rb
     66 		auto offsetParamPosition = Vec(8.0, 40.0);
     67 		auto scaleParamPosition = Vec(8.0, 152.0);
     68 
     69 		auto offsetInputPosition = Vec(10.5, 81.0);
     70 		auto scaleInputPosition = Vec(10.5, 193.0);
     71 		auto inInputPosition = Vec(10.5, 243.0);
     72 
     73 		auto outOutputPosition = Vec(10.5, 281.0);
     74 		// end generated by svg_widgets.rb
     75 
     76 		addParam(createParam<Knob29>(offsetParamPosition, module, Offset::OFFSET_PARAM));
     77 		addParam(createParam<Knob29>(scaleParamPosition, module, Offset::SCALE_PARAM));
     78 
     79 		addInput(createInput<Port24>(offsetInputPosition, module, Offset::OFFSET_INPUT));
     80 		addInput(createInput<Port24>(scaleInputPosition, module, Offset::SCALE_INPUT));
     81 		addInput(createInput<Port24>(inInputPosition, module, Offset::IN_INPUT));
     82 
     83 		addOutput(createOutput<Port24>(outOutputPosition, module, Offset::OUT_OUTPUT));
     84 	}
     85 
     86 	void contextMenu(Menu* menu) override {
     87 		DisableOutputLimitModuleWidget::contextMenu(menu);
     88 
     89 		auto m = dynamic_cast<Offset*>(module);
     90 		assert(m);
     91 
     92 		OptionsMenuItem* ooo = new OptionsMenuItem("Order of operations");
     93 		ooo->addItem(OptionMenuItem("Scale, then offset", [m]() { return !m->_offsetFirst; }, [m]() { m->_offsetFirst = false; }));
     94 		ooo->addItem(OptionMenuItem("Offset, then scale", [m]() { return m->_offsetFirst; }, [m]() { m->_offsetFirst = true; }));
     95 		OptionsMenuItem::addToMenu(ooo, menu);
     96 	}
     97 };
     98 
     99 Model* modelOffset = bogaudio::createModel<Offset, OffsetWidget>("Bogaudio-Offset", "OFFSET", "CV offset and scaler", "Attenuator", "Polyphonic");