Creating a resonator in Gen
(Having some issues with my last post, the option to edit was removed for some reason, so my apologies)
I want to recreate a resonator using some specifications from a text (on vocal synthesis), but I am having a hard time converting the mathematical model to something that makes sense within Gen~. I understand that for a filter, I will want a sample delay, and based on transformations on the signal before it is added back to the original, I can build a resonator. I'm new to following older texts though, including the formulas and block diagrams they use to describe the methods.
In the text, it states that the output of the resonator ( y(nT) ) is computed from the input ( x(nT) ) using the equation:
y(nT) = Ax(nT)+By(nT-T)+Cy(nT-2T)
The resonant frequency is represented by F, bandwidth as BW, and T is 1/samplerate. The constants, A, B, and C are the following:
C = -exp(-2PI BW T)
B = 2exp(-PI BW T)cos(2PI F T)
A = 1 - B - C
And further, specifications (which are related) are given for an antiresonator. I feel like if I can understand the application of the first equation, I should be able to apply what I learned to the second, but I don't know how to start otherwise. Is there anyone that could give me some advice on building a gen patch from this? Any advice would appreciated. If anyone is interested, the text is here: http://www.fon.hum.uva.nl/david/ma_ssp/doc/Klatt-1980-JAS000971.pdf (and the resonator specs are on pp. 974-975.
Thanks
Digging through the examples I found this, which at least is similar to the reson~ object, which hopefully by dissecting, I'll be able to find out more about calculating the coefficients and the differences (if there are any) between reson~ and the filter described in the text.
Hopefully this actually does match the specifications now, it does appear to be behaving very similarly to reson~.
Hi,
Sometimes I find it easier to see it in patcher form first, especially for filter diagrams. The patcher below has both patcher-form and codebox-form. The codebox version is wrapped in a function to make it easier to run resonators in parallel or series (though you could also do that in a patcher form using sub-gen-patchers).
Graham
Great example for me to compare the codebox vs patcher, thanks Graham!
GRAHAM WAKEFIELD, if wanted to recode your example as a resonator bank which takes a 64 long list of values for frequencies, how would i do that?
this is what i've got so far
A couple of things -- you've coded this as a set of resonators in series, whereas resonator banks are usually arranged in parallel. You probably also want independent amplitudes per resonator (and maybe also independent bandwidth). Also I think this could be better expressed using a for loop, which means changing from using History objects to using Data objects, where each resonator utilized a different index of a Data.
Here's something along those lines. It could be made more efficient if you know the resonator freq/amp values do not often change, but otherwise this is very flexible, since you could have other audio processes generating these values:
Graham
Thanks Graham!!
// this could be better optimized
// to calculate coefficients less frequently
// if it is known that they cannot change at any time
This?
`
Yes along those lines. The amp curves could also be cached in a similar way.
Maybe changes to bandwidth should also retrigger coefficient calculation.
Thanks! Is there some kind of delay on this? I will be using it for a kind of tuning resonator not for physical modeling, so the frequencies and amplitudes will be fixed.