non MSP IIR filter
What is the reason for needing to avoid the signal domain?
The low freq control data?
Hi Brendan.. yes, i don’t want to upsample and downsample just to implement the IIR filter… especially because I might need to run this for 20 or more signals simultaneously.
Did you try posting under Gen? No doubt you’re not insistent about JS? Sadly I’m fluent in neither, and any attempt at a lpf in Max I make will just duplicate your own.
I’d strongly recommend keeping this in signal domain if you want to do this via normal IIR filter. MSP has some pretty efficient filters, such as onepole~, and IIR filters are a pain to implement correctly, since you have to be aware of things like denormal numbers.
If it’s sensor data, however, I’d use slide~ (there’s slide in control rate as well, but you’d need to be feeding it at a steady rate) or rampsmooth~, or if it’s coming in at control rate, use line or line~ to smooth it out. Slide~ is almost obscenely efficient, btw.
If something needs very regular processing (e.g. it’s calculated > 20 times a second), I recommend doing it in signal domain. It’s pretty efficient, and if you want to save CPU on these types of control processes, you can always downsample with poly~. (I routinely downsample my LFOs by a factor of 16.)
If you’re scheduling a bunch of events in the controller thread, the scheduler gets unhappy, and then you lose timing precision (not so with signal domain!) –which your IIR coefficients are dependent upon! You also don’t really have an accurate sense of how much CPU the scheduler itself is using, so there can be problems with spikes.
In general, my rule of thumb is don’t use control-rate to do things more efficiently than signal rate. It blocks up your scheduler thread for more important things, and usually isn’t worth the trouble.
Either Line or slide would work if you really want to avoid signal rate. (interpolation = lowpass filtering)
You can find formulas for various biquad filters here:
MnM (part of IRCAM’s FTM) has a 1st order IIR filter ( y[n] = alpha * x[n] + (1 – alpha) * y[n-1] )
It’s called [mnm.alphafilter]
Lots of goodies in the mnm package for massaging sensor data streams.
What’s wrong with regular objects? It’s pretty easy to implement, I doubt denormal is ever going to be a problem there.
----------begin_max5_patcher---------- 1256.3oc6YssiihCD84juBFdZ2Y5NBykbYkVoc+NZ0pkC3j3YACx3jI8NZ92 2Baf1NbIPOYRyC6Kfn7siOUUtJJ+84yr2ldljaa8GVOYMa12mOalTTgfYkeO yNAeNLFmK6lMi7szse09AUSBxYgTbbJNJgjma4rvspQ1wjzihXhPNRTozcoL QN8eIRYtKbJEq5o30LhBM11VOW1TFVDdfx1+BmDJTshBPvHsb87Kds1U9gyB m5wPijvBf5inM1ZKMCmHWA6+lSwwZPkxpQZgreLedwiGFHsDlljPXhF7h0qO wd15OsvwYGvVe15bwmew52PVOpj86fPnOOhdtcZyoeZKiSxg0EKnoLM9w0QR LtqjubJeTyN6362Jm72lmV33UajywFzh.3EZUuj75OPRVRjuK5aPDgqixXao zLCE3zKQr5NPDc3Dlca771ANyhdc+BzsLPHTuDRvHIDW80kvKogRd.lEZL4D gmCF7ZatY13rLMwyzFRA480T4Ds7gZQTlRDpVDmbhVMdmZoXNr6EvV+HWg7y qWZqZDTXyqFZM0HsN13qYw36nQMfpcebZ3+PhzWF6zLBixz8lMZNhrCeLV7R 6pPy12gCIcN3V4+Y164znTVAHLFYg3pkq3PWk8u9lQ1CFNqkAmC6ii4aw7BV caLQS2B1roowlMUqHASeLilfEDAUAVWm5IkljwoLgwBQXXXNNjGxSiiMlJUK mZokHPWGR9FMRbvv+unEn6zrJUfcMGEQ2SxElxD384lRLBnpaDp6SaHuOeaS +6vXZF.UKzB8la0YuGG9qDtsyvANKkpeGoAdPvk97M76cru.Jsa60v+2qRt7 PwR+raOY9oG+kvilGd1IYBorrJnlM8bkgX6gM27NIS26CY9Yvr7ihKW5UkeB 7x26Z1kKm1L4W9.YxxLaBjViW2lL3+sI6mIQdKK3vUW8rR+I.SJm0gwWMHEY D4AQI9klXUO6L5gamaZc0S0eDHCAOQHiwEAXvDh2GJgn1kcyHNCQ4646OvMq emaVzH1ruklZLk0UVYRzVzd6rPd5QdXkpsRQXYhbHkQAkUm09S0gruneGnQQ lIIqxqLuHKU0+CLHU1Xg7lAhXHznEZRf3hjGGDj8mLP1efHNXxXVrbDHdZvw AivPdHbbBMJKEBdkWWVihTdVqJqQvpEts7oyZYL8x7LgOLwyudWC2Q3ZLMLz F7Qls31O0M0P2JZ154450TxNGehD8BrDPPzWvBAmt8nPEDSubX+rU945UVZD kCoUPzyh20htONcKNtr.f0iskptL+MRbjkPMA1zz7XZDgWUExbh.Rz.5kR85 TWti5xZZlyiamWcwCFWeQ6knesrpo99tsVgd.K4hWUUFy6ZEh0yq7BPjGJsY SGEhE0d8mqmcNPzBB+EUUypsSGIwBo+ByucuL13pDMvlawr8C5BgTUbs+RzO 5qp3FyP2OSuAZEsdkZ8BFfUj2cgh53BN3XVTZBfTzs4lNz+u0t7S2nHGk8UC +zN8IW1wu9qykti8lQtcLInj3o.vr9KbnfdhXciXzq5nVdhU4MG0K8f9InG4 7Y9aeJ15x7.J4rl4rX7SScD7esQeZD2uYL+FJugBG2AfFTvcCNqGJbP2E3bw NuC7flTZKu6FZPC.MtuSzn7yt3tWK.xE245E22Zy6Zsq6YEVmeL++.n1Ff0C -----------end_max5_patcher-----------
Looks like the denormal thing doesn’t matter w/ Max. Good to know. (is there anything internal to Max that does that?)
I personally prefer slide, since you get the benefits of asymmetry in attack/decay if needed. Really depends on what your signal looks like. For things that are similar to a percussive attack, having a fast attack + long decay often works pretty well.
Bit of a wild hair here, but you could also pretty easily implement an FIR filter via zl.stream, vexpr, and zl.sum. Could be interesting to use a window function with that.
that’s great.. I think I can get away with regular objects. Thanks everyone!
I just uploaded C code I wrote 10 years ago that does IIR processing. (Sorry I didn’t do this sooner. I was wrapped in a PHP object and couldn’t get out.) It most certainly needs updating and I’ll get to that as soon as I can. It’s at: https://github.com/diskerror/MAX