BogaudioModules

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

PEQ6.cpp (10230B)


      1 
      2 #include "PEQ6.hpp"
      3 
      4 void PEQ6::sampleRateChange() {
      5 	float sr = APP->engine->getSampleRate();
      6 	for (int c = 0; c < _channels; ++c) {
      7 		_engines[c]->setSampleRate(sr);
      8 	}
      9 }
     10 
     11 bool PEQ6::active() {
     12 	return
     13 		outputs[OUT_OUTPUT].isConnected() ||
     14 		outputs[OUT1_OUTPUT].isConnected() ||
     15 		outputs[OUT2_OUTPUT].isConnected() ||
     16 		outputs[OUT3_OUTPUT].isConnected() ||
     17 		outputs[OUT4_OUTPUT].isConnected() ||
     18 		outputs[OUT5_OUTPUT].isConnected() ||
     19 		outputs[OUT6_OUTPUT].isConnected() ||
     20 		expanderConnected();
     21 }
     22 
     23 int PEQ6::channels() {
     24 	return inputs[IN_INPUT].getChannels();
     25 }
     26 
     27 void PEQ6::addChannel(int c) {
     28 	const int n = 6;
     29 	_engines[c] = new PEQEngine(n);
     30 	for (int i = 0; i < n; ++i) {
     31 		_engines[c]->configChannel(
     32 			i,
     33 			c,
     34 			params[LEVEL1_PARAM + i*3],
     35 			params[FREQUENCY1_PARAM + i*3],
     36 			params[FREQUENCY_CV1_PARAM + i*3],
     37 			&params[FREQUENCY_CV_PARAM],
     38 			params[BANDWIDTH_PARAM],
     39 			inputs[LEVEL1_INPUT + i*2],
     40 			inputs[FREQUENCY_CV1_INPUT + i*2],
     41 			inputs[FREQUENCY_CV_INPUT],
     42 			&inputs[BANDWIDTH_INPUT]
     43 		);
     44 	}
     45 	_engines[c]->setSampleRate(APP->engine->getSampleRate());
     46 }
     47 
     48 void PEQ6::removeChannel(int c) {
     49 	delete _engines[c];
     50 	_engines[c] = NULL;
     51 }
     52 
     53 void PEQ6::modulate() {
     54 	_fullFrequencyMode = params[FMOD_PARAM].getValue() > 0.5f;
     55 
     56 	auto lowMode = params[LP_PARAM].getValue() > 0.5f ? MultimodeFilter::LOWPASS_MODE : MultimodeFilter::BANDPASS_MODE;
     57 	auto highMode = params[HP_PARAM].getValue() > 0.5f ? MultimodeFilter::HIGHPASS_MODE : MultimodeFilter::BANDPASS_MODE;
     58 	for (int c = 0; c < _channels; ++c) {
     59 		PEQEngine& e = *_engines[c];
     60 		e.setLowFilterMode(lowMode);
     61 		e.setHighFilterMode(highMode);
     62 		e.setFrequencyMode(_fullFrequencyMode);
     63 		e.modulate();
     64 	}
     65 }
     66 
     67 void PEQ6::processAlways(const ProcessArgs& args) {
     68 	outputs[OUT_OUTPUT].setChannels(_channels);
     69 	for (int i = 0; i < 6; ++i) {
     70 		outputs[OUT1_OUTPUT + i].setChannels(_channels);
     71 	}
     72 	std::fill(_rmsSums, _rmsSums + 6, 0.0f);
     73 
     74 	_expanderMessage = NULL;
     75 	if (expanderConnected()) {
     76 		_expanderMessage = toExpander();
     77 	}
     78 }
     79 
     80 void PEQ6::processChannel(const ProcessArgs& args, int c) {
     81 	PEQEngine& e = *_engines[c];
     82 	float out = e.next(inputs[IN_INPUT].getVoltage(c), _rmsSums);
     83 	float beOut = 0.0f;
     84 	for (int i = 0; i < 6; ++i) {
     85 		if (outputs[OUT1_OUTPUT + i].isConnected()) {
     86 			outputs[OUT1_OUTPUT + i].setVoltage(e.outs[i], c);
     87 		}
     88 		else {
     89 			beOut += e.outs[i];
     90 		}
     91 	}
     92 	if (_bandExclude) {
     93 		outputs[OUT_OUTPUT].setVoltage(beOut, c);
     94 	}
     95 	else {
     96 		outputs[OUT_OUTPUT].setVoltage(out, c);
     97 	}
     98 
     99 	if (_expanderMessage) {
    100 		std::copy(e.outs, e.outs + 6, _expanderMessage->outs[c]);
    101 		std::copy(e.frequencies, e.frequencies + 6, _expanderMessage->frequencies[c]);
    102 		_expanderMessage->bandwidths[c] = e.bandwidth;
    103 	}
    104 }
    105 
    106 void PEQ6::postProcessAlways(const ProcessArgs& args) {
    107 	for (int i = 0; i < 6; ++i) {
    108 		_rms[i] = _rmsSums[i] * _inverseChannels;
    109 	}
    110 
    111 	bool ffm = params[FMOD_PARAM].getValue() > 0.5f;
    112 	lights[FMOD_RELATIVE_LIGHT].value = !ffm;
    113 	lights[FMOD_FULL_LIGHT].value = ffm;
    114 }
    115 
    116 struct PEQ6Widget : BandExcludeModuleWidget {
    117 	static constexpr int hp = 21;
    118 
    119 	PEQ6Widget(PEQ6* module) {
    120 		setModule(module);
    121 		box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
    122 		setPanel(box.size, "PEQ6");
    123 		createScrews();
    124 
    125 		// generated by svg_widgets.rb
    126 		auto frequencyCvParamPosition = Vec(14.5, 47.0);
    127 		auto bandwidthParamPosition = Vec(14.5, 129.0);
    128 		auto lpParamPosition = Vec(35.5, 210.0);
    129 		auto hpParamPosition = Vec(35.5, 222.0);
    130 		auto fmodParamPosition = Vec(20.0, 267.0);
    131 		auto level1ParamPosition = Vec(58.5, 28.0);
    132 		auto frequency1ParamPosition = Vec(59.5, 184.0);
    133 		auto frequencyCv1ParamPosition = Vec(59.5, 224.0);
    134 		auto level2ParamPosition = Vec(103.5, 28.0);
    135 		auto frequency2ParamPosition = Vec(104.5, 184.0);
    136 		auto frequencyCv2ParamPosition = Vec(104.5, 224.0);
    137 		auto level3ParamPosition = Vec(148.5, 28.0);
    138 		auto frequency3ParamPosition = Vec(149.5, 184.0);
    139 		auto frequencyCv3ParamPosition = Vec(149.5, 224.0);
    140 		auto level4ParamPosition = Vec(193.5, 28.0);
    141 		auto frequency4ParamPosition = Vec(194.5, 184.0);
    142 		auto frequencyCv4ParamPosition = Vec(194.5, 224.0);
    143 		auto level5ParamPosition = Vec(238.5, 28.0);
    144 		auto frequency5ParamPosition = Vec(239.5, 184.0);
    145 		auto frequencyCv5ParamPosition = Vec(239.5, 224.0);
    146 		auto level6ParamPosition = Vec(283.5, 28.0);
    147 		auto frequency6ParamPosition = Vec(284.5, 183.0);
    148 		auto frequencyCv6ParamPosition = Vec(284.5, 224.0);
    149 
    150 		auto frequencyCvInputPosition = Vec(10.5, 79.0);
    151 		auto bandwidthInputPosition = Vec(10.5, 163.0);
    152 		auto inInputPosition = Vec(10.5, 290.0);
    153 		auto level1InputPosition = Vec(55.5, 255.0);
    154 		auto frequencyCv1InputPosition = Vec(55.5, 290.0);
    155 		auto level2InputPosition = Vec(100.5, 255.0);
    156 		auto frequencyCv2InputPosition = Vec(100.5, 290.0);
    157 		auto level3InputPosition = Vec(145.5, 255.0);
    158 		auto frequencyCv3InputPosition = Vec(145.5, 290.0);
    159 		auto level4InputPosition = Vec(190.5, 255.0);
    160 		auto frequencyCv4InputPosition = Vec(190.5, 290.0);
    161 		auto level5InputPosition = Vec(235.5, 255.0);
    162 		auto frequencyCv5InputPosition = Vec(235.5, 290.0);
    163 		auto level6InputPosition = Vec(280.5, 255.0);
    164 		auto frequencyCv6InputPosition = Vec(280.5, 290.0);
    165 
    166 		auto outOutputPosition = Vec(10.5, 325.0);
    167 		auto out1OutputPosition = Vec(55.5, 325.0);
    168 		auto out2OutputPosition = Vec(100.5, 325.0);
    169 		auto out3OutputPosition = Vec(145.5, 325.0);
    170 		auto out4OutputPosition = Vec(190.5, 325.0);
    171 		auto out5OutputPosition = Vec(235.5, 325.0);
    172 		auto out6OutputPosition = Vec(280.5, 325.0);
    173 
    174 		auto fmodRelativeLightPosition = Vec(16.0, 243.0);
    175 		auto fmodFullLightPosition = Vec(16.0, 256.0);
    176 		// end generated by svg_widgets.rb
    177 
    178 		addParam(createParam<Knob16>(frequencyCvParamPosition, module, PEQ6::FREQUENCY_CV_PARAM));
    179 		addParam(createParam<Knob16>(bandwidthParamPosition, module, PEQ6::BANDWIDTH_PARAM));
    180 		addParam(createParam<IndicatorButtonGreen9>(lpParamPosition, module, PEQ6::LP_PARAM));
    181 		addParam(createParam<IndicatorButtonGreen9>(hpParamPosition, module, PEQ6::HP_PARAM));
    182 		addParam(createParam<StatefulButton9>(fmodParamPosition, module, PEQ6::FMOD_PARAM));
    183 		addSlider(level1ParamPosition, module, PEQ6::LEVEL1_PARAM, module ? &module->_rms[0] : NULL);
    184 		addParam(createParam<Knob16>(frequency1ParamPosition, module, PEQ6::FREQUENCY1_PARAM));
    185 		addParam(createParam<Knob16>(frequencyCv1ParamPosition, module, PEQ6::FREQUENCY_CV1_PARAM));
    186 		addSlider(level2ParamPosition, module, PEQ6::LEVEL2_PARAM, module ? &module->_rms[1] : NULL);
    187 		addParam(createParam<Knob16>(frequency2ParamPosition, module, PEQ6::FREQUENCY2_PARAM));
    188 		addParam(createParam<Knob16>(frequencyCv2ParamPosition, module, PEQ6::FREQUENCY_CV2_PARAM));
    189 		addSlider(level3ParamPosition, module, PEQ6::LEVEL3_PARAM, module ? &module->_rms[2] : NULL);
    190 		addParam(createParam<Knob16>(frequency3ParamPosition, module, PEQ6::FREQUENCY3_PARAM));
    191 		addParam(createParam<Knob16>(frequencyCv3ParamPosition, module, PEQ6::FREQUENCY_CV3_PARAM));
    192 		addSlider(level4ParamPosition, module, PEQ6::LEVEL4_PARAM, module ? &module->_rms[3] : NULL);
    193 		addParam(createParam<Knob16>(frequency4ParamPosition, module, PEQ6::FREQUENCY4_PARAM));
    194 		addParam(createParam<Knob16>(frequencyCv4ParamPosition, module, PEQ6::FREQUENCY_CV4_PARAM));
    195 		addSlider(level5ParamPosition, module, PEQ6::LEVEL5_PARAM, module ? &module->_rms[4] : NULL);
    196 		addParam(createParam<Knob16>(frequency5ParamPosition, module, PEQ6::FREQUENCY5_PARAM));
    197 		addParam(createParam<Knob16>(frequencyCv5ParamPosition, module, PEQ6::FREQUENCY_CV5_PARAM));
    198 		addSlider(level6ParamPosition, module, PEQ6::LEVEL6_PARAM, module ? &module->_rms[5] : NULL);
    199 		addParam(createParam<Knob16>(frequency6ParamPosition, module, PEQ6::FREQUENCY6_PARAM));
    200 		addParam(createParam<Knob16>(frequencyCv6ParamPosition, module, PEQ6::FREQUENCY_CV6_PARAM));
    201 
    202 		addInput(createInput<Port24>(frequencyCvInputPosition, module, PEQ6::FREQUENCY_CV_INPUT));
    203 		addInput(createInput<Port24>(bandwidthInputPosition, module, PEQ6::BANDWIDTH_INPUT));
    204 		addInput(createInput<Port24>(inInputPosition, module, PEQ6::IN_INPUT));
    205 		addInput(createInput<Port24>(level1InputPosition, module, PEQ6::LEVEL1_INPUT));
    206 		addInput(createInput<Port24>(frequencyCv1InputPosition, module, PEQ6::FREQUENCY_CV1_INPUT));
    207 		addInput(createInput<Port24>(level2InputPosition, module, PEQ6::LEVEL2_INPUT));
    208 		addInput(createInput<Port24>(frequencyCv2InputPosition, module, PEQ6::FREQUENCY_CV2_INPUT));
    209 		addInput(createInput<Port24>(level3InputPosition, module, PEQ6::LEVEL3_INPUT));
    210 		addInput(createInput<Port24>(frequencyCv3InputPosition, module, PEQ6::FREQUENCY_CV3_INPUT));
    211 		addInput(createInput<Port24>(level4InputPosition, module, PEQ6::LEVEL4_INPUT));
    212 		addInput(createInput<Port24>(frequencyCv4InputPosition, module, PEQ6::FREQUENCY_CV4_INPUT));
    213 		addInput(createInput<Port24>(level5InputPosition, module, PEQ6::LEVEL5_INPUT));
    214 		addInput(createInput<Port24>(frequencyCv5InputPosition, module, PEQ6::FREQUENCY_CV5_INPUT));
    215 		addInput(createInput<Port24>(level6InputPosition, module, PEQ6::LEVEL6_INPUT));
    216 		addInput(createInput<Port24>(frequencyCv6InputPosition, module, PEQ6::FREQUENCY_CV6_INPUT));
    217 
    218 		addOutput(createOutput<Port24>(outOutputPosition, module, PEQ6::OUT_OUTPUT));
    219 		addOutput(createOutput<Port24>(out1OutputPosition, module, PEQ6::OUT1_OUTPUT));
    220 		addOutput(createOutput<Port24>(out2OutputPosition, module, PEQ6::OUT2_OUTPUT));
    221 		addOutput(createOutput<Port24>(out3OutputPosition, module, PEQ6::OUT3_OUTPUT));
    222 		addOutput(createOutput<Port24>(out4OutputPosition, module, PEQ6::OUT4_OUTPUT));
    223 		addOutput(createOutput<Port24>(out5OutputPosition, module, PEQ6::OUT5_OUTPUT));
    224 		addOutput(createOutput<Port24>(out6OutputPosition, module, PEQ6::OUT6_OUTPUT));
    225 
    226 		addChild(createLight<BGSmallLight<GreenLight>>(fmodFullLightPosition, module, PEQ6::FMOD_FULL_LIGHT));
    227 		addChild(createLight<BGSmallLight<GreenLight>>(fmodRelativeLightPosition, module, PEQ6::FMOD_RELATIVE_LIGHT));
    228 	}
    229 
    230 	void addSlider(Vec position, PEQ6* module, int id, float* rms) {
    231 		auto slider = createParam<VUSlider151>(position, module, id);
    232 		if (rms) {
    233 			dynamic_cast<VUSlider*>(slider)->setVULevel(rms);
    234 		}
    235 		addParam(slider);
    236 	}
    237 };
    238 
    239 Model* modelPEQ6 = createModel<PEQ6, PEQ6Widget>("Bogaudio-PEQ6", "PEQ6", "6-channel parametric equalizer / filter bank", "Filter", "Polyphonic");