more correct SVF

master
zetaPRIME 2022-03-16 23:04:06 -04:00
parent d360074e81
commit b8f9664f7c
4 changed files with 21 additions and 9 deletions

16
notes
View File

@ -32,14 +32,24 @@ parameters {
TODO {
immediate frontburner {
- fix focus issues after loading a project with patchboard focused
- wet-only output for delay (be smart about it)
revert action
distortion effect
}
shift+drag fine tuning for KnobGadget
automation node {
listens for one specific param
supports tweening
value bounds, scaling exponent
how to UI?
I guess some sort of text box/spinner to enter bounds
dial for exponent
focusable control to set param
}
qt update causing some patchboard artifacting on mouse movement
look into performance/timing/sync of audio engine; it's having buffer issues way more than it feels like it should

View File

@ -9,11 +9,10 @@ using namespace Xybrid::Audio;
void SVFilter::process(AudioFrame in, double freq, double res, int ovs) {
if (ovs <= 0) return;
res = std::max(res, 0.01);
//double f = freq / (audioEngine->curSampleRate() * ovs);
double f = 2.0 * std::sin(freq / (audioEngine->curSampleRate() * ovs));
//double f = 2.0 * std::sin(PI * std::min(0.25, freq / (audioEngine->curSampleRate() * ovs)));
double q = std::sqrt(1.0 - std::atan(sqrt(res)) * 2.0 / PI);
double f = 2.0 * std::sin(PI * freq / (audioEngine->curSampleRate() * ovs));
double q = std::sqrt(1.0 - std::atan(std::sqrt(res)) * 2.0 / PI);
double damp = std::sqrt(q);
for (int i = 0; i < ovs; i++) {

View File

@ -8,6 +8,9 @@ namespace Xybrid::NodeLib {
class SVFilter {
//
public:
/// Default oversampling level. Enough to mostly eliminate artifacting at high cutoff.
static const constexpr int DEFAULT_OVERSAMP = 3;
Data::AudioFrame low = 0.0;
Data::AudioFrame high = 0.0;
Data::AudioFrame band = 0.0;
@ -19,7 +22,7 @@ namespace Xybrid::NodeLib {
inline SVFilter(const SVFilter& o) { std::memcpy(static_cast<void*>(this), static_cast<const void*>(&o), sizeof(SVFilter)); }
inline SVFilter& operator=(const SVFilter& o) { std::memcpy(static_cast<void*>(this), static_cast<const void*>(&o), sizeof(SVFilter)); return *this; }
void process(Data::AudioFrame in, double freq, double res, int oversamp = 2);
void process(Data::AudioFrame in, double freq, double res, int oversamp = DEFAULT_OVERSAMP);
inline void reset() { low = 0.0; high = 0.0; band = 0.0; notch = 0.0; }
};
}

View File

@ -132,7 +132,7 @@ void SVF::onGadgetCreated() {
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(frequency)->setLabel(qs("Freq"))->setRange(0.0, 16000.0, 50.0, KnobGadget::NoStep)->setDefault(6400.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);
}