BogaudioModules

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

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