Support

If you have a problem or need to report a bug please email : support@dsprobotics.com

There are 3 sections to this support area:

DOWNLOADS: access to product manuals, support files and drivers

HELP & INFORMATION: tutorials and example files for learning or finding pre-made modules for your projects

USER FORUMS: meet with other users and exchange ideas, you can also get help and assistance here

NEW REGISTRATIONS - please contact us if you wish to register on the forum

Autocorrelator pitch detection

Post any examples or modules that you want to share here

Autocorrelator pitch detection

Postby KG_is_back » Fri Jul 25, 2014 11:59 am

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 1030 times
KG_is_back
 
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Autocorrelator pitch detection

Postby martinvicanek » Sat Jul 26, 2014 7:20 am

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. :)
User avatar
martinvicanek
 
Posts: 1318
Joined: Sat Jun 22, 2013 8:28 pm

Re: Autocorrelator pitch detection

Postby tester » Sun Jul 27, 2014 11:13 am

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.
tester
 
Posts: 1786
Joined: Wed Jan 18, 2012 10:52 pm
Location: Poland, internet

Re: Autocorrelator pitch detection

Postby KG_is_back » Sun Jul 27, 2014 3:03 pm

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

Postby KG_is_back » Mon Jul 28, 2014 7:33 pm

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 1083 times
KG_is_back
 
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia


Return to User Examples

Who is online

Users browsing this forum: No registered users and 14 guests

cron