BogaudioModules

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

Unison.cpp (2629B)


      1 
      2 #include "Unison.hpp"
      3 
      4 void Unison::modulate() {
      5 	_channels = clamp((int)params[CHANNELS_PARAM].getValue(), 1, 16);
      6 
      7 	_cents = clamp(params[DETUNE_PARAM].getValue(), 0.0f, maxDetuneCents);
      8 	if (inputs[DETUNE_INPUT].isConnected()) {
      9 		_cents *= clamp(inputs[DETUNE_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
     10 	}
     11 	_cents /= 100.0f;
     12 }
     13 
     14 void Unison::processAll(const ProcessArgs& args) {
     15 	float pitch = inputs[PITCH_INPUT].getVoltage();
     16 	float gate = inputs[GATE_INPUT].getVoltage();
     17 	outputs[PITCH_OUTPUT].setChannels(_channels);
     18 	outputs[GATE_OUTPUT].setChannels(_channels);
     19 
     20 	if (_cents < 0.001f) {
     21 		for (int c = 0; c < _channels; ++c) {
     22 			outputs[PITCH_OUTPUT].setVoltage(pitch, c);
     23 			outputs[GATE_OUTPUT].setVoltage(gate, c);
     24 		}
     25 	}
     26 	else {
     27 		int offset = 0;
     28 		if (_channels % 2 == 1) {
     29 			offset = 1;
     30 			outputs[PITCH_OUTPUT].setVoltage(pitch, 0);
     31 			outputs[GATE_OUTPUT].setVoltage(gate, 0);
     32 		}
     33 		float divisions = 1.0f / ((_channels - offset) / 2);
     34 		for (int c = 0; c < _channels - offset; ++c) {
     35 			float cents = _cents * divisions * (float)(1 + c / 2);
     36 			float p = pitch + (c % 2 == 0 ? 1.0f : -1.0f) * cents * (1.0f / 12.0f);
     37 			outputs[PITCH_OUTPUT].setVoltage(p, c + offset);
     38 			outputs[GATE_OUTPUT].setVoltage(gate, c + offset);
     39 		}
     40 	}
     41 }
     42 
     43 struct UnisonWidget : BGModuleWidget {
     44 	static constexpr int hp = 3;
     45 
     46 	UnisonWidget(Unison* module) {
     47 		setModule(module);
     48 		box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
     49 		setPanel(box.size, "Unison");
     50 		createScrews();
     51 
     52 		// generated by svg_widgets.rb
     53 		auto channelsParamPosition = Vec(9.5, 34.0);
     54 		auto detuneParamPosition = Vec(9.5, 89.0);
     55 
     56 		auto detuneInputPosition = Vec(10.5, 127.0);
     57 		auto pitchInputPosition = Vec(10.5, 174.0);
     58 		auto gateInputPosition = Vec(10.5, 209.0);
     59 
     60 		auto pitchOutputPosition = Vec(10.5, 247.0);
     61 		auto gateOutputPosition = Vec(10.5, 282.0);
     62 		// end generated by svg_widgets.rb
     63 
     64 		addParam(createParam<Knob26>(channelsParamPosition, module, Unison::CHANNELS_PARAM));
     65 		addParam(createParam<Knob26>(detuneParamPosition, module, Unison::DETUNE_PARAM));
     66 
     67 		addInput(createInput<Port24>(detuneInputPosition, module, Unison::DETUNE_INPUT));
     68 		addInput(createInput<Port24>(pitchInputPosition, module, Unison::PITCH_INPUT));
     69 		addInput(createInput<Port24>(gateInputPosition, module, Unison::GATE_INPUT));
     70 
     71 		addOutput(createOutput<Port24>(pitchOutputPosition, module, Unison::PITCH_OUTPUT));
     72 		addOutput(createOutput<Port24>(gateOutputPosition, module, Unison::GATE_OUTPUT));
     73 	}
     74 };
     75 
     76 Model* modelUnison = createModel<Unison, UnisonWidget>("Bogaudio-Unison", "UNISON", "Polyphonic unison voicing processor with detune", "Polyphonic");