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