curve functions for waveform distortion

    Dec 05 2010 | 3:10 am
    I am currently using curve~ to populate a buffer~ in order to distort waveforms using lookup~. It works well enough, but is somewhat of a kluge.
    What I'd really like is a transfer function that would operate directly on the waveform instead through a look-up table in a buffer~. Ideally I'd like a formula with variables (like the "curve" parameter in curve~) that I could change in real time to alter the resultant waveform in real time.
    Ultimately I'd like to be able to produce sine type and s curve ("logarithmic" and "exponential") transfer functions. My math skills are not up to this, and also I'm not sure what would be the best way to implement it in MAX/MSP
    Thanks, Bruce

    • Dec 05 2010 | 3:15 am
      Not sure about operating directly on the buffer~, it seems like you'd need to use a lookup table regardless, but I'm not sure. Check the helpfile for jit.displays to get a few math expressions to get you started (sine, exp, etc.) using [uzi] and [expr]. You might also find some interesting possibilities in the jit.bfg helpfile (that is an amazing object...)
      The math part really isn't bad, provided you have appropriate scaling for the input and output of the domain and range. An [itable] is a great way to test various functions, and you can preset it (and draw in it directly), so you should be able to get some good curves.
    • Dec 05 2010 | 3:29 am
      Hey that was quick! Thanks. I may have missed something, but I didn't see anything in the jit.displays helpfile with expressions in them.
      I guess what I'm hoping for is to operate mathematically directly on MSP signal sample values rather than create a lookup table in a buffer~ from a mathematical expression, and then run the signal samples values through it.
      It's real possible that I am missing something here, but I'm just getting that itchy feeling that there aught to be a more efficient and hopefully realtime alterable way to distort a waveform.
      It seems that overdrive~ is an object that is doing just that, but there is no access to the transfer function other than to adjust the drive factor.
      Basically I'd like to create a patch that operates just like the overdrive~ object but which has more sophisticated control over the transfer function.
      Thanks, Bruce
    • Dec 05 2010 | 4:02 am
      i would recomoend you the following:
      try the whole thing with messaages first, see how it works to scale a floating
      point number from 0.-1.
      then you can rebuild it for signals.
      just take care with cos and cos~, the are doing not the same. :)
    • Dec 05 2010 | 5:32 am
      Here's my test patcher which pretty much does what I want. It's just a little weird during transition from one transfer function curve to another and a bit messy trying to get curve~ to populate a buffer~ without glitches.
      Thanks for the help so far, Bruce
    • Dec 06 2010 | 8:08 pm
      that patch is great. learned a ton by hacking around in it and am still figuring parts out... fantastic!
      you might have a look at a sine-wave project I did awhile back, it has some simple expressions for filling small buffers~ with sine waves. you can control offset, number of cycles, exponent, and how they're mixed. the "p calc" subpatch shows what I came up with for populating a list using [uzi] and [expr]. which I'm sure you already know, and could probably be done much more elegantly :)
      oh, and the jit.displays helpfile wasn't the one with the expressions, it was jit.charmap, oops. (I think jit.displays used to have some expr-gamma curves to play with, but they're gone now.) Again, brute-force [uzi] works fine. Though with some more digging you'll get much more interesting (and most likely much faster) results with jit.bfg and jit.expr.
      [expr] and [vexpr] both support table-based calculations too, by using the table symbol, so you can draw tables for use in your expressions. or better yet, create them with expressions and apply them to modify other tables, grab signal output into a fresh table and work with that, etc... etc...
    • Dec 07 2010 | 2:07 am
      Boy, now that's a patcher. Mine is strictly just a gob of wires while I explore the subject. Yours is beautiful. It will take a while to work my way through it to see if I can make use of the sine populating functions for my little project. Anyway congrats on a beautiful and functional creation. BTW, I never bought into Jitter because I was not really interested in the visual side of things. Do others make use of Jitter objects for audio processing?
    • Dec 07 2010 | 2:42 am
      thanks! yeah it was a fun one to build, I was totally pumped to use the new transparency abilities of waveform~ and scope~... (it was just after 5 came out).
      Audio for Jitter, well, like anything else there are a ton of straightforward and not-so-straightforward things that are possible, surely there are a lot of folks on here with ideas. I would think one of the best parts would be to use the video-specific (matrix-specific, that is) FX jitter objects to see what happens to audio and vice-versa.
      The other whole part of it is the GL stuff, which is... well, freakin awesome. So again, how would an audio signal distort the vertices of a complex mesh, or change the rate and intensity of a jit.bfg pattern... etc... :)