[BUG] filtercoeff + biquad = less accurate than lists + biquad
Jul 31, 2009 at 2:40pm
[BUG] filtercoeff + biquad = less accurate than lists + biquad
Usually when you use signal domain control, it’s because you think it’s more accurate than using max messages, and that your sound is going to sound smoother, etc.
But here it’s just up side down : In my example patch attached, using filtercoeff~ -> biquad~ is less accurate than when sending max lists to the biquad~, this, in any situations.
But before, here, there is a strange fact about all max filters (which is not a bug), that I just discovered and I have to explain it first :
Normally when you send a signal to a signal object, you suppose that this signal object is “listening” to the whole signal, each sample… but for all standard msp filter objects, in fact, they don’t. I realized this while accelerating an LFO on the biquad frequency, with a high Q value (using noise~ as source) : Except of course the source sound on their first inlet, Biquad~, lores~, reson~, svf~, onepole~ are in fact just “listening” to their own signal inlets only once per signal vector**. I imagine this comes like this for efficiency reasons. And then some of these objects (are supposed to) smooth these vector-spaced input data, with a ramp, during the signal vector : Biquad~. And some others don’t smooth the data: lores~, and also cascade~. (for the others, i didn’t test if they smooth of not) After complaining about this “vector-limit” in an other topic ( http://www.cycling74.com/forums/index.php?t=msg&goto=178433#msg_178433 ), i finally found that, as i don’t specially love the sound of ring modulation and fm-like-synthesis and then will not want LFO on the filter frequency more than 20Hz, and while staying at short signal vector size about 128, that finally this won’t be an issue for me… hmm, this is not an issue for biquad~ because it smooth the coeff data, but it can be an issue with lores~ or also cascade~, as they don’t smooth anything during the vector !!
But let’s go back to our bug, now :
So while testing with filtergraph.maxhelp, I found that Biquad~ is smoothing these coeff data during one signal vector.
Then after, in filtercoeff.maxhelp, i found that this time, biquad~ doesn’t smooth anything, but change suddenly the coeffs at each vector.*** What is strange is that when I delete some of the 5 patch cords between the filtercoeff~ and the biquad~, then the biquad~ is sometimes smoothing again.
See example patch attached.
** And I’m then wondering about the utility for the filtercoeff~ object to have four signal domain outlets… one simple outlet sending list messages to biquad~ (at each vector), would be more efficient than that.
*** The use of the smooth attribute in biquad~, found in the doc, doesn’t seem to produce any effect on my MacBookPro/Os X.5.7/Max 5.0.6
Jul 31, 2009 at 7:49pm
Alexandre wrote on Fri, 31 July 2009 08:40
not a bug precisely but maybe a little ‘underdocumented’.
– Pasted Max Patch, click to expand. –
Copy all of the following text.Then, in Max, select New From Clipboard.
i’m still wondering, why at ‘resamp 1′ the coeffs are updated only every second sample (according to [capture~]) and not every sample.
Jul 31, 2009 at 10:10pm
hum.. 6 years already using max, and sometimes this software is so mysterious :
One more observation i just made is that, as opposed to what I supposed, it looks like Biquad~ is the only filter to really “listening” to its signal parameters at each sample… …at the only condition that the five signal coeff inlets are connected to a signal patch cord !
Ok, so now, using “resamp 1″ this sounds fine !
> why at ‘resamp 1′ the coeffs are updated only every second sample
it looks like a small bug: i just notice that ‘resamp 10′ makes 11 identical samples, ‘resamp 3′ makes 4, ‘resamp 2′ makes 3, ‘resamp 1′ makes 2. but anyway we can’t hear any difference.
After few hours on this, I just would like to suggest something to C74 team :
* Here for filtercoeff, but there are many other examples of things that would be fun to have in the doc
Aug 2, 2009 at 8:56pm
I am pretty sure this is documented somewhere, although it might be in the SDK, which understandably many Max/MSP users never have reason to read.
The basic issue is efficiency. Most filters only sample parameter inputs once per sample vector. If you want the parameters updated every sample, you have to set the vector size to 1. Please do not be surprised when you see your CPU usage skyrocket.
As an aside: parameter changes that occur as Max events won’t be handled more often than once per sample vector, either. So I don’t know about “less” accurate.
Aug 3, 2009 at 12:34pm
(sorry double post – see down here)
Aug 3, 2009 at 12:35pm
Thanks Peter for your remarks,
> If you want the parameters updated every sample, you have to set the vector
Of course nobody should use vector size less than 128 or 64. If one want the parameters updated (almost) every sample, better use filtercoeff+biquad with “resamp 1″, as Volker just showed, than any other filter, because we then can stay at any vector size we want, plus this “resamp 1″ will change almost nothing on the cpu usage, unless we have hundreds of filtercoeff running.
> parameter changes that occur as Max events won’t be handled more often
You probably didn’t listen to my patch example (or does it sound different on your system??), or maybe my first post was not clear enough : You’re right that Max events are handled once per sample vector, but what I hear, from the biquad~ fed with Max events at each vector, is a “SMOOTHED” curve of the filtering frequency… while I hear, from the biquad~ fed with filtercoeff~, a curve in “STAIRS”. Is that clear ?
The filtercoeff~ will ALWAYS be less accurate (and less efficient) than directly sending Max events every vector to the biquad~… Until you send a “resamp 1″ message to filtercoeff~… for it to become then the most accurate.
> ..which understandably many Max/MSP users never have reason to read.
I totally agree that it’s important to have simple, efficient objects that works fine in most situations without bothering users with complicated stuff. But, even if this is a Great software with greats objects, here, this is simply not logical at all, because…
…When are you going to use filtercoeff~ ?
And after, you read topics here about “poor Max Sound quality”, where people are wondering about the quality of the max filters, or aliasing, etc…
Maybe “that” could explain “this”…
*** And I maintain this looks like a bug or “forgotten code”.
Aug 4, 2009 at 11:01am
maybe smooth-biquad~ would be useful for what you are trying to achieve…
Aug 4, 2009 at 11:46am
> for what you are trying to achieve…
I’m ok with the “max-evens->biquad~” way. I just made this topic to show that “filtercoeff + biquad” is less accurate than “lists + biquad” (…until you don’t find this “resamp 1″ hidden feature)
> maybe smooth-biquad~ would be useful
if you listen to this “smooth-biquad~.help” from cnmat, you’ll notice that it doesn’t make any difference – with max-events – in the example, as it is supposed to. I imagine that when the cnmat wrote this “smooth-biquad~.help”, few years ago, the standard biquad~ object was not, at this time, smoothed for max-events.
And then ok, it does make a difference, i just found it, replacing the biquad~, after the filtercoeff, im my example patch, by [smooth-biquad~], this will then do the same than max-evens->biquad~ without any “stairs”.
So C74 team have introduced this smooth feature in biquad~ but, contrary to [smooth-biquad~], they only did the half job, they made it work only for max-event inputs… not for signal input. And as, by default, the signals input are going out only once per vector, in filtercoeff~, we then have a situation where the “max-evens” way of doing, as you see in my example, is more accurate than the “signal” way of doing… Making the filtercoeff~ object, in its default mode (without a “resamp 1″ msg), totally useless.
Aug 5, 2009 at 1:38pm
I confess I didn’t listen to your example; I was just trying to quickly address some general points about how MSP filters are (mostly) implemented.
Your explanation is quite clear, so I understand your concern better now.
The bigger misunderstanding on my part was that I was focusing on biquad~, where the main issue is filtercoeff~. Given that calculations filtercoeff~ performs are complex and expensive, it’s quite typical of MSP objects in that situation to only calculate once per signal vector.
biquad~, OTOH, has no idea where its signal inputs are coming from. No object ever knows where the patch cords coming into its inlets originate. So all biquad~ can do is “believe” the signal input. It’s cute that biquad~ interpolates between Max message parameters over the course of a signal vector, and that should be a very inexpensive calculation.
There’s a time and place for everything, even for extremely small vector sizes.-!
Actually, the resamp message to filtercoeff~ is a bit like setting a really small signal vector size to that one object (not identical, but I would expect a similar rise in CPU utilization). Never mind the idiosyncratic behavior you observed with that message. That might be worthy of a bug report.
And, if Gregory is reading, it would be helpful if the documentation for the resamp message included a sentence or two explaining what the “resampling” is all about. I don’t think there is much in the documentation (outside the SDK) that explains the only-calculate-once-per-signal-vector strategy used by some MSP objects. So I agree with Alexandre that a bit more here would be welcome.
Aug 5, 2009 at 3:25pm
Thanks for clarification Peter,
> the resamp message to filtercoeff~ is a bit like setting a
> No object ever knows where the patch cords coming into its inlets
Hm, i didn’t think about that. Forgive me if i put a [BUG] title on the topic, in fact, this not-logical situation i’m talking about may not come from a “bug”…
You’re true, biquad~ just can’t smooth data for a period of a vector if it doesn’t know when is the next signal value coming !
And about [smooth-biquad~] from cnmat, i just found that it just smooth the data over the vector, then it’s is not really made to be used with this “resamp” option of filtercoeff~. Maybe C74 team could put this way of doing as an option on the standard biquad~. I even think it should be the default option, as almost nobody knows about the “resamp” feature.
You must be logged in to reply to this topic.