Autocorrelator pitch detection

Post any examples or modules that you want to share here
Post Reply
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Autocorrelator pitch detection

Post by KG_is_back »

I have made an Autocorrelator to detect period of a signal. First it writes data into circular buffer. Then multiplies each value in given range with input and lowpasses that (for each value in range). Finely it finds maximum lowpassed value and interpolates the subsample element from neighbor values. Output is the period of the input signal.

Note, it eats CPU for breakfast, launch and dinner. Bigger range you give it, with lower base note, higher the array of samples for computation will be. It can easily reach 100% cpu. Some computation time might be saved using hop and using SSE support. I may add that later...
Attachments
pitch detection.fsm
(4.98 KiB) Downloaded 1190 times
User avatar
martinvicanek
Posts: 1334
Joined: Sat Jun 22, 2013 8:28 pm

Re: Autocorrelator pitch detection

Post by martinvicanek »

Nice! I tried it with a guitar and it worked quite well in the specified range. It does have a latency which is sometimes a bit unpredictable. Yes, it is quite CPU hungry as it is. Apart from SSE and hopping you could try to evaluate the autocorrelation for fewer lag values and then interpolate. Maybe that's already in your code, I haven't checked. I really like the compact implementation, it is all neatly stuffed in one ASM. :)
tester
Posts: 1786
Joined: Wed Jan 18, 2012 10:52 pm
Location: Poland, internet

Re: Autocorrelator pitch detection

Post by tester »

Looking forward for developments in this one as well. Thanks.
Need to take a break? I have something right for you.
Feel free to donate. Thank you for your contribution.
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Autocorrelator pitch detection

Post by KG_is_back »

The problem is, I can't use SSE instructions per sample, because arrays and movaps xmm0,array[eax]; behaves slightly limited. Both with fld array[eax]; and movaps xmm0,array[eax]; the code crashes if you try to read a value "shifted wrong." to explain the problem:

Code: Select all

float array[10];

mov eax,4;
fld array[eax]; //this will read a value at second bin, because address reference is in bytes and one float is 4 bytes

mov eax,3;
fld array[eax]; //this will crash, because you are trying to read values offset relative to the pointer.

mov eax,16;
movaps xmm0,array[eax]; //the same stands for movaps when moving packed values. Packed value is in this case considered a single value (although it contains 4 floats) therefore...
mov eax,4;
movaps xmm0,array[eax]; //this will not work, because movaps works in multiples of 16bytes.


That complicates reading packed values from the buffer each sample, because 3 of 4 samples the starting point is wrong. Solution is, that I will use fld for reading from buffer and movaps for reading and writing awrg array (which accumulates lowpassed correlation values for each period) and finding maximum with sse.
Also I might enable downsampling (hop in the assembler block and a lowpass filter in front of it for antialiasing) to trade precision for performance.
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Autocorrelator pitch detection

Post by KG_is_back »

Ok... I partially implemented SSE optimization (reduced CPU by 50%) and also downsampling (acually a hop for pitch calculation - might have to add a dawnsampling lowpass before the detector, to prevent aliasing) which led me reduce CPU downto 10% on my machine (which is probably the CPU load of the whole schematic except for the loop).
Also added a knob which lets you control lowpass coefficient of the averaging accumulator array (the one that contains lowpassed versions of correlations for each delay).
As expected the thing has some problems with octave jumping - sometimes detects double/triple period = 12/15 semitones down. I've tested it with only simple osc, which do not change over time. with changing signal this problem might be reduced to minimum.
Attachments
pitch detection.fsm
(14.95 KiB) Downloaded 1247 times
Post Reply