BogaudioModules

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

Pulse.cpp (3039B)


      1 
      2 #include "Pulse.hpp"
      3 
      4 #define LINEAR_MODE "linear_mode"
      5 
      6 json_t* Pulse::saveToJson(json_t* root) {
      7 	root = VCOBase::saveToJson(root);
      8 	json_object_set_new(root, LINEAR_MODE, json_boolean(_linearMode));
      9 	return root;
     10 }
     11 
     12 void Pulse::loadFromJson(json_t* root) {
     13 	VCOBase::loadFromJson(root);
     14 	json_t* l = json_object_get(root, LINEAR_MODE);
     15 	if (l) {
     16 		_linearMode = json_is_true(l);
     17 	}
     18 }
     19 
     20 bool Pulse::active() {
     21 	return outputs[OUT_OUTPUT].isConnected();
     22 }
     23 
     24 void Pulse::addChannel(int c) {
     25 	VCOBase::addChannel(c);
     26 	_engines[c]->squareActive = true;
     27 }
     28 
     29 void Pulse::modulate() {
     30 	_slowMode = params[SLOW_PARAM].getValue() > 0.5f;
     31 }
     32 
     33 void Pulse::modulateChannel(int c) {
     34 	VCOBase::modulateChannel(c);
     35 	Engine& e = *_engines[c];
     36 
     37 	float pw = params[PW_PARAM].getValue();
     38 	if (inputs[PWM_INPUT].isConnected()) {
     39 		float pwm = clamp(inputs[PWM_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f);
     40 		pwm *= clamp(params[PWM_PARAM].getValue(), -1.0f, 1.0f);
     41 		pw = clamp(pw + pwm, -1.0f, 1.0f);
     42 	}
     43 	pw *= 1.0f - 2.0f * e.square.minPulseWidth;
     44 	pw *= 0.5f;
     45 	pw += 0.5f;
     46 	e.square.setPulseWidth(e.squarePulseWidthSL.next(pw), _dcCorrection);
     47 }
     48 
     49 void Pulse::processChannel(const ProcessArgs& args, int c) {
     50 	VCOBase::processChannel(args, c);
     51 
     52 	outputs[OUT_OUTPUT].setChannels(_channels);
     53 	outputs[OUT_OUTPUT].setVoltage(_engines[c]->squareOut, c);
     54 }
     55 
     56 struct PulseWidget : VCOBaseModuleWidget {
     57 	static constexpr int hp = 3;
     58 
     59 	PulseWidget(Pulse* module) {
     60 		setModule(module);
     61 		box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
     62 		setPanel(box.size, "Pulse");
     63 		createScrews();
     64 
     65 		// generated by svg_widgets.rb
     66 		auto frequencyParamPosition = Vec(9.5, 27.0);
     67 		auto slowParamPosition = Vec(31.0, 62.0);
     68 		auto pwParamPosition = Vec(9.5, 98.5);
     69 		auto pwmParamPosition = Vec(14.5, 154.5);
     70 
     71 		auto pitchInputPosition = Vec(10.5, 185.0);
     72 		auto pwmInputPosition = Vec(10.5, 220.0);
     73 		auto syncInputPosition = Vec(10.5, 255.0);
     74 
     75 		auto outOutputPosition = Vec(10.5, 293.0);
     76 		// end generated by svg_widgets.rb
     77 
     78 		addParam(createParam<Knob26>(frequencyParamPosition, module, Pulse::FREQUENCY_PARAM));
     79 		addParam(createParam<IndicatorButtonGreen9>(slowParamPosition, module, Pulse::SLOW_PARAM));
     80 		addParam(createParam<Knob26>(pwParamPosition, module, Pulse::PW_PARAM));
     81 		addParam(createParam<Knob16>(pwmParamPosition, module, Pulse::PWM_PARAM));
     82 
     83 		addInput(createInput<Port24>(pitchInputPosition, module, Pulse::PITCH_INPUT));
     84 		addInput(createInput<Port24>(pwmInputPosition, module, Pulse::PWM_INPUT));
     85 		addInput(createInput<Port24>(syncInputPosition, module, Pulse::SYNC_INPUT));
     86 
     87 		addOutput(createOutput<Port24>(outOutputPosition, module, Pulse::OUT_OUTPUT));
     88 	}
     89 
     90 	void contextMenu(Menu* menu) override {
     91 		auto m = dynamic_cast<Pulse*>(module);
     92 		assert(m);
     93 		menu->addChild(new BoolOptionMenuItem("Linear frequency mode", [m]() { return &m->_linearMode; }));
     94 
     95 		VCOBaseModuleWidget::contextMenu(menu);
     96 	}
     97 };
     98 
     99 Model* modelPulse = createModel<Pulse, PulseWidget>("Bogaudio-Pulse", "PULSE", "Square/pulse oscillator", "Oscillator", "Polyphonic");