Bode Plot for SFV

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

I want to make a bode plot for the SVF (in NI Reaktor)

I found the transfer functions for all SFV filter modes here:
https://www.zhdk.ch/file/live/bb/bbddbe ... tion_2.pdf
(Page 4)
but I am lacking the math :scared:

I would need an example for one of the transfer functions then I think I could figure out the rest.
For the lowpass it's given as

F^2 z / z^2 + (F^2 + DF -2)z + (1-DF)

I assume F is Frequency in radians, D Damping Faktor, but I have no clue about anything
Here is what I came up with for the lowpass case, so what are all my mistakes:
SVF TransFunc Test.jpg
You do not have the required permissions to view the files attached to this post.
thanks

Post

I just use the approximation:

unit / (i(w)/Q + pow(i(w), 2) + 1)
Low: unit = 1
High: unit = i(w)^2
Band: unit = i(w)/Q
Notch: unit = i(w)^2 + 1

Do you need to plot highly accurate frequency and phase? Why?

If so just use the transfer function you have there. It's a bit more expensive and you'll need to use a zero-finding algorithm to output peak level per segment to graph it correctly in discrete format (AKA pixels, without flicker) but it is the most accurate.

The result is a complex number including "real" and "imaginary" components. You can just think of these as "x, y" because that's all they really are. It's a sort of two dimensional vector with specific computational rules. The hardest part for newbies to grasp is no doubt understanding which input variables are complex and how to translate the unit "1" to a complex. It's usually complex(1, 0) as complex(0, 1) is written as 1i or i(1).

Complex Magnitude = sqrt(r^2 + i^2)
Complex Phase = atan2(i, r)
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

Yes it should be accurate since it's part of complex feedback.
So you should really read the exact value.
I also need the accurate phase delay at some point.

And I also want to know what's wrong with my implementation of the transfer function in general.
I assume there are several misunderstandings. So I'd need an explicit example to get the hang of it again.
I know what a complex number is though, see my implementation above.
Still, it's wrong. Probably in quite obvious ways...
thanks

Post

Well the typical issue is that it isn't obvious at all. I've found it extremely difficult to locate accurate transfer functions. When you do you find them in completely different formats in various papers sourced all over the place. It then depends upon specific implementations and making an attempt to narrow things down so your implementation matches the transfer function is nightmarish and often times as we're dealing in discrete systems technically impossible (as in perfection at least.)

Learning to translate that huge range of formulae to whatever you're working with is a very important skill. Only once you've accomplished that translation will you end up finding out various issues like that the TF is in another castle...
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

Have you considered using another tool for verification? One designed for this application (mathematics) rather than a software modular which may use extremely inaccurate approximations?

Try writing the formula in c-syntax or as an equation. Looking at the graph I can see you're computing some ^n but it isn't clear at all (n = ?) and the logic for sqrt(x/y) isn't clear to me either.
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

I did this before for biquad and other filters, so Reaktor per se is not a problem for now.
However that was years ago and I lost all the connection with these things.

And now let's assume the quoted transfer function from the paper is indeed accurate...

Then, would my implementation be accurate?
I assume not, so what mistakes did I make and what would be the solution?

That's my question.
thanks

Post

Well unfortunately I can't understand reaktor (is that?) in the least and I've found it an absolute bloody nightmare to work with while having plenty of experience with modular synthesizers (I build my own!) both hardware and software.

Try looking at the way equations are written.

For example:

w^2 = pow(w, 2)

I'm not sure about reaktors meta-modules but you could likely wrap your rotations in a more standard format, and worry about optimizing them once you have a working implementation to compare to.

"Premature optimization is the root of all evil."

The real meaning of this is important to note as it may not be obvious. A premature optimization is for example starting out wanting to implement a transfer function and jumping to hand-written assembly optimized sin() functions.

That's just plain bad design and methodology.

The proper way to do this is to use a modular approach which I hope would be intuitive in a modular synthesizer and utilize meta-modules for sections of the equation. For example computing w can happen in its own module, as can complex^n.

In the case of an optimized sin(), you'd just use the existing sin() function and worry about optimizing it or placing that inline with the other code later!

Then your implementation will start to look much more like the equation and it should become far more obvious where you've made a mistake.

Splitting up and mixing together all the individual operations might slightly optimize the result, but it makes the equation very difficult to impossible to understand by looking at the graph.
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

You can read that image just like any other flow graph, there is no difference.
cmplex mul is complex multiplication. Self explanatory.

I appreciate your time but please keep on topic now and if you don't know, simply don't answer.

The question was, what mistakes did I make in my implemention pictured above?
Or, alternatively, can s.o. post an explicit example?

Thank you.
thanks

Post

At quick glance:
* F is an abstract coefficient - not really `frequency in radians`, in the paper you can see it's approximately 2*sin(pi*fc/fs) (but only for D -> 0)
* Magnitude value is abs(H(z)) -> sqrt(real_part^2 + imaginary_part^2) - but you seems to square all things on their own (which is incorrect, i.e. (a^2 + b^2 + c^2) != (a + b + c)^2)

Post

Thank you so much.
Now it seems to work.

I'll see if I can figure out the other responses and phase delays.
Will post the results as pictures here, cause I think the flow graphs can be quite useful.
thanks

Post

That's the sqrt(x/y) I mentioned and that w should be computed separately.

That's something like:

Code: Select all

fe = PtoF(in[i])
pi2sr = 2*pi / sr
W_e = fe * pi2sr
W_c = in[fc] * pi2sr
D = Res2d(in[res])
DxF = D * W_cut
IFxD = 1 - DxF

Nc = W_c^2 * W_e^n
x = Nc.r^2 + Nc.i^2

C1 = W_c^2 + DxF - 2 * W_e^n
C2 = W_e^n * W_e^n
y = C1.r^2 + C1.i^2 + C2.r^2 + C2.i^2 + IFxD^2

out = sqrt(x / y)
Should be obvious both that:
  1. This is impossible for anyone to read because of the insane structure.
  2. The equation is nonsense.
It never occurred to me that you couldn't see that. The solution is to use proper structure and format things as in the equation so it's clear. It's partially Reaktor's fault for lacking any busing/vectors facility.
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

What is impossible to read?
Which equation is nonsense?
And what that I didn't see?

Do have answers to my question? Sorry I don't get it.
thanks

Post

You're summing a lot of squares without it being clear what the intent is of doing that. I figured it was some misguided optimization attempt.
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

Now I get it, no it was a math illiteracy. Last time I did these things was 10 years ago or so.

Also I think I still I have a fundamental misunderstanding regarding Z and Z^-1 etc.
I thought it was just the phase delay (complex) of one sample to the next, so one rotation by a frequency step, but my HP and BP plots don't work. The LP seems to work though.

Will post the flow graph tomorrow, and will try to stick to better readability.
When you are used to it such flow graphs are much better than code btw.
thanks

Post

VA wrote: When you are used to it such flow graphs are much better than code btw.
Not necessarily. I find the major difference is how I (the user) input data. Without a touch screen Reaktor is basically 99% mouse-dependent, which can be uncomfortable and slow! Typing in code can be much faster at times, if you are a good typist, but maybe the code is harder to follow visually than a flowgraph, which may reduce productivity.

I have also attempted a filter plotting UI element in Reaktor. The main difficulty is as aciddose said, the lack of true vectors/arrays, and also the lack of a dynamic pixel drawing method. I think my solution will involve evaluating the plot function with a simple incrementing input (sawtooth) into an array and outputting that to a multi-display module. I don't really understand how to use the iterator component to do it yet. But this should allow a bit of flexibility in the size of the final display.

Post Reply

Return to “DSP and Plugin Development”