zero crossings in loops
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?
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) < = 0 ?
For efficency you could write a lookup table which points to the next/previous zerocrossing.
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:
-- Pasted Max Patch, click to expand. --Copy all of the following text. Then, in Max, select New From Clipboard.----------begin_max5_patcher---------- 1004.3oc2XssjZiCD8Y3qvEOyRoKVW79V9N1JUJAHHNiuPYKlLaRk7suRsrM FhwXV73Tjolwx5xHN8oOcqV784yVrN+Mc4hf+N3eBlM66ymMCFxMvrp9yVjp daShpDV1hTcYoZudwR+bF8aFX7B8gD0llwOnLa9bb19OUn2X76OguBsLHjRc MLj6IVtBE7wp+k3svFku9K+Eqda1kmYxToZXlOTDqRpmI6XZbVh1.nhbZv7i l5Qws1jx3uAaBlX+b8C6Wo4eOn83awhfO5l4Gym6dr7AIjRsIHsO9fFA7gT. Mh93C5SDejo+pEx+Bcr93tc5he1OkTIQX.YvktmDT2TB9NoDbmTB4NojcI4J yhkVyQks++G+X2BKF5SWfgHDQXnqIRzGKHQ+wRCDLySCzaSChnmUZ3JQKGyN n17R.Zk82AvQHHUBF2aRDg78ijPCfj7uLt4XyTGB9ltHuGNBy.NhANx.FDTg 4WghDueIZQSThVSv5.r8u0AIAn9zNB+AORfWj7UrdjNrQQ5vuSdABqrJm3rS QYsZqmZLYuCpAD0UwbbnFlvndC5Be9UT6UF8sSBwE.QPI8JjnO+zwvxLS.1f Gxak04ZjB5IhTt8419nCZj+babeVNO526QRumUwQ8YGH9p35U.vkOqzvWUup 2kWj9yZXlnVqSVueSdRdg+iAshyPQxktWhBwX3MI29ivxHsHDkwT7o0GRASw V7OITh4QUSVpSrTabd1Y6LZ4YOXM60EHfJCo3PXIRIgxf23RN4BHb0aownLe t9vZQcmWaUzNYQKDzr3y7hrZayVEiIusGzDu4EXIxpAdMe2N6EJcCYsUQumt 5uoUiJ5zEtb6Zpp3kycNUdhtdqsYdlnBuhEwvRQiywjluElhNvx.67kj3Rnc Qym5qfd5LMesj65BA.1sDyvtY27rK+lN.2sa7yU3k4GK1Ti65xeBNQEa0kl3 LkSM1ZQNme.oYQeNd6VMLec7WZ71C415UJq0DcFucWXhLDLQ6AScPhUwn3Fl ra36tkJyUVMDQDhBWIp6NFVF9FVlqPhVtjdsLbGxiqXTHXELR0cED+ZOt.NW iXyqyp5MF1K8V1q3F16kVBwicjDJGiCnE5MFnMbjiEngH.e9yLIReQSTz3vs reOZIeQeSrVJb.YptHc16dlJ5PvjbRwzPRnimTDgGPRO58gHIHqrUQ4aZ57f HkNzCCmP2oX.GF5tl0TiI5PvD9NRTRgSc41xQsMDwodOZPJZHAoz6CsOHlb2 N71XJbR8pb4Pwzc4UiffSFbJHEya58nd0Ag1no83.4.xzIm1X0KptZbxoUWz EQ5+dVa5bwkSl+i4+GfMSyBF -----------end_max5_patcher-----------
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.
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….
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..
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…
the best way to remove clips in ‘musical’ loops is to ramp down and up from 0. Check out grooveduck.
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!
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…
Forums > MaxMSP