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