Closed mxmilkiib closed 4 years ago
I would like that too, but it's not so simple. The plugins just use the units and value ranges of the FAUST standard library functions they wrap. All the filter functions wrapped so far accept the cutoff frequency as a normalized value 0.0 .. +1.0, corresponding to a frequency value of 20 .. 20_000. But they have an exponential curve built into the conversion formula:
freq = 2*(10^(3*normFreq+1))
Additionally the normalized value is used in the filter calculation as well. Neither my FAUST nor my algebra knowledge is strong enough, currently, to adapt the functions to accept the cutoff as a real frequency.
So, patches welcome, I guess. I'll also try to find help on the FAUST mailing list or from the original author of the filter functions.
It's quite simple, we did this for sfizz when I copied in the sallen-key model. It was not possible to work with the standard library versions so it's an edit.
I've kept a change list https://github.com/sfztools/sfizz/blob/443e89c45d6b5a9c7e9f8b03a24d22c8e9a332ee/src/sfizz/dsp/filters/sallenkey_modulable.dsp#L1-L7
As the cutoff is concerned, you just plug the direct frequency (Hz) into the formula for wd
This should be the same for Moog and others.
https://github.com/sfztools/sfizz/blob/443e89c45d6b5a9c7e9f8b03a24d22c8e9a332ee/src/sfizz/dsp/filters/sallenkey_modulable.dsp#L76
I suppose, the exp formula imitates the range of analog knob, so it may still be useful to keep this. Like in fons's plugins, perhaps you can let yours have optional ports to permit for both linear and exponential modulations.
I have a branch where I copied the moogLadder
function from the FAUST lib into the project and changed it to take the cutoff as Hertz:
https://github.com/SpotlightKid/faustfilters/blob/feature/cutoff-as-hz/faust/moogladder.dsp#L47
But the resulting plugin is not working correctly in Ardour. It works at first, but if I reload the project, the plugin only outputs a high DC value (I think, I'm not sure how to interpret the plugin analyser graph).
I'm currently trying to get to the bottom of this, but fighting with getting different LV2 tools to work (and failing mostly), e.g. plugin-torture and your lv2-plugin-checker
(they both do not support the option feature, which DPF plugins need). lv2bm
runs, but I'm not sure what it actually does.
Oh right I see your problem here. Indeed Moog LPF implementations have F and Q controls coupled, there is need to do something about that. I'm going to check this.
When you set Hz frequency at 0 or very low near 0, term k
will go negative.
Do you protect against this?
The hslider definition has a min value of 20 and I also clamp the value in the plugin:
When I test my formula (in Python), the results go from fn(20.0) = 0.0
to fn(20000) = 1.0
.
I don't see issue with this dsp file, or formula, this works fine in faustlive. The Q correction formula is not very elegant though, there must be surely a good approximation to make out of this.
It may be an issue with my Ardour binary, then. The plugin with the Hz cutoff param works fine in Carla and in jalv too. I'll test with the official Ardour 6,2 demo version again.
This moogLadder filter implementation does not react in the best way, anyway. There is a huge amplitude drop when increasing the Q from the minimum (0.707) until 1.0 (that's what you graph shows, right?). And also when the cutoff is near 20.000. But it sounds very good, although the max Q still seems a bit tame (comparing it to my Behringer Model D).
The plot is the depth by how much Q should drop with regards to frequency.
It's the term (normFreq^0.2)*0.9
but X-axis displays the real frequency.
The references in faust comments link to Will Pirkle's articles on filters. There is not a documentation there about the correction which is used. To be frank, I don't remember to have found much infos on this correction in papers of this subject. It's possible that this adjustment is totally determined by experimentation.
The formula used here
k = (3.9 - (normFreq^0.2)*0.9)*(Q - 0.707)/(25.0 - 0.707);
It's observed that term (Q - 0.707)/(25.0 - 0.707)
is "something Q related", just a center-and-reduce.
Term (normFreq^0.2)*0.9
is max at full cutoff, which makes depth range down from 3.9 to 3.0 over frequency.
It you'd like to make some adjustments on this, probably it's the best idea to load this code in faustlive and experiment change of these values.
Now I can't reproduce the problem I was having in Ardour anymore, neither in the official demo version nor with the one from the Arch package. :-( Although I tested this dozens of times the day before yesterday and was always able to reproduce it.
Aaanyway, I guess I'll copy and modify all the filter functions these plugins use from the FAUST library, like I did for the moogLadder filter.
I won't change anything else about the filter behaviour in this project, though (apart from fixes like for the diodeLadder filter). This would be out of scope. The purpose of this plugin package is to make existing filter implementations available via DPF, not to develop new ones, and to be a template for wrapping any simple audio effect implemented in FAUST with DPF.
I have now updated all the filters to take the cutoff parameter as Hertz.
@mxmilkiib Care to test the new versions (you need to git checkout feature/cutoff-as-hz
and recompile/reinstall)?
...
faustpp -DIdentifier=Korg35HPF -a ../../faust/arch/generic.hpp ../../faust/korg35hpf.dsp > Korg35HPF.hpp
/bin/sh: faustpp: command not found
...
Oh, maybe git rebase
messed up the modification time of files, so make wants to re-generate the C++ files from the FAUST DSP sources, even though those generated files are already present?
Try touch plugins/*/*.{c,h}pp
and run make
again.
Or maybe my makefile rules are wrong.
Recloned, switched, touched, worked, working! Sorted, thanks :)
Edit: adding a link to https://github.com/grame-cncm/faust/issues/435 as this relates directly to metadata.
Just released version 0.3.0 with these changes.
Actually I liked the initial idea of directly using the standard library implementation. Maybe it would be a good idea to request adding versions of those filters with non-normalized freq parameters to the Faust standard library?
Alternatively, one could transfer the input with an inverse of the normalization function and let Faust's term rewriting system do the rest (currently, it doesn't simplify things like exp(lg(x))
but IMO it should do in the future ;)).
@cbix: I'm planning to publish a cookiecutter template, with which you can create your own FAUST-DPF plugin projects easily. The DPF-specific code is basically the same for all plugins anyway (except class names and preset definitions). That would make it easy to wrap any FAUST stdlib function with just one audio input and output yourself. I could also make a stereo in/out version.
As for submitting a PR to the faustlibraries project, I will eventually do that, but I wouldn't be unhappy if somebody beats me to that :)
@SpotlightKid how about a faust2dpf script and architecture file as PR to faust? ;) Or do you think the faustpp dependency is problematic here?
@cbix: it might be nice to have, but I'm probably not the one going to write it. Firstly, I don't have any experience with how the faust2* scripts are supposed to work and secondly, for me the advantage of incorporating FAUST into a framework like DPF is that you keep full control over the details of the implementation of the plugin and you can customize the source to your liking after generating the project. I don't intend to provide "plugin generator" but a "plugin code project generator".
Could there be any way to have the control value range be a little less abstract? :)