more correct SVF
parent
d360074e81
commit
b8f9664f7c
16
notes
16
notes
|
@ -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
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue