Book: The Art of VA Filter Design 2.1.2

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Robin from www.rs-met.com wrote: i think, now i'll finally get my hands dirty with implementing the TPT/ZDF-SVF (which is also the first time, that i implement an SVF at all - as strange as that may sound)
done. and - lo and behold - it worked on first go. well, at least, plotting the impulse responses looked reasonable and LP+2*R*BP+HP reconstruct the original signal, as it should be. here it is:

Code: Select all

// Example code for a TPT/ZDF-SVF (obviously, this could be optimized for production code)
// written by Robin Schmidt, licensing/copyright: none (public domain)
// Parameters:
// fc: cutoff frequency
// fs: sample-rate
// R:  damping coefficient
// N:  number of samples
// x:  input signal
// yL: lowpass output
// yB: bandpass output
// yH: highpass output
void svf(double fc, double fs, double R, int N, double x[], double yL[], double yB[], double yH[])
{
  double wd = 2*PI*fc;           // target radian frequency
  double T  = 1/fs;              // sampling period
  double wa = (2/T)*tan(wd*T/2); // prewarped radian frequency for analog filter (Eq. 3.7)
  double g  = wa*T/2;            // embedded integrator gain (Fig 3.11), wc == wa

  // states of the 2 integrators, static so we can call the function block-wise while maintaining 
  // the states from block to block:
  static double s1 = 0.0;
  static double s2 = 0.0;

  // loop over the samples:
  for(int n = 0; n < N; n++)
  {
    // compute highpass output via Eq. 5.1:
    yH[n] = (x[n] - 2*R*s1 - g*s1 - s2) / (1 + 2*R*g + g*g);

    // compute bandpass output by applying 1st integrator to highpass output:
    yB[n] = g*yH[n] + s1;
    s1    = g*yH[n] + yB[n]; // state update in 1st integrator

    // compute lowpass output by applying 2nd integrator to bandpass output:
    yL[n] = g*yB[n] + s2;
    s2    = g*yB[n] + yL[n]; // state update in 2nd integrator

    // Remark: we have used two TDF2 integrators (Fig. 3.11) where one of them would be in code:
    // y = g*x + s; // output computation
    // s = g*x + y; // state update
  }
}
[/size]
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Just skimmed it so far, and it looks like amazing work, Vadim! I really look forward to reading it through and hopefully fill in some gaps in my knowledge! :)
kiloHearts Developer

Post

Robin from www.rs-met.com wrote:
Robin from www.rs-met.com wrote: i think, now i'll finally get my hands dirty with implementing the TPT/ZDF-SVF (which is also the first time, that i implement an SVF at all - as strange as that may sound)
done. and - lo and behold - it worked on first go. well, at least, plotting the impulse responses looked reasonable and LP+2*R*BP+HP reconstruct the original signal, as it should be. here it is:
Looks reasonable. I actually posted another earlier, but it's pretty much similar (I use different state-update but that's not really important):

http://www.kvraudio.com/forum/viewtopic ... 51#4913251

Post

mystran wrote: Looks reasonable. I actually posted another earlier, but it's pretty much similar (I use different state-update but that's not really important):

http://www.kvraudio.com/forum/viewtopic ... 51#4913251
yes, looks similar, although i didn't check in detail. but the filter makes me wonder a bit: we obtain the lowpass from the output of the bandpass by integration - but the bandpass signal should already have DC removed completely, no? so, how can the integrator reconstruct a DC component that has already been filtered out completely?
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Robin from www.rs-met.com wrote:but the filter makes me wonder a bit: we obtain the lowpass from the output of the bandpass by integration - but the bandpass signal should already have DC removed completely, no? so, how can the integrator reconstruct a DC component that has already been filtered out completely?
Well, the integrator has an infinite gain at DC :) But intuitively, you're right, that's still kind of weird :)

Post

Z1202 wrote:
Robin from www.rs-met.com wrote:but the filter makes me wonder a bit: we obtain the lowpass from the output of the bandpass by integration - but the bandpass signal should already have DC removed completely, no? so, how can the integrator reconstruct a DC component that has already been filtered out completely?
Well, the integrator has an infinite gain at DC :) But intuitively, you're right, that's still kind of weird :)
good to know, that i'm in good company to think so.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Robin from www.rs-met.com wrote:
Z1202 wrote:
Robin from www.rs-met.com wrote:but the filter makes me wonder a bit: we obtain the lowpass from the output of the bandpass by integration - but the bandpass signal should already have DC removed completely, no? so, how can the integrator reconstruct a DC component that has already been filtered out completely?
Well, the integrator has an infinite gain at DC :) But intuitively, you're right, that's still kind of weird :)
good to know, that i'm in good company to think so.
I would further assume, that should you simply connect an integrator to the bandpass output, the resulting lowpass signal might "drift" around DC, whereas inside the filter the feedback will probably take care of the precision losses.

Post

Z1202 wrote:I would further assume, that should you simply connect an integrator to the bandpass output, the resulting lowpass signal might "drift" around DC, whereas inside the filter the feedback will probably take care of the precision losses.
hopefully. but yes, i agree - i would expect something like that, too.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

you're just integrating the differentiated value.

how is it so hard to believe this:

s - s[i-1] + s[i-1] = s ?

differentiation:
d = s - a;
a = s;

integration:
b += d;

b == s;

the problem of drift due to error is solved by the feedback, which can never be absolutely zero.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

Robin from www.rs-met.com wrote:
Z1202 wrote:I would further assume, that should you simply connect an integrator to the bandpass output, the resulting lowpass signal might "drift" around DC, whereas inside the filter the feedback will probably take care of the precision losses.
hopefully. but yes, i agree - i would expect something like that, too.
Well, suppose you have a DC input x=const, and BP=0 and LP!=x, then you immediately get the signal x-LP at the input of the first integrator. There you go :)

Post

aciddose wrote:you're just integrating the differentiated value.

how is it so hard to believe this:

s - s[i-1] + s[i-1] = s ?

differentiation:
d = s - a;
a = s;

integration:
b += d;

b == s;


hmm...well, yes. sometimes, it helps to switch the perspective. from a (discrete) time-domain perspective, it's certainly much easier to believe (although we are actually not really using the naive integrator here)
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Z1202 wrote:Well, suppose you have a DC input x=const, and BP=0 and LP!=x, then you immediately get the signal x-LP at the input of the first integrator. There you go :)


:tu: yeah - so, as we see, the feedback is indeed crucial for this DC reconstruction. i guess, i'm already way too spoiled with this strictly sequential thinking in DSP.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Something to note: since the finite DC gain relies on the differentials having zeroes at DC (which the integrators then cancel), if the differentials go through a non-linearity (eg practical OTA) you will typically get some DC drift at output. This is dependent on the cutoff (increases as cutoff gets lower).

If you observe that happening, don't panic. It's something that happens with with an analog implementation as well (or even SPICE). In a properly gain-staged filter it shouldn't become a problem at audio rates (ie back off the saturation), but you might want to stick a DC blocker at the output.

Post

I'm wondering why google still doesn't find the original link, while it finds the discodsp mirror. Does this have to do with the way I posted the URL? Attempt no.2:
http://ay-kedi.narod2.ru/VAFilterDesign.pdf

Post

We paid Google :hihi:

Post Reply

Return to “DSP and Plugin Development”