BogaudioModules

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

PEQ14XV.cpp (6777B)


      1 
      2 #include "PEQ14XV.hpp"
      3 #include "dsp/pitch.hpp"
      4 
      5 PEQ14XV::Engine::Engine() {
      6 	filters[0] = new MultimodeFilter8();
      7 	for (int i = 1; i < 13; ++i) {
      8 		filters[i] = new MultimodeFilter4();
      9 	}
     10 	filters[13] = new MultimodeFilter8();
     11 }
     12 
     13 PEQ14XV::Engine::~Engine() {
     14 	for (int i = 0; i < 14; ++i) {
     15 		delete filters[i];
     16 	}
     17 }
     18 
     19 void PEQ14XV::addChannel(int c) {
     20 	_engines[c] = new Engine();
     21 }
     22 
     23 void PEQ14XV::removeChannel(int c) {
     24 	delete _engines[c];
     25 	_engines[c] = NULL;
     26 }
     27 
     28 void PEQ14XV::modulate() {
     29 	float outGain = clamp(params[OUTPUT_GAIN_PARAM].getValue(), 0.0f, 1.0f);
     30 	outGain *= maxOutputGain;
     31 	_outputGain.setLevel(outGain);
     32 
     33 	float b14Mix = clamp(params[BAND14_MIX_PARAM].getValue(), 0.0f, 1.0f);
     34 	b14Mix = 1.0f - b14Mix;
     35 	b14Mix *= Amplifier::minDecibels;
     36 	_band14Mix.setLevel(b14Mix);
     37 
     38 	_band1Enable = params[BAND1_ENABLE_PARAM].getValue() > 0.5f;
     39 	_band14Enable = params[BAND14_ENABLE_PARAM].getValue() > 0.5f;
     40 }
     41 
     42 void PEQ14XV::modulateChannel(int c) {
     43 	Engine& e = *_engines[c];
     44 
     45 	float sr = APP->engine->getSampleRate();
     46 	float response = sensitivity(params[EF_DAMP_PARAM], &inputs[EF_DAMP_INPUT], c);
     47 	if (e.response != response) {
     48 		e.response = response;
     49 		for (int i = 0; i < 14; ++i) {
     50 			e.efs[i].setParams(sr, e.response);
     51 		}
     52 	}
     53 
     54 	e.efGain.setLevel(gain(params[EF_GAIN_PARAM], &inputs[EF_GAIN_INPUT], c));
     55 
     56 	float transpose = clamp(params[TRANSPOSE_PARAM].getValue(), -1.0f, 1.0f);
     57 	if (inputs[TRANSPOSE_INPUT].isConnected()) {
     58 		transpose *= clamp(inputs[TRANSPOSE_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f);
     59 	}
     60 	e.transposeSemitones = 24.0f * transpose;
     61 }
     62 
     63 void PEQ14XV::processAlways(const ProcessArgs& args) {
     64 	outputs[OUT_OUTPUT].setChannels(_channels);
     65 	outputs[ODDS_OUTPUT].setChannels(_channels);
     66 	outputs[EVENS_OUTPUT].setChannels(_channels);
     67 
     68 	_baseMessage = NULL;
     69 	if (baseConnected()) {
     70 		_baseMessage = fromBase();
     71 	}
     72 
     73 	if (expanderConnected()) {
     74 		if (_baseMessage) {
     75 			// *toExpander() = *_baseMessage;
     76 			_baseMessage->copyTo(toExpander());
     77 		}
     78 		else {
     79 			toExpander()->reset();
     80 		}
     81 	}
     82 }
     83 
     84 void PEQ14XV::processChannel(const ProcessArgs& args, int c) {
     85 	if (_baseMessage && _baseMessage->valid) {
     86 		Engine& e = *_engines[c];
     87 		float in = inputs[IN_INPUT].getPolyVoltage(c);
     88 		float out = 0.0f;
     89 		float odds = 0.0f;
     90 		float evens = 0.0f;
     91 		for (int i = 0; i < 14; ++i) {
     92 			auto mode = MultimodeFilter::BANDPASS_MODE;
     93 			int poles = 4;
     94 			float bandwidth = _baseMessage->bandwidths[c];
     95 			if (i == 0 && _baseMessage->lowLP) {
     96 				mode = MultimodeFilter::LOWPASS_MODE;
     97 				poles = 12;
     98 				bandwidth = MultimodeFilter::minQbw;
     99 			}
    100 			if (i == 13 && _baseMessage->highHP) {
    101 				mode = MultimodeFilter::HIGHPASS_MODE;
    102 				poles = 12;
    103 				bandwidth = MultimodeFilter::minQbw;
    104 			}
    105 			float f = _baseMessage->frequencies[c][i];
    106 			if (e.transposeSemitones > 0.01f || e.transposeSemitones < -0.01f) {
    107 				f = frequencyToSemitone(f);
    108 				f += e.transposeSemitones;
    109 				f = semitoneToFrequency(f);
    110 			}
    111 			if (f < MultimodeFilter::minFrequency || f > MultimodeFilter::maxFrequency) {
    112 				continue;
    113 			}
    114 
    115 			e.filters[i]->setParams(
    116 				APP->engine->getSampleRate(),
    117 				MultimodeFilter::BUTTERWORTH_TYPE,
    118 				poles,
    119 				mode,
    120 				f,
    121 				bandwidth,
    122 				MultimodeFilter::PITCH_BANDWIDTH_MODE
    123 			);
    124 
    125 			float level = e.efs[i].next(_baseMessage->outs[c][i]);
    126 			level = scaleEF(level, _baseMessage->frequencies[c][i], _baseMessage->bandwidths[c]);
    127 			level = e.efGain.next(level);
    128 			level *= 0.1f;
    129 			level = std::max(0.0f, std::min(1.0f, level));
    130 			level = 1.0f - level;
    131 			level *= Amplifier::minDecibels;
    132 			e.amplifiers[i].setLevel(level);
    133 
    134 			float o = e.amplifiers[i].next(e.filters[i]->next(in));
    135 			o = _outputGain.next(o);
    136 			out += (float)((i != 0 || _band1Enable) && (i != 13 || _band14Enable)) * o;
    137 			odds += (float)(i % 2 == 0 && (i != 0 || _band1Enable)) * o;
    138 			evens += (float)(i % 2 == 1 && (i != 13 || _band14Enable)) * o;
    139 		}
    140 
    141 		float band14raw = _baseMessage->outs[c][13];
    142 		band14raw = _band14Mix.next(band14raw);
    143 		out += band14raw;
    144 		odds += band14raw;
    145 		evens += band14raw;
    146 
    147 		outputs[OUT_OUTPUT].setVoltage(_saturator.next(out), c);
    148 		outputs[ODDS_OUTPUT].setVoltage(_saturator.next(odds), c);
    149 		outputs[EVENS_OUTPUT].setVoltage(_saturator.next(evens), c);
    150 	}
    151 	else {
    152 		outputs[OUT_OUTPUT].setVoltage(0.0f, c);
    153 		outputs[ODDS_OUTPUT].setVoltage(0.0f, c);
    154 		outputs[EVENS_OUTPUT].setVoltage(0.0f, c);
    155 	}
    156 }
    157 
    158 struct PEQ14XVWidget : BGModuleWidget {
    159 	static constexpr int hp = 5;
    160 
    161 	PEQ14XVWidget(PEQ14XV* module) {
    162 		setModule(module);
    163 		box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
    164 		setPanel(box.size, "PEQ14XV");
    165 		createScrews();
    166 
    167 		// generated by svg_widgets.rb
    168 		auto efDampParamPosition = Vec(12.0, 40.0);
    169 		auto efGainParamPosition = Vec(47.0, 40.0);
    170 		auto transposeParamPosition = Vec(24.5, 132.0);
    171 		auto outputGainParamPosition = Vec(12.0, 227.0);
    172 		auto band14MixParamPosition = Vec(47.0, 227.0);
    173 		auto band1EnableParamPosition = Vec(19.5, 262.0);
    174 		auto band14EnableParamPosition = Vec(57.0, 262.0);
    175 
    176 		auto efDampInputPosition = Vec(8.0, 73.0);
    177 		auto efGainInputPosition = Vec(43.0, 73.0);
    178 		auto transposeInputPosition = Vec(25.5, 169.0);
    179 		auto inInputPosition = Vec(10.5, 290.0);
    180 
    181 		auto oddsOutputPosition = Vec(40.5, 290.0);
    182 		auto outOutputPosition = Vec(10.5, 325.0);
    183 		auto evensOutputPosition = Vec(40.5, 325.0);
    184 		// end generated by svg_widgets.rb
    185 
    186 		addParam(createParam<Knob16>(efDampParamPosition, module, PEQ14XV::EF_DAMP_PARAM));
    187 		addParam(createParam<Knob16>(efGainParamPosition, module, PEQ14XV::EF_GAIN_PARAM));
    188 		addParam(createParam<Knob26>(transposeParamPosition, module, PEQ14XV::TRANSPOSE_PARAM));
    189 		addParam(createParam<Knob16>(outputGainParamPosition, module, PEQ14XV::OUTPUT_GAIN_PARAM));
    190 		addParam(createParam<Knob16>(band14MixParamPosition, module, PEQ14XV::BAND14_MIX_PARAM));
    191 		addParam(createParam<IndicatorButtonGreen9>(band1EnableParamPosition, module, PEQ14XV::BAND1_ENABLE_PARAM));
    192 		addParam(createParam<IndicatorButtonGreen9>(band14EnableParamPosition, module, PEQ14XV::BAND14_ENABLE_PARAM));
    193 
    194 		addInput(createInput<Port24>(efDampInputPosition, module, PEQ14XV::EF_DAMP_INPUT));
    195 		addInput(createInput<Port24>(efGainInputPosition, module, PEQ14XV::EF_GAIN_INPUT));
    196 		addInput(createInput<Port24>(transposeInputPosition, module, PEQ14XV::TRANSPOSE_INPUT));
    197 		addInput(createInput<Port24>(inInputPosition, module, PEQ14XV::IN_INPUT));
    198 
    199 		addOutput(createOutput<Port24>(oddsOutputPosition, module, PEQ14XV::ODDS_OUTPUT));
    200 		addOutput(createOutput<Port24>(outOutputPosition, module, PEQ14XV::OUT_OUTPUT));
    201 		addOutput(createOutput<Port24>(evensOutputPosition, module, PEQ14XV::EVENS_OUTPUT));
    202 	}
    203 };
    204 
    205 Model* modelPEQ14XV = createModel<PEQ14XV, PEQ14XVWidget>("Bogaudio-PEQ14XV", "PEQ14XV", "PEQ14 vocoder expander", "Filter", "Vocoder", "Expander", "Polyphonic");