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");