BogaudioModules

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

VCO.cpp (4498B)


      1 
      2 #include "VCO.hpp"
      3 
      4 bool VCO::active() {
      5 	return (
      6 		outputs[SQUARE_OUTPUT].isConnected() ||
      7 		outputs[SAW_OUTPUT].isConnected() ||
      8 		outputs[TRIANGLE_OUTPUT].isConnected() ||
      9 		outputs[SINE_OUTPUT].isConnected()
     10 	);
     11 }
     12 
     13 void VCO::modulate() {
     14 	_slowMode = params[SLOW_PARAM].getValue() > 0.5f;
     15 	_linearMode = params[LINEAR_PARAM].getValue() > 0.5f;
     16 	_fmLinearMode = params[FM_TYPE_PARAM].getValue() < 0.5f;
     17 	_fmDepth = params[FM_PARAM].getValue();
     18 }
     19 
     20 void VCO::modulateChannel(int c) {
     21 	VCOBase::modulateChannel(c);
     22 	Engine& e = *_engines[c];
     23 
     24 	e.squareActive = outputs[SQUARE_OUTPUT].isConnected();
     25 	e.sawActive = outputs[SAW_OUTPUT].isConnected();
     26 	e.triangleActive = outputs[TRIANGLE_OUTPUT].isConnected();
     27 	e.sineActive = outputs[SINE_OUTPUT].isConnected();
     28 
     29 	if (e.squareActive) {
     30 		float pw = params[PW_PARAM].getValue();
     31 		if (inputs[PW_INPUT].isConnected()) {
     32 			pw *= clamp(inputs[PW_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f);
     33 		}
     34 		pw *= 1.0f - 2.0f * e.square.minPulseWidth;
     35 		pw *= 0.5f;
     36 		pw += 0.5f;
     37 		e.square.setPulseWidth(e.squarePulseWidthSL.next(pw), _dcCorrection);
     38 	}
     39 }
     40 
     41 void VCO::processChannel(const ProcessArgs& args, int c) {
     42 	VCOBase::processChannel(args, c);
     43 	Engine& e = *_engines[c];
     44 
     45 	outputs[SQUARE_OUTPUT].setChannels(_channels);
     46 	outputs[SQUARE_OUTPUT].setVoltage(e.squareOut, c);
     47 	outputs[SAW_OUTPUT].setChannels(_channels);
     48 	outputs[SAW_OUTPUT].setVoltage(e.sawOut, c);
     49 	outputs[TRIANGLE_OUTPUT].setChannels(_channels);
     50 	outputs[TRIANGLE_OUTPUT].setVoltage(e.triangleOut, c);
     51 	outputs[SINE_OUTPUT].setChannels(_channels);
     52 	outputs[SINE_OUTPUT].setVoltage(e.sineOut, c);
     53 }
     54 
     55 struct VCOWidget : VCOBaseModuleWidget {
     56 	static constexpr int hp = 10;
     57 
     58 	VCOWidget(VCO* module) {
     59 		setModule(module);
     60 		box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
     61 		setPanel(box.size, "VCO");
     62 		createScrews();
     63 
     64 		// generated by svg_widgets.rb
     65 		auto frequencyParamPosition = Vec(41.0, 45.0);
     66 		auto fineParamPosition = Vec(48.0, 153.0);
     67 		auto slowParamPosition = Vec(114.0, 149.7);
     68 		auto linearParamPosition = Vec(114.0, 162.7);
     69 		auto pwParamPosition = Vec(62.0, 188.0);
     70 		auto fmParamPosition = Vec(62.0, 230.0);
     71 		auto fmTypeParamPosition = Vec(100.5, 231.5);
     72 
     73 		auto pwInputPosition = Vec(15.0, 274.0);
     74 		auto fmInputPosition = Vec(47.0, 274.0);
     75 		auto pitchInputPosition = Vec(15.0, 318.0);
     76 		auto syncInputPosition = Vec(47.0, 318.0);
     77 
     78 		auto squareOutputPosition = Vec(79.0, 274.0);
     79 		auto sawOutputPosition = Vec(111.0, 274.0);
     80 		auto triangleOutputPosition = Vec(79.0, 318.0);
     81 		auto sineOutputPosition = Vec(111.0, 318.0);
     82 		// end generated by svg_widgets.rb
     83 
     84 		addParam(createParam<Knob68>(frequencyParamPosition, module, VCO::FREQUENCY_PARAM));
     85 		addParam(createParam<Knob16>(fineParamPosition, module, VCO::FINE_PARAM));
     86 		addParam(createParam<IndicatorButtonGreen9>(slowParamPosition, module, VCO::SLOW_PARAM));
     87 		addParam(createParam<Knob26>(pwParamPosition, module, VCO::PW_PARAM));
     88 		addParam(createParam<Knob26>(fmParamPosition, module, VCO::FM_PARAM));
     89 		addParam(createParam<SliderSwitch2State14>(fmTypeParamPosition, module, VCO::FM_TYPE_PARAM));
     90 		addParam(createParam<IndicatorButtonGreen9>(linearParamPosition, module, VCO::LINEAR_PARAM));
     91 
     92 		addInput(createInput<Port24>(pitchInputPosition, module, VCO::PITCH_INPUT));
     93 		addInput(createInput<Port24>(syncInputPosition, module, VCO::SYNC_INPUT));
     94 		addInput(createInput<Port24>(pwInputPosition, module, VCO::PW_INPUT));
     95 		addInput(createInput<Port24>(fmInputPosition, module, VCO::FM_INPUT));
     96 
     97 		addOutput(createOutput<Port24>(squareOutputPosition, module, VCO::SQUARE_OUTPUT));
     98 		addOutput(createOutput<Port24>(sawOutputPosition, module, VCO::SAW_OUTPUT));
     99 		addOutput(createOutput<Port24>(triangleOutputPosition, module, VCO::TRIANGLE_OUTPUT));
    100 		addOutput(createOutput<Port24>(sineOutputPosition, module, VCO::SINE_OUTPUT));
    101 	}
    102 
    103 	void contextMenu(Menu* menu) override {
    104 		auto m = dynamic_cast<VCO*>(module);
    105 		assert(m);
    106 		OptionsMenuItem* p = new OptionsMenuItem("Polyphony channels from");
    107 		p->addItem(OptionMenuItem("V/OCT input", [m]() { return m->_polyInputID == VCO::PITCH_INPUT; }, [m]() { m->_polyInputID = VCO::PITCH_INPUT; }));
    108 		p->addItem(OptionMenuItem("FM input", [m]() { return m->_polyInputID == VCO::FM_INPUT; }, [m]() { m->_polyInputID = VCO::FM_INPUT; }));
    109 		OptionsMenuItem::addToMenu(p, menu);
    110 
    111 		VCOBaseModuleWidget::contextMenu(menu);
    112 	}
    113 };
    114 
    115 Model* modelVCO = bogaudio::createModel<VCO, VCOWidget>("Bogaudio-VCO", "VCO", "Oscillator", "Oscillator", "Polyphonic");