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
Users are reminded of the forum rules they sign up to which prohibits any activity that violates any laws including posting material covered by copyright
Autocorrelator pitch detection
5 posts
• Page 1 of 1
Autocorrelator pitch detection
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...
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 1118 times
- KG_is_back
- Posts: 1196
- Joined: Tue Oct 22, 2013 5:43 pm
- Location: Slovakia
Re: Autocorrelator pitch detection
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.
-
martinvicanek - Posts: 1328
- Joined: Sat Jun 22, 2013 8:28 pm
Re: Autocorrelator pitch detection
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.
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
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:
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.
- 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
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.
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 1176 times
- KG_is_back
- Posts: 1196
- Joined: Tue Oct 22, 2013 5:43 pm
- Location: Slovakia
5 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 36 guests