Saturday, November 20, 2021

New Audio Effect and Strange Bug

I had an idea for a new audio effect inspired by Def Leppard's middle section in Rocket. The effect takes a sample and has a speed-jog control; 1.0 for normal forward speed, 0.5 for half speed (octave down) 2.0 for double speed (octave up), but the number can go negative too; -1.0 for backwards and -2.0 for double speed backwards. All samples loop fully. It results in many odd loops, particularly interesting when the forward/backward play is flipped regularly. Not sure if it's efficient to even create it - every new plug in uses resources. If I do create it, should it be mono, stereo, hexio and tuned or monotone? For my last slew of sample effects, Zeitraum, I made normal, monotone, and stereo.

Anyway, the effect is very complex in how it anti-aliases samples, so it's not finished yet, but, I encountered a weird bug connected with backwards looping. Look at this code, a and b are floats:

if (a<0)
    a+=b;

After this, a can sometimes =>b, when logically a should always be >=0 and <b. This took a while to track down. It happens when a is just a tiny bit below zero (around -0.0000001), so the precision limits of float are accidentally pushing the result over b, which is a pain. If it a>=b then the routine will infringe on memory beyond the end of the sample.

This caused a bit of a panic, that memory leaks were occurring in my sample playback because I use this for looping. When I reach the end of a sample, I subtract the size of the loop from the pointer. Fortunately, -0.001 and +0.001 (or even -0.999 or +0.999) are converted to zero when floats are converted to a long pointer, so it would appear to only be a problem for backwards loops. I'm not sure what the best solution is. When a==b I want to set a to 'just below' b, - not b-1. I'd prefer to avoid a check. I could limit loops to full size -0.001 of a sample, though my perfectionism doesn't like the idea.