@porres I tried the paf~ that solipp linked to, and it seems to be exactly what I'm looking for. How would I get the Windows version of vosim~ from github?
-
Objects for formant synthesis?
-
yeah, I'm working on a version of that too to incorporate in ELSE. I tried for years to include that into Pd Vanilla and will give it another shot for 0.57, but it's likely I'll redesign and include it in ELSE

For vosim~ just get any recent github actions artifacts from https://github.com/porres/pd-else/actions but you have to be logged in
I now added a version of SuperCollider's Formlet Ugen, but I'm not sure how to use that in this context
-
@porres Thank you!
-
So, how about we discuss all these options and how they relate to each other? Anyone with me?
Let me talk about FOF here... Basically, it's a hard-synced oscillator! And I always thought hard synced oscillators sounded really nice for forcing harmonics into a fundamental pitch, and that's it... Ok, there's more to that of course, and it also passes through a decay envelope, which can be implemented with [rpole~], here's a minimal Pd patch of this main core.... it uses objects from ELSE of course... specially for making hard sync easier. Below, 150 is 'f0' (fundamental), 390 is center/formant frequency, and 100 is bandwidth, all in Hertz...

But then, the envelope grain might and can overlap. The Csound implementation is pretty much "Csoundy", ridiculously complicated with way too many parameters and options, not to mention a seemingly inexplicable low output that forces you to multiply it by a ridiculously large and arbitrary number. Besides the decay envelope, it also applies another envelope on top of it, which might be pretty useless when the first envelope simply dies before it, but it can be useful to apply an attack phase. What a mess! The FAUST implementation is simpler and makes more sense!
The Formlet UGen from supercollider implements a filter with attack and decay, and it rings, so you don't need the hard synced oscillator. Plus, it can "overlap" grains quite seeminglessly. It's pretty clever and it made its way back into Csound, where it's called fofilter.
What makes no sense for me is the "BandWidth" parameter in FOF (or using Formlet). In Pd's examples we have the paf like patches and the bandwidth makes actual sense because it represents a bandwidth of partials over the center frequency. In FOF we don't have that
and the larger the bandwidth, the thinner the sound actually is because the decay is faster.Now, i also ported the Formant UGen and this is what it is, basically, as a patch, guess what? Yup, another hard synced oscillator, basically, being enveloped, so... I guess it relates to the Fof approach... but not quite... one way or another, there's no reference in the docs or code of where it comes from and maybe I should ask the SC Forum (again)
Below, BW ratio means the ratio of bandwidth according to the fundamental, so '3' is '150' hz. This parameter to me feels like controlling the "brightness" anyhow.
And there are also the FM approach, the paf, the VOSIM, not to mention the filterbank approach... Gosh, what a mess... I guess I know why I procrastinated so much to finally deal with this... but it's time and now I'll map them all and see how they relate to each other. And I'll sort it all out in my Live Electronics Tutorial...
I'm still thinking what are the objects that make sense actually including in ELSE...
-
@porres I tried both of the example patches you posted. The first one produces significant levels of harmonics well past the Nyquist frequency which gives it a harsh sound. I think it needs a low pass filter. Also, the bandwidth parameter seems to act more like a volume control than what I expect bandwidth to do. It doesn't seem to alter the shape of the formant. It just raises and lowers the volume of all of the harmonics.
The second one produces the spectrogram I expect from FOF. The high harmonics die out to zero after the formant peak. Also, the bandwidth parameter actually alters the shape of the formant, which is what it should do.
I can't see myself using the first one, but I'll do some comparisons between the second one and paf~. I like paf~ so far. Since the patent on paf has expired, there's no reason not to use it.
-
@jamcultur said:
Also, the bandwidth parameter seems to act more like a volume control than what I expect bandwidth to do.
I talked about that
and how the bw parameter in FOF makes no good sense.About frequencies over nyquist, maybe if you're hard syncing before the decay envelope is over, cause hard syncing does have aliasing issues indeed.
I can't see myself using the first one
To be clear again, that is not any real implementation of anything. It's just "the core", the main element of the technique...
And I'm not sure I'm gonna add a 'fof~' right now, I also like the other options better, like [paf~], and my idea is to work on a modification of Miller's external that has multichannel support. I guess I'll ship "formlet", which is clever.
By the way, I asked about the Formant UGen in SC's forum, which is the second one, and got no answer yet on what is the reference/source for it.
-
@porres It looks like the Formant UGen example might be an implementation of FOF, based on the formants it produces. Also, the bandwidth parameter in the Formant UGen alters the formant the way that it should in FOF. Specifying bandwidth as a ratio is a little strange, but it has the right result. I'd prefer to specify the bandwidth in hertz. I don't know what the first example is, but it is not a correct implementation of FOF.
-
@porres I just found this paper that says "SuperCollider has a uGen formlet [14] dating back to 2002 which forms a FOF-type wave burst using the difference between two second-order resonant bandpass filters having different decay rates but the same center frequency." So formlet isn't exactly FOF, but it gives similar results.
-
@jamcultur said:
I'd prefer to specify the bandwidth in hertz.
just divide the bw freq by the fundamental (and keep [max~ 1])
-
@jamcultur said:
I just found this paper that says "SuperCollider has a uGen formlet [14] dating back to 2002 which forms a FOF-type wave burst
I've mentioend it and I've implemented it like I said
check my comments carefully please 
-
@jamcultur said:
I don't know what the first example is, but it is not a correct implementation of FOF.
I didn't say it's FOF, but I said many times it's the basis of it, the starting point, the core... and if you check the CSound and FAUST code you'll see what I mean.
It looks like the Formant UGen example might be an implementation of FOF, based on the formants it produces.
It might be what you wish FOF would do, but it's not FOF, it's not implementing FOF, it's not the same algorithm as the CSound and FAUST code. Like I said, it's something related but I don't know about its actual source/reference.
-
just added a very much simplified version of Miller's paf~ external code, with the ability of setting parameters as arguments and the main parameters as signal inputs! I will now expand it and add MC support. There's no vibrato but I think that is trivial to implement as a patch!
see:
https://github.com/porres/pd-else/commit/fddcc9597cf17c977abb14d5409cffd329b6abf5
get it at
https://github.com/porres/pd-else/actions/runs/20529081595 -
@porres I got this when I tried to use paf~

-
have you updated and used all binaries from the download?
-
@porres I copied everything and I'm not getting that message anymore, but else/paf~ does not give the same results as Miller Puckette's paf~. The first image shows spectrograms from both versions of paf~ with the first six harmonics of the fundamental frequency=264, the formant center frequency=650, and the bandwidth=80. Miller Puckette's paf~ is at the top, and else/paf~ is at the bottom. The second and third harmonics are about the same in both, but the other harmonics are significantly higher in else/paf~.

The second image is the same except with bandwidth=10 in both versions of paf~. Changing the bandwidth to 10 made a big difference in Miller Puckette's paf~. All but the second and third harmonics were eliminated. Changing bandwidth to 10 in else/paf~ made almost no difference in the spectrogram or in the sound.

The third image shows both version of paf~ with bandwidth=500. The results were much closer, but not identical. The highest peak in Miller Puckette's paf~ was at 528 hz, while the highest peak in else/paf~ was at 793 hz.

-
@jamcultur said:
The second and third harmonics are about the same in both, but the other harmonics are significantly higher in else/paf~.
nice and thanks for deeply testing this.
One thing I can think of is that I am using 'sines' and not 'cosines'. The thing is that you can change the phase offset in both mine and miller's, so I didn't bother. Maybe I should default to cosine? I thought about that, but this is still in the oven, so... I can think some more and maybe revert it to cosine!
Can you see if changing that aligns things better?
cheers
-
we're back to cosines in https://github.com/porres/pd-else/actions/runs/20608031480
-
@porres The cosine version looks the same as before with fundamental=264, formant=650, bandwidth=10. The top spectrogram is Miller Puckette's paf~, bottom is else/paf~

I just noticed one small difference; the cosine version has a small peak below 40hz that the previous version didn't have. -
can you upload your patch?
-
What I can tell you is that there's no audible difference for me over here. I have all literally dozens iterations of code changes/overhaul from Miller's original code. Testing the original and my latest version basically sounds the same. But I haven't put it into the test like you with a deep spectral analysis