rework svf effect using nodelib object
parent
2d077d90c0
commit
18557d933b
|
@ -56,17 +56,12 @@ namespace {
|
|||
SVF::SVF() { }
|
||||
|
||||
void SVF::init() {
|
||||
auto sr = audioEngine->curSampleRate();
|
||||
this->max_freq = ((float)sr / 4.0);
|
||||
this->frequency = 12000;
|
||||
this->resonance = 65;
|
||||
addPort(Port::Input, Port::Audio, 0);
|
||||
addPort(Port::Output, Port::Audio, 0);
|
||||
}
|
||||
|
||||
void SVF::reset() {
|
||||
release();
|
||||
auto sr = audioEngine->curSampleRate();
|
||||
filter.reset();
|
||||
}
|
||||
|
||||
void SVF::release() {
|
||||
|
@ -74,107 +69,70 @@ void SVF::release() {
|
|||
}
|
||||
|
||||
void SVF::process() {
|
||||
|
||||
|
||||
|
||||
auto in = std::static_pointer_cast<AudioPort>(port(Port::Input, Port::Audio, 0));
|
||||
auto out = std::static_pointer_cast<AudioPort>(port(Port::Output, Port::Audio, 0));
|
||||
in->pull();
|
||||
out->pull();
|
||||
if (this->fm != _off)
|
||||
if (this->frequency > 0) { this->frequency-=0.1; }
|
||||
|
||||
size_t ts = audioEngine->curTickSize();
|
||||
for (size_t f = 0; f < ts; f++) {
|
||||
AudioFrame fCurrent = (*in)[f];
|
||||
AudioFrame fOut;
|
||||
if (this->fm == _off) {
|
||||
(*out)[f] = fCurrent;
|
||||
continue;
|
||||
}
|
||||
AudioFrame inp = (*in)[f];
|
||||
|
||||
double res = this->resonance;
|
||||
//double damp = MIN(2.0*(1.0 - pow(res, 0.25)), MIN(2.0, 2.0/freq - freq*0.5));
|
||||
double q = sqrt(1.0 - atan(sqrt(res)) * 2.0 / PI);
|
||||
double damp = sqrt(q);
|
||||
filter.process(inp, frequency, resonance);
|
||||
|
||||
//double freq = 2.0*sin(M_PI * MIN(0.25, this->frequency/audioEngine->curSampleRate()));
|
||||
double freq = this->frequency / (audioEngine->curSampleRate() * 2 );
|
||||
double in_l, in_r;
|
||||
double low_l, low_r;
|
||||
double band_l, band_r;
|
||||
double high_l, high_r;
|
||||
double notch_l, notch_r;
|
||||
|
||||
in_l = fCurrent.l;
|
||||
in_r = fCurrent.r;
|
||||
low_l=low.l;
|
||||
low_r=low.r;
|
||||
band_l=band.l;
|
||||
band_r=band.r;
|
||||
high_l=high.l;
|
||||
high_r=high.r;
|
||||
notch_l=notch.l;
|
||||
notch_r=notch.r;
|
||||
|
||||
|
||||
low_l = low_l + freq * band_l;
|
||||
high_l = damp * in_l - low_l - q * band_l;
|
||||
band_l = freq * high_l + band_l;
|
||||
notch_l = high_l + low_l;
|
||||
low_r = low_r + freq * band_r;
|
||||
high_r = damp * in_r - low_r - q * band_r;
|
||||
band_r = freq * high_r + band_r;
|
||||
notch_r = high_r + low_r;
|
||||
low_l = low_l + freq * band_l;
|
||||
high_l = damp * in_l - low_l - q * band_l;
|
||||
band_l = freq * high_l + band_l;
|
||||
notch_l = high_l + low_l;
|
||||
low_r = low_r + freq * band_r;
|
||||
high_r = damp * in_r - low_r - q * band_r;
|
||||
band_r = freq * high_r + band_r;
|
||||
notch_r = high_r + low_r;
|
||||
|
||||
low = {low_l, low_r};
|
||||
band = {band_l, band_r};
|
||||
high = {high_l, high_r};
|
||||
notch = {notch_l, notch_r};
|
||||
|
||||
|
||||
switch (fm) {
|
||||
case _low:
|
||||
(*out)[f] = this->low;
|
||||
switch (mode) {
|
||||
case Low:
|
||||
(*out)[f] = filter.low;
|
||||
break;
|
||||
case _band:
|
||||
(*out)[f] = this->band;
|
||||
case High:
|
||||
(*out)[f] = filter.high;
|
||||
break;
|
||||
case _high:
|
||||
(*out)[f] = this->high;
|
||||
case Band:
|
||||
(*out)[f] = filter.band;
|
||||
break;
|
||||
case _notch:
|
||||
(*out)[f] = this->notch;
|
||||
case Notch:
|
||||
(*out)[f] = filter.notch;
|
||||
break;
|
||||
default:
|
||||
(*out)[f] = inp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SVF::saveData(QCborMap& m) const {
|
||||
//m[qs("frequency")] = QCborValue(frequency);
|
||||
//m[qs("resonance")] = QCborValue(resonance);
|
||||
m[qs("frequency")] = QCborValue(frequency);
|
||||
m[qs("resonance")] = QCborValue(resonance);
|
||||
m[qs("mode")] = QCborValue(mode);
|
||||
}
|
||||
|
||||
void SVF::loadData(const QCborMap& m) {
|
||||
//frequency = m.value("frequency").toDouble(frequency);
|
||||
//resonance = m.value("resonance").toDouble(resonance);
|
||||
frequency = m.value("frequency").toDouble(frequency);
|
||||
resonance = m.value("resonance").toDouble(resonance);
|
||||
mode = static_cast<FilterMode>(m.value("mode").toInteger(mode));
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::unordered_map<SVF::FilterMode, QString> modeNames = [] {
|
||||
std::unordered_map<SVF::FilterMode, QString> m;
|
||||
m[SVF::Off] = "off";
|
||||
m[SVF::Low] = "low";
|
||||
m[SVF::High] = "high";
|
||||
m[SVF::Band] = "band";
|
||||
m[SVF::Notch] = "notch";
|
||||
return m;
|
||||
}();
|
||||
}
|
||||
|
||||
void SVF::onGadgetCreated() {
|
||||
if (!obj) return;
|
||||
auto l = new LayoutGadget(obj);
|
||||
|
||||
//(new KnobGadget(l))->bind(freq)->setLabel(qs("Frequency Step"))->setRange(0.0, 10, 0.5)->setDefault(1.0);
|
||||
(new KnobGadget(l))->bind(frequency)->setLabel(qs("Frequency"))->setRange(0.0, this->max_freq, 10.0)->setDefault(6440.0);
|
||||
l->addSpacer();
|
||||
(new KnobGadget(l))->bind(resonance)->setLabel(qs("Resonance"))->setRange(0.0, 100.0, 0.1)->setDefault(0.0);
|
||||
l->addSpacer();
|
||||
(new KnobGadget(l))->bind(fm)->setLabel(qs("Filter Mode"))->setRange(0,4,1)->setDefault(0);
|
||||
auto modetxt = [](double inp) {
|
||||
if (auto f = modeNames.find(static_cast<FilterMode>(inp)); f != modeNames.end()) return f->second;
|
||||
return qs("?");
|
||||
};
|
||||
|
||||
(new KnobGadget(l))->bind(frequency)->setLabel(qs("Freq"))->setRange(0.0, 25000.0, 10.0, KnobGadget::NoStep)->setDefault(6440.0);
|
||||
(new KnobGadget(l))->bind(resonance)->setLabel(qs("Res"))->setRange(0.0, 100.0, 1.0)->setDefault(0.0);
|
||||
(new KnobGadget(l))->bind(mode)->setLabel(qs("Mode"))->setTextFunc(modetxt)->setRange(0, Notch, 1, KnobGadget::BigStep)->setDefault(0);
|
||||
}
|
||||
|
|
|
@ -14,29 +14,22 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <QContiguousCache>
|
||||
|
||||
#include "data/node.h"
|
||||
#include "data/audioframe.h"
|
||||
|
||||
#include "nodelib/svfilter.h"
|
||||
|
||||
namespace Xybrid::Effects {
|
||||
class SVF : public Data::Node {
|
||||
enum FilterMode {_off, _low, _band, _high, _notch };
|
||||
double frequency= 0.5;
|
||||
NodeLib::SVFilter filter;
|
||||
|
||||
double frequency = 6440.0;
|
||||
double resonance = 0.0;
|
||||
|
||||
Xybrid::Data::AudioFrame low = 0.0;
|
||||
Xybrid::Data::AudioFrame band = 0.0;
|
||||
Xybrid::Data::AudioFrame high = 0.0;
|
||||
Xybrid::Data::AudioFrame notch = 0.0;
|
||||
FilterMode fm = _off;
|
||||
|
||||
// solve these in cons.
|
||||
double max_freq;
|
||||
double freq;
|
||||
double q;
|
||||
|
||||
public:
|
||||
enum FilterMode : uchar { Off, Low, High, Band, Notch };
|
||||
FilterMode mode = Low;
|
||||
|
||||
SVF();
|
||||
~SVF() override = default;
|
||||
|
||||
|
|
|
@ -207,10 +207,10 @@ void I2x03::onGadgetCreated() {
|
|||
|
||||
auto wavetxt = [](double inp) {
|
||||
if (auto f = waveNames.find(static_cast<int8_t>(inp)); f != waveNames.end()) return f->second;
|
||||
return QString("?");
|
||||
return qs("?");
|
||||
};
|
||||
auto percenttxt = [](double d) {
|
||||
return QString("%1%").arg(d*100, 0);
|
||||
return qs("%1%").arg(d*100, 0);
|
||||
};
|
||||
|
||||
auto ol = new LayoutGadget(obj, true);
|
||||
|
|
Loading…
Reference in New Issue