Velo.cpp (4156B)
1 2 #include "Velo.hpp" 3 4 #define LEVEL_SCALES_CV "level_scales_cv" 5 6 bool Velo::LevelParamQuantity::isLinear() { 7 return dynamic_cast<Velo*>(module)->isLinear(); 8 } 9 10 void Velo::sampleRateChange() { 11 float sampleRate = APP->engine->getSampleRate(); 12 for (int c = 0; c < maxChannels; ++c) { 13 _levelSL[c].setParams(sampleRate, 5.0f, 1.0f); 14 _velocitySL[c].setParams(sampleRate, 5.0f, 1.0f); 15 } 16 } 17 18 json_t* Velo::saveToJson(json_t* root) { 19 json_object_set_new(root, LEVEL_SCALES_CV, json_boolean(_levelScalesCV)); 20 return root; 21 } 22 23 void Velo::loadFromJson(json_t* root) { 24 json_t* s = json_object_get(root, LEVEL_SCALES_CV); 25 if (s) { 26 _levelScalesCV = json_boolean_value(s); 27 } 28 } 29 30 bool Velo::active() { 31 return inputs[IN_INPUT].isConnected() && outputs[OUT_OUTPUT].isConnected(); 32 } 33 34 void Velo::modulate() { 35 _velocityDb = clamp(params[VELOCITY_PARAM].getValue(), 0.0f, 1.0f); 36 _velocityDb *= _velocityDb; 37 _velocityDb *= Amplifier::minDecibels; 38 assert(_velocityDb <= 0.0f); 39 } 40 41 void Velo::processAll(const ProcessArgs& args) { 42 int n = inputs[IN_INPUT].getChannels(); 43 outputs[OUT_OUTPUT].setChannels(n); 44 for (int c = 0; c < n; ++c) { 45 float level = clamp(params[LEVEL_PARAM].getValue(), 0.0f, 1.0f); 46 if (inputs[LEVEL_INPUT].isConnected()) { 47 level *= clamp(inputs[LEVEL_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); 48 } 49 if (inputs[CV_INPUT].isConnected()) { 50 float cv = clamp(inputs[CV_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); 51 cv *= clamp(params[LEVEL_ATTENUATOR_PARAM].getValue(), -1.0f, 1.0f); 52 if (_levelScalesCV) { 53 level += level * cv; 54 } 55 else { 56 level += cv; 57 } 58 } 59 level = clamp(level, 0.0f, 2.0f); 60 level = _levelSL[c].next(level); 61 62 float velocity = 1.0f; 63 if (inputs[VELOCITY_INPUT].isConnected()) { 64 velocity = clamp(inputs[VELOCITY_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); 65 } 66 velocity = _velocitySL[c].next(velocity); 67 _velocity[c].setLevel((1.0f - velocity) * _velocityDb); 68 69 float out = inputs[IN_INPUT].getVoltage(c); 70 if (isLinear()) { 71 out *= level; 72 } 73 else { 74 level = 1.0f - level; 75 level *= Amplifier::minDecibels; 76 level = std::min(level, 12.0f); 77 _amplifier[c].setLevel(level); 78 out = _amplifier[c].next(out); 79 } 80 out = _velocity[c].next(out); 81 out = _saturator[c].next(out); 82 outputs[OUT_OUTPUT].setVoltage(out, c); 83 } 84 } 85 86 struct VeloWidget : BGModuleWidget { 87 static constexpr int hp = 3; 88 89 VeloWidget(Velo* module) { 90 setModule(module); 91 box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT); 92 setPanel(box.size, "Velo"); 93 createScrews(); 94 95 // generated by svg_widgets.rb 96 auto levelParamPosition = Vec(9.5, 34.5); 97 auto levelAttenuatorParamPosition = Vec(14.5, 75.0); 98 auto velocityParamPosition = Vec(14.5, 115.0); 99 auto linearParamPosition = Vec(25.5, 143.0); 100 101 auto levelInputPosition = Vec(10.5, 160.0); 102 auto cvInputPosition = Vec(10.5, 195.0); 103 auto velocityInputPosition = Vec(10.5, 230.0); 104 auto inInputPosition = Vec(10.5, 265.0); 105 106 auto outOutputPosition = Vec(10.5, 303.0); 107 // end generated by svg_widgets.rb 108 109 addParam(createParam<Knob26>(levelParamPosition, module, Velo::LEVEL_PARAM)); 110 addParam(createParam<Knob16>(levelAttenuatorParamPosition, module, Velo::LEVEL_ATTENUATOR_PARAM)); 111 addParam(createParam<Knob16>(velocityParamPosition, module, Velo::VELOCITY_PARAM)); 112 addParam(createParam<IndicatorButtonGreen9>(linearParamPosition, module, Velo::LINEAR_PARAM)); 113 114 addInput(createInput<Port24>(levelInputPosition, module, Velo::LEVEL_INPUT)); 115 addInput(createInput<Port24>(cvInputPosition, module, Velo::CV_INPUT)); 116 addInput(createInput<Port24>(velocityInputPosition, module, Velo::VELOCITY_INPUT)); 117 addInput(createInput<Port24>(inInputPosition, module, Velo::IN_INPUT)); 118 119 addOutput(createOutput<Port24>(outOutputPosition, module, Velo::OUT_OUTPUT)); 120 } 121 122 void contextMenu(Menu* menu) override { 123 auto m = dynamic_cast<Velo*>(module); 124 assert(m); 125 menu->addChild(new BoolOptionMenuItem("Level knob/CV scales bipolar CV", [m]() { return &m->_levelScalesCV; })); 126 } 127 }; 128 129 Model* modelVelo = createModel<Velo, VeloWidget>("Bogaudio-Velo", "VELO", "Triple-CV VCA, for tremolo, MIDI velocity, etc", "VCA", "Polyphonic");