For a project I am attempting to create an automatic tuner for a guitar, which reads the audio from the guitar jack, determines the frequency and adjusts the string by a motor.
Using http://www.instructables.com/id/Reliable-Frequency-Detection-Using-DSP-Techniques/ the algorithm is quite accurate.
void setup() {
sum = 0;
pd_state = 0;
int period = 0;
// Autocorrelation
for(i=0; i < samples; i++)
{
sum_old = sum;
sum = 0;
for(k=0; k < samples-i; k++) sum += (values[k])*(values[k+i]);
// Peak Detect State Machine
if (pd_state == 2 && (sum-sum_old) <=0)
{
period = i;
pd_state = 3;
}
if (pd_state == 1 && (sum > thresh) && (sum-sum_old) > 0) pd_state = 2;
if (!i) {
thresh = sum * 0.5;
pd_state = 1;
}
}
// Frequency identified in Hz
freq_per = realFreq/period;
lcd.cls();
lcd.printf("%f",freq_per);
}
At the end the frequency is determined by the by dividing the realFreq, which is the precise reading frequency with the period determined by the peak detection portion.
The frequency is quite accurate between 40-200 Hz normally about 0.5 Hz out which is accurate enough for my needs. But above 200 Hz the accuracy falls to 2-3Hz.
Is there a technique to improve the accuracy of this function. The sampling frequency is 4410 and I wanted to reduce this to improve the speed but keep the accuracy as high as possible.
Thank you.