zero crossings in loops

    Jul 08 2010 | 11:51 am
    Hi I'm using Lemur as interface and am controlling looppoints that way. When using waveform~ there is a possiblitiy of choosing "snap to zero", which works fine when choosing loops WITHIN waveform~ using the compouters mouse, but when giving information from outside the object, zero crossings are not found. As an alternative, I've used a peek~ object, through which I'm entering loop point information "scroolling" through neighbour samples until a '0' is output at which point I choose the actual sample point. Anyway this doesn't work well and it eats a lot of CPU; WHY CAN*T I JUST USE WAVEFORM~ with the snap zero function?

    • Jul 08 2010 | 12:47 pm
      don't know about waveform~, but generally when searching for zerocrossing checking the samples for an exact zero value won't work because most of the time zerocrossings lie _between_ two samples. You need to check if the sign changes from one sample to the next.
      mathematically speaking: x(n) * x(n-1)
      For efficency you could write a lookup table which points to the next/previous zerocrossing.
    • Jul 08 2010 | 1:11 pm
      Yes - the waveform thing is a pain.
      However, you can workaround if you know the following things (actually I thought it would be simpler than this, but this is the solution I just found).
      1 - banging the selection inputs outputs the selection
      2 - sending "snap zero" or "snapto 3" will snap the points currently stored in the object.
      All that remains is to gate the selection output when you are sending values in, then snap the values, then output again.
      That would look something like this:
    • Jul 08 2010 | 10:12 pm
      i too have encountered this problem. thanks for the solution alex, though i think C74 should try and make this a quality of the [waveform~] object without needing any workarounds.
    • Jul 08 2010 | 11:07 pm
      Agreed - I once (4 years ago or more) spent a long time making workarounds for some weird waveform esoteric behaviours - I haven't used it a lot since then in such a serious way, but although I can see the logic of not snapping when you have sent in specific points, it would be nice to have it as an option to snap the incoming points....
    • Jul 19 2010 | 1:42 pm
      thank you Alex for your 'workaround'! It does work however I don't grasp what exactly makes the difference. Probably the fact of banging the selection start/end inlets in waveform. To you Mudang, I'm sorry but formulas tend to become chinese in my head, so I really do not know how to proceed from there. I suppose that when you can zoom in and actually SEE the seemingly perfect zero-crossings in Alex' example, this procedure will do the trick...
      My next problem is that choosing a perfect zero crossing in a sound does not create good loops in itself. I want to be able to have msp detect meaningful sound units in a given sound file, - segments, phrases, etc..
    • Jul 19 2010 | 3:53 pm
      The reason my version works is because I input the loop points (ignoring the output - hence the gate). I then set the zero cross mode again (which internally snaps the points). I then bang to output the snapped points (now with the gate open).
      The second problem is a much greater one, and and I do not know of a good easy solution to it - there are not many objects that search buffers, but I suppose you could try searching for some 3rd party externals...
    • Jul 19 2010 | 5:31 pm
      the best way to remove clips in 'musical' loops is to ramp down and up from 0. Check out grooveduck.
    • Jul 20 2010 | 12:14 am
      I wrote an mxj object to do this a while back if you want it. I think it takes a start and end point in ms and outputs the nearest zero crossing points (ms floating-point) for each.
      I found that gooveduck worked just as well though!
    • Jul 20 2010 | 9:28 pm
      I have aesthetic problems with using amplitude ramps in the output. From an aesthetic point of view finding perceived phrases in the sound material is much more interesting. So working with an intelligent onset detection or the like is more the path from here...