[announcement] PM.Chamberlin~ (state-variable filter)
Hi everybody, I’ve just posted a new svf filter to the toolbox. It does self-oscillation and saturation, supports higher cutoff rates than svf~ and adds a peak filtering mode. (it is more expensive, however) You can also control it via MIDI values and the tuning is accurate enough for melodic playing. It also has the option of only using one output which should save a bit of CPU when you don’t need all the outputs.
Tomita Whistle, here we come….;-)
License mentions source?
filter model used?
Anyway, thanks again!
Re source: It’s a binary distribution. That said, the filter is ported (lightly) from the ICST DSP library which is BSD-licensed, however, so you can definitely take a look at that. They also made an interesting two-part PDF which explains how it works.
The model is a Chamberlin state-variable digital filter, and has a non-linearity in the feedback, IIRC. The frequency is updated every 16 samples, so it works decent enough for sweeps, but FM is probably asking a bit much. Might add the ability to up/downsample the freq input in the future.
Aw…yeah, we want to add lfo&env to freq for whistle patch, right, and stepping is bad to hear there…16 samps is *prob* ok, tho…
Thanks for reference, I had seen this design before, and indeed, it does sound excellent, oscillates great, and the non linearity in the feedback gives that lovely fat ‘formanty’ sound. Thanks again!
this external shows up as a folder and max doesn’t see it. any suggestions?
Which Max, and which OS?
Mac OS 10.6.8
2.66 intel core 2 duo
I’m not sure. I tested the link and I see the external fine; I can explore the package contents.
What do you see when you unpack it? I see PM.Chamberlin~.mxo, PM.Chamberlin~.maxhelp, and license.txt
I changed the link to add the bundle bit and updated the plist files; I’m not sure if this is a 10.5-10.6 difference or what the story is. HTH, and let me know.
one more thing.. peter this sounds great.
thanks Peter, the filter sounds great, it’s a useful addition to the msp toolbox!
However, I think there is still some unwanted (bitcruhs-like) distortion in the signal. This distortion is changing when you change the signal vector size.
Listen to this test patch:
----------begin_max5_patcher---------- 487.3ocyUE0aCBBD9Y8WAgW2VCnVa6da+NVZVrHyxhBFkl0tk0e6CO0N6l1v pMM8EH7cGv28cGGe55fWo1xKwnGQOibb9z0wAfp.bZV6fyh1xRiJA2vR96pU uguu1jluUCv4YSXqixVwKREx8noDBo0GQL3gYWOD1ho1nS4Z8tbd8ciKEIxn TLZYiCupjZYTFXF+TgvXqikRwGfEJYBoAVtISHMmIvR+e.quI.k1flGoYqEx jWJ3Lc88SCmaNIj2BXhRlASlEnkU64KW2pg6sTiXprLtT+GQxfmGUvQZERUH RDxehpNhT.EeQDAZuh.4Dh.sJp8IdUSKBGkDnUIIo7dhN+fAqADFI6PAfEgx oxmjt4SOR63YEKCTxeGh1W74YW7Mtbq2YJH99j5oQkbGPPJ4ol6SUrG40uzP uYe9GTW56Ck908BtzpCaGKku2v4d6L5ckjl+egy7EfZDBsDCCFkzv+HNhsuu ddX6I6o5fETWdOGxiASaGOhrfRhMeS86O9fCrB+3HnTsof0lMZxUHxg7QLuT a5jqEJYGeBOxm0h3XtrK4yDw4JSCgFJPMMplZZQQAJSmM6vpAz4KIWqdWZdx ZMYGIkBskRzqFk7sVlHWONEXCm7ttbhZAmBtMoz4VMYV7k62p+yi7A -----------end_max5_patcher-----------
I can provide audio samples if you don’t hear any differences on your system (mine is: 44.1kHz, mac os 10.5.8).
(addition: I am also curious about the level difference, I wasn’t expecting that)
idea: could it be that for upsampling you do not take into account the last values of the previous signal vector? (that you don’t store these in your object structure)
I hear a level difference (-6dB), but I’m not getting the bit crushing. I think the level difference could be from the saturation code. I’ve tried this at signal vectors of 64,128, and 256 at 44.1kHz.
Because of the saturation, pre and post gain can make a big difference in the sound of the filter. I’d like to hear the recordings if you have time. Also, does this happen in both modes of the filter? (mono vs. poly outs) The code is slightly different there, and that could account for it.
----------begin_max5_patcher---------- 1208.3ocyYssbihCD8Y6uBJdbKGWnKbwyay9ar0TovfrilEjbAxYRloF+su5 B3fy.XgMlkGB1Hgac5i59ntI+Z4B2s72HktNew4ebVr3WKWrPOjZfEU2uvMO 9sjr3R8i4VlvOPN4txLE6XNkkQD54fUCdHVj7Bks+4BRhvXaXT3ZuUNAdX0G .j24Ob9V0uhlpsOe62eBtog84GE0KfW0nIwYII7iLsww0qZAojvDwBJm04J6 Ucw4apezuWtTcYkktNi7CI5pglf7ldIbepe1XGmIJo+jnFC.W6cURxOP8TNH 3Z+UNvtnnn1oHP0nlgDuefXrsaIcOKNy8rsTvhEmqm18qEz3Lm+lmk5Nd7xe cxAtdjnF+v.M0Dp2EQ5a5jZBmOTysksfMNnsYKA8msHJn62SJZRACJApBLfn 6NA5FYiHj1+gQVwF98yFc3kWtH2mLww7sR5tMuDL3.e.vWGwaXeeudC7ws65 vtB7ox.fUNtaiY6udze+72k37QHyVF+iSN.OuwRRAA8Mj4Fc3cXuLKZFo1Nt gWlHJyt2UBufOxvqISNo5nj.OjMxIfM2o35s3WGjfsfeatGxWenALTGPi7Lt mWWt2PKi3iMxNDBtb8uKgfDddNQEC8Ik.43GhKHNBtCWR+TUll0oCd8kNTUW g1C1nuQom0Jwg6Ot3OCyuh.Jzr1nGm9IIStX7hSNHGPq7Edv7Ev2f5.MpMW6 jwF+xxFwhUYbZYGIaCWUE5G03nE7l9TUAdynpUuKgGrQwIBZivylgq6bCNzt Ltz9iztJJpJEEb8yJiF3QkRfFOZ0hAQaFKsjQk.gFIU3Fz0Ivv+WIPSIBvP7 Li.8flhUrHBz+wRf2.UjQekrdeLkcVZ403hy19Om0VgG.TK7fw5MMbUWhAcH 21Ns3e17ER.IHEOSXwayH1nDup42T+clJynkhOnxx3WIoOGKjkLt8nf7w2Jq HsJVSwKYGI7c0CWOdS3kK4F07OEd9.5KlmxnB0IjZj1HD4hGp1W5w.M3g1dp xW3Eht2CuDx7TY7fIJOrUPKyU1O.iYXf18+LJ6eUlprKjqL.OsG2eGWCi1V7 iRtoryY4EolFBZytojccOo77WRZFMWyQs5VkBxgxtw7qzRZO6Vj2NvYDSiIs a+XFiWIGddinSFP7tYovsQuUa0xzPyjZwh5OFmZ1NjuN4kXU2vxc6SR8POuV 0NPCutVyaCBAL8H5E1WgsAyh5Zm9lkLcrf.gWuaILXvcK8HZ7A2QiO92ZiOU 07Fh5y4Qf4biOIumjQzuXMO6ewZ8GWT8ZqMMBDf6iafyBpg7yz3jasti.SQY X+5qsl.zQ7eCvp+YxS8Xe9+GmdoUieoGTxOVjTyK0MX67wpmRJExrckVdiGR 8OKnwC8BMMkvZlJlSSOvoLQEH5nnWawDzJLI6VxALcXJxFLsYR4IkFgc7zLa uCLG4ovokmP1fI+oESXKvzmHyGMl7sglPyusNMMgmWXRq0ilLLodIk1wSSGl f1BI3jAo.agDXdIXBleZ3yPVZZOoCBsUFvaVkxogzzsyYUQuSaMuVIVpwMbl goos9xHK24ltfIaikfyqZll1n6K1QZGQ3oUBvBNBeGbj7leu7+LmQPXG -----------end_max5_patcher-----------
I sorry for the delay but now I have time to reply and make examples for you.
I hear it in both modes of the filter (mono & poly outs), it’s not clearly visible in the scope~ and spectroscope~, but it is clearly audible on my system.
I included some spectrum plots of the audiofiles I attached to the previous post, this clearly shows the distortion that I hear (note: green is incoming audio, red is filtered audio, sv means signal vector size)
[attachment=169399,2557] [attachment=169399,2558] [attachment=169399,2559] [attachment=169399,2560] [attachment=169399,2561]
Those spectrum plots look pretty cool!
If only you could get spectral plots like that it MaxMSP……
Well – maybe sometime in the not too distant future..
yeah Alex, having spectrum plots like this in in max would be awesome!! :-p
Thanks for the thorough example. I’ll have to look through the code. The filter equation is from the ICST library. My guess is that the distortion may be from updating the filter coeff every 8 samples, and the filter coeff is affected by the feedback, so the slower updates could be causing the distortion.
I could add an option to set the update rate. I might do it as a % where 0-100 is scaled to 0-n where n is the result of the vector size 2^n.
Peter, what if you update the filter coeffs only when they change? Do you still hear it? Maybe when you set the coeffs the ‘history’ of the filter is reset as well.
If it’s due to the filter resetting it is still weird that it changes with signal vector size (which are all multiple of 8 in my examples)
Had the coffee now; the base2 log isn’t great, and I’ll probably just go with a sample delay.
It’s also interesting that the distortion seems to go up as the vector size increases. There’s a multiply involving 1/vs, and I hadn’t taken the do_every_nth factor into account there, and I’ll see about tweaking it.
It’d be really nice if we could message people privately. I had someone offer to build a windows version, but I have no way of contacting them…
"It’d be really nice if we could message people privately. I had someone offer to build a windows version, but I have no way of contacting them… "
sometimes you can see the mail address of the person who replies in the email notification you receive in your mailbox
looking forward to the tweaks :-)
I think I’ve got it tracked down. I had an error in my bit logic in the coeff update routine. See if this works better. There’s still some noise in it, but it looks harmonic, and much cleaner with a sine wave through it. It’s available on the download page.
One issue still to be resolved: updaterate of 1 sample sounds bad, but updaterate of 2 samples sounds fine.
I’m coming from Java, so I’m not used to doing a lot of bit-manipulation tricks. My do every nth code looks like this: (for i in vector)
if (0 == (i | nth))
where nth is nth -1 (so if every 8 samples, use 7 for the bitmask). Hopefully I’m getting that right now…
Thanks, the ‘bitcrush effect’ is gone.
Yes, there still is some distortion and, but this is due to the saturation I think and it really depends on the level of incoming audio.
Only it seems that in this version you have broken the non-signal frequency input, it only reacts on signal input now.
I don’t think "if (0 == (i | nth))" is doing what you want (check it with the max bitwise-or object if you like),
I think you are looking for "if (0 == (i % nth))" (where nth is nth – 0). Though you need to make sure that your signal vector size is a multiple of nth.
(it might be possible with bitmask operations as well if you stick to powers of 2, but I don’t know them so well either)
----------begin_max5_patcher---------- 561.3oc2WtraqBCDFdM7TXgT2Qi7EHX5t9bTUUwE2DeTvDANpo2d2K1.oIMM kfIfhNabhGaw7OedlAy61VNw4aYkNf6.O.rrd21xRaRYvpYtkSVz1jUQk5s4 jjmkwDRG250jrsRscdqEwlLtXESp2Npw35HYxRtXwSErDYs67CmAcAAdpQj9 +H5LH3wueL4ajsOGXiUdp1Y4w+6VrWqGeNWHEQYL8R2WviVs+Jk72zqffyfJ qeZaqFbGX7JjK6aDSfDUX5gTiXOCBYzjDxB1KUd6nH9V.5WiX7oiXDt9fk.U +Pvy7+yPFcbHincGx0OA4qqY0d0gWcdsyEiGPjfXPuS6w9ZVfpS46DI3eAID CPRbjXgiaGnoU0ErxpT9HIOWbRkCaF.OZ.PyXkkQKXGQTXeSvZ0DUqolIy6U B1bCn4PQHc3H7D4j2.nlxPerwEoA+mUjhP0HABMtHENVEolflMYwrBC6T4g2 qzpWLHzvrB2FRXXQFA6qzJkN7ZLi3lefxmgdlhM5XgsKXiZLo2WE.gquoGwz N0W1F0WtNLe.BLEF9yMskKdD63p2iyJt3meYfNRT1ODRk4aJRZcRi3.eGKor RIWnqR2aOUml.zt8rjmlxD6es2Ld557JE2HgST+dtJhdFJ5PUO1JR8BhqMIc tTZ5N2T2rnSIgl1bI08u6VSAS6QG4.D7GZ55plahwT34HIx0mjf8SRX+P0aT B7zuWAsaxknkUmIYzAfupIeZ+EPP4wS. -----------end_max5_patcher-----------
You’re right, it definitely isn’t. I need:
0 == (i & nth) where nth = nth-1 (so if you say 8, it uses 7 for the bitmask)
The reason for doing this via bitmask and not % is that I’m trying to avoid adding a division to the mix. The 2^x-1 bitmask should always be non-zero except for when i%(2^x) is 0.
I’ll have to see what I did to kill the non-signal input…
Hi Peter, yes 0 == (i & nth) works, but I don’t think it works well for all values (I guess it only works for powers of 2).
if updaterate is 8 samples for example then nth = 7, then (i&nth)==0 for i=0, 8, 16 which is correct
if updaterate is 7 samples for example, then nth = 6, then (i&nth)==0 for i=0 , 1, 8 ,9, 16 ,7 which is NOT what you want
if updaterate is 6 samples for example, then nth = 5, then (i&nth)==0 for i=0, 2, 8, 10, 16, 18 which is NOT what you want
check it here:
----------begin_max5_patcher---------- 610.3oc0W1riaBCDG+L7TXwgdJ6JaCN.8VeNpVUY.2D2BFDXTS2U66dw1PIc CIgOBH0CwQdvF+e9MyXady1xIJ+DqxA7YvWAVVuYaYoMoLX012xIidJNkVoG lSbdVFSHc1YdljcRpsKjG6rIpy3hTlTOATuw7ZYmUXqUdhdx4Q+3IDoa9eOW HEzLl9QeojSS6dRQIqpYwoRdt3akrXoQ4HO+mg6.HBQ8GrsA7R2rnx3ibwgq NCrmtSvYyQogJ9qZMfZdYJquaaqZ1MRRIX+pwut.TOAPCBJ7ffBM.n7tOnLu A4uKXF+0g2DxtEPBvJDPPpVW7yjGONxXUUzCrK3AFtPbfmANtIKLIEjyPw9M Iyn9U9DPg6knveFjHhJN3rq++6knzVwDpZ81ug0MEz3etrLExiNQwTzfwqXU y0fQIueO34se6H1E45trWf1kgqQ7+ZmvvWl+hmmC6py2MI5gao6VWjPkrxle .t.TQyJRaNodYH.MKDfB0AcOWs6CC+u5vxfU3vRjY6OjI+eSK7kfHvTJDvCf D3BNl3tnAY1S.tlnoNKhUtLHDNyzhtSJu8kK0Num9VkD3FVt7If+xJWvqQ0B Batq89omRnGiSJW7wORQuNJ6+KjpxqKi6DVabFzuRIrJIWn+7gyFipf3rAcj mjvDmuEZFOoHuwMq5hugJev2S6In+1A7xfQxwJ0lPG.eOo5MMotPI8gkaXMg mljBQZr4Z9.LbeusPqjsEe3QHI+MUR3QBIzDJGZigglHJjXtqzxinjQn0Mtd HXj0CnsSRvGeI5iPRn6sSVvBzTSm2s+CPzBQm. -----------end_max5_patcher-----------