Old 01-12-2021, 06:43 PM   #1
noouch
Human being with feelings
 
Join Date: Aug 2008
Posts: 37
Default JSFX Autocorellation

*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?

Last edited by noouch; 01-14-2021 at 12:37 AM.
noouch is offline   Reply With Quote
Old 01-13-2021, 12:36 AM   #2
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 10,226
Default

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.

-Michael

Last edited by mschnell; 01-13-2021 at 08:37 AM.
mschnell is online now   Reply With Quote
Old 01-13-2021, 06:22 AM   #3
jrk
Human being with feelings
 
Join Date: Aug 2015
Posts: 1,569
Default

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...
jrk is offline   Reply With Quote
Old 01-13-2021, 07:34 AM   #4
jrk
Human being with feelings
 
Join Date: Aug 2015
Posts: 1,569
Default

I'm gonna be "that guy" (again)...what kind of "certain timespan" are you thinking of? What's your aim with this?

Have you considered the (cheap to compute) exponential moving average?
(2x multiply and 1 addition per sample)
__________________
it's meant to sound like that...

Last edited by jrk; 01-13-2021 at 08:57 AM.
jrk is offline   Reply With Quote
Old 01-13-2021, 01:43 PM   #5
noouch
Human being with feelings
 
Join Date: Aug 2008
Posts: 37
Default

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.

Last edited by noouch; 01-13-2021 at 02:01 PM.
noouch is offline   Reply With Quote
Old 01-13-2021, 03:25 PM   #6
jrk
Human being with feelings
 
Join Date: Aug 2015
Posts: 1,569
Default

Oh, well, I've never done anything like that... I gather fft is a (computationally heavy?) of getting autocorrelation.

Have you seen JS: FFT Peak-Following Filter?

As far as a simple moving average goes, I've got something like this, which was for a jsfx compressor that I never finished.

the circular buffer (array) remembers scaled values. It has LENGTH slots.

Code:
@sample 
new_value = abs(spl0);


sample_count += 1;
idx = sample_count % LENGTH;

avg -= array[idx];
avg += new_value / LENGTH;

array[idx] = new_value / LENGTH;
__________________
it's meant to sound like that...

Last edited by jrk; 01-13-2021 at 03:41 PM.
jrk is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 05:34 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, vBulletin Solutions Inc.