parametric_eq.cpp (4593B)
1 2 #include "parametric_eq.hpp" 3 #include "dsp/pitch.hpp" 4 5 const float PEQChannel::maxDecibels = 6.0f; 6 const float PEQChannel::minDecibels = Amplifier::minDecibels; 7 constexpr float PEQChannel::maxFrequency; 8 constexpr float PEQChannel::minFrequency; 9 const float PEQChannel::maxFrequencySemitone = frequencyToSemitone(PEQChannel::maxFrequency); 10 const float PEQChannel::minFrequencySemitone = frequencyToSemitone(PEQChannel::minFrequency); 11 12 void PEQChannel::setSampleRate(float sampleRate) { 13 _sampleRate = sampleRate; 14 _levelSL.setParams(sampleRate, 0.05f, maxDecibels - minDecibels); 15 _frequencySL.setParams(sampleRate, 0.5f, frequencyToSemitone(maxFrequency - minFrequency)); 16 _bandwidthSL.setParams(sampleRate, 0.05f, MultimodeFilter::maxQbw - MultimodeFilter::minQbw); 17 _rms.setSampleRate(sampleRate); 18 } 19 20 void PEQChannel::setFilterMode(MultimodeFilter::Mode mode) { 21 _mode = mode; 22 _poles = _mode == MultimodeFilter::BANDPASS_MODE ? 4 : 12; 23 } 24 25 void PEQChannel::modulate() { 26 float level = clamp(_levelParam.getValue(), 0.0f, 1.0f); 27 if (_levelInput.isConnected()) { 28 level *= clamp(_levelInput.getPolyVoltage(_c) / 10.0f, 0.0f, 1.0f); 29 } 30 level *= maxDecibels - minDecibels; 31 level += minDecibels; 32 _amplifier.setLevel(_levelSL.next(level)); 33 34 float fcv = 0.0f; 35 if (_frequency1Input.isConnected()) { 36 fcv += clamp(_frequency1Input.getPolyVoltage(_c) / 5.0f, -1.0f, 1.0f); 37 } 38 if (_frequency2Input.isConnected()) { 39 float cv = clamp(_frequency2Input.getPolyVoltage(_c) / 5.0f, -1.0f, 1.0f); 40 if (_frequencyCv2Param) { 41 cv *= _frequencyCv2Param->getValue(); 42 } 43 fcv += cv; 44 } 45 fcv *= _frequencyCv1Param.getValue(); 46 if (_fullFrequencyMode) { 47 fcv *= maxFrequencySemitone - minFrequencySemitone; 48 } 49 else { 50 fcv *= 12.0f; 51 } 52 53 frequency = _frequencyParam.getValue(); 54 frequency *= frequency; 55 frequency *= maxFrequency; 56 frequency = clamp(frequency, minFrequency, maxFrequency); 57 frequency = frequencyToSemitone(frequency); 58 frequency += fcv; 59 frequency = clamp(frequency, minFrequencySemitone, maxFrequencySemitone); 60 frequency = semitoneToFrequency(_frequencySL.next(frequency)); 61 62 bandwidth = MultimodeFilter::minQbw; 63 if (_mode == MultimodeFilter::BANDPASS_MODE) { 64 bandwidth = clamp(_bandwidthParam.getValue(), 0.0f, 1.0f); 65 if (_bandwidthInput && _bandwidthInput->isConnected()) { 66 bandwidth *= clamp(_bandwidthInput->getPolyVoltage(_c) / 10.0f, 0.0f, 1.0f); 67 } 68 bandwidth = MultimodeFilter::minQbw + bandwidth * (MultimodeFilter::maxQbw - MultimodeFilter::minQbw); 69 } 70 _filter->setParams( 71 _sampleRate, 72 MultimodeFilter::BUTTERWORTH_TYPE, 73 _poles, 74 _mode, 75 frequency, 76 bandwidth, 77 MultimodeFilter::PITCH_BANDWIDTH_MODE 78 ); 79 } 80 81 void PEQChannel::next(float sample) { 82 out = _amplifier.next(_filter->next(sample)); 83 rms = _rms.next(out / 5.0f); 84 } 85 86 87 void PEQEngine::setFrequencyMode(bool full) { 88 for (int i = 0; i < _n; ++i) { 89 _channels[i]->setFrequencyMode(full); 90 } 91 } 92 93 void PEQEngine::setSampleRate(float sr) { 94 for (int i = 0; i < _n; ++i) { 95 _channels[i]->setSampleRate(sr); 96 } 97 } 98 99 void PEQEngine::modulate() { 100 for (int i = 0; i < _n; ++i) { 101 _channels[i]->modulate(); 102 } 103 } 104 105 float PEQEngine::next(float sample, float* rmsSums) { 106 bandwidth = _channels[1]->bandwidth; // take from any bandpass-only channel. 107 float out = 0.0f; 108 for (int i = 0; i < _n; ++i) { 109 PEQChannel& c = *_channels[i]; 110 c.next(sample); 111 out += outs[i] = c.out; 112 frequencies[i] = c.frequency; 113 rmsSums[i] += c.rms; 114 } 115 return _saturator.next(out); 116 } 117 118 119 float PEQXFBase::scaleEF(float ef, float frequency, float bandwidth) { 120 bandwidth = (bandwidth - MultimodeFilter::minQbw) / (MultimodeFilter::maxQbw - MultimodeFilter::minQbw); 121 bandwidth *= MultimodeFilter::maxBWPitch; 122 float minf = std::max(0.0f, powf(2.0f, -bandwidth) * frequency); 123 float maxf = std::min(PEQChannel::maxFrequency, powf(2.0f, bandwidth) * frequency); 124 float scale = (2.0f * (maxf - minf)) / PEQChannel::maxFrequency; 125 scale = 1.0f / scale; 126 scale = sqrtf(scale); // FIXME: someday prove this is correct. 127 return 2.0f * scale * ef; 128 } 129 130 131 #define BAND_EXCLUDE "band_exclude" 132 133 json_t* BandExcludeModule::saveToJson(json_t* root) { 134 json_object_set_new(root, BAND_EXCLUDE, json_boolean(_bandExclude)); 135 return root; 136 } 137 138 void BandExcludeModule::loadFromJson(json_t* root) { 139 json_t* be = json_object_get(root, BAND_EXCLUDE); 140 if (be) { 141 _bandExclude = json_is_true(be); 142 } 143 } 144 145 146 void BandExcludeModuleWidget::contextMenu(Menu* menu) { 147 auto m = dynamic_cast<BandExcludeModule*>(module); 148 assert(m); 149 menu->addChild(new BoolOptionMenuItem("Exclude direct-output bands from mix", [m]() { return &m->_bandExclude; })); 150 }