*EDIT* This is pretty much working now, making this the everything autocorellation thread!
Hi everyone, new to the JS forums but been messing about in JSFX for a good while now and am becoming comfortable with it. I am currently trying to implement an algorithm that accumulates total energy across a certain timespan. To do this efficiently, it needs to add the latest sample, and subtract that sample's value back out later using a delay line.
In trying to get this working, I am seeing some drifty numerical wackiness, which I am blaming on the inaccuracies that result from adding tiny floating point numbers to the rather large accumulated one.
As far as I can tell, JS uses exclusively 64-bit floats for everything. Is there some way I can force it to a use a certain fixed precision for this?
What do you mean by "fixed precision" ?
64 bit float format provides a "fixed precision" of about 48 bits. That is some 10e-14. I suppose that there are not that many relevant algorithms that need more. Do check your algorithm on that behalf. Maybe some math can modify it to be less prone to the effects you see.
To get a better precision some very hard software means need to be applied, as the computer hardware can't do this.
Sounds like some kind of moving average? Shouldn't need huge precision, altho' a "simple moving average" can be a bit wacky all on its own. If the input is peaky.
__________________ it's meant to sound like that...
I'm trying to implement autocorrelation as outlined in the Autotune patent, which is done with four multiply-adds per lag per sample.
Basically it involves keeping a series of moving averages across lengths ranging from a couple up to 880 samples. It's an awesomely elegant approach, but for perfect accuracy it requires that the number added is EXACTLY the number subtracted 880 samples later.
I tried filtering out the drift with a DC offset filter, and briefly tried something like an exponential moving average, but wasn't able to get any usable results from either. As far as I can tell, this approach requires equal-weight averages, and doesn't respond well to drift. The numbers not being subtracted back out is clearly visible when I plot the values
Of course my code could be wrong as well, it almost looks like it's barely subtracting the values out at all. Maybe I'm chasing a red herring here and the issue is something else.
Yeah that's pretty much what I'm doing, but I'm beginning to suspect the problem is something else, like not indexing the array properly or something.
The cool thing about doing autocorellation in the time domain is that, on top of it being fast to compute, tracking is pretty much instantaneous, down to a half-cycle or so. It's that accurate and precise tracking that enables the pitch shifting portion to be dead-simple and avoid getting into stuff like PSOLA etc.
At some point it occurred to me that I may be off by one or something silly like that in my array indexing, so on a whim I increased my delay buffer size 50x, which reduced my error by 50x. Lesson learned: superstitiously add 1 to however many indices I think an array needs.
NI Form uses PSOLA.
Great for some things, but really alters some sounds.
So the thing about PSOLA is that it smudges and colors the sound a lot. The AT patent says that the "overlap" part is not necessary; just advance the delay read head if we're flat, and retard it if we're sharp. And if we run out of room? We know exactly how long one cycle is, so just jump back by that many samples. No multiply-adds, no spectral voodoo magic, dead simple. Definitely a hell of a lot simpler than the "phase vocoder" approach I sometimes see being associated with autotune.