Reputation: 47
I have built an app that takes input from the microphone of my phone and calculates the frequency. I am using the Jtransform library to calculate the FFT and thus the frequency.
I have followed previous questions on this matter and this is the method I have chosen:
sampleSize = 1024
sampleRate = 8000
audioData is the array I have filled with mic input
fft.complexForward(audioData)
This method calculates the fft, storing the real and imaginary numbers in sequence
re[] = real number array
im[] = imaginary number array
magnitude[i] = math.sqrt((re[i]*re[i])+(im[i]*im[i]))
I then get the largest magnitude/peak
Frequency = sampleRate * peak/sampleSize
Now This number changes rapidly, not even staying constant (though staying within a range) on a sustained note (my whistling/guitar string)
I have an array of known guitar string frequencies (Open E string being 82.407 hz). Since the calculated fluctuates so many times a second, I cannot compare these at all as it goes in and out of bounds.
Is there a method that can be applied to this problem to get a more steady frequency? Or is this the correct way to get the frequency of a guitar string?
Thank you
Upvotes: 0
Views: 344
Reputation: 70673
Peak magnitude of an FFT result is not the correct way to determine guitar pitch frequency.
Musical pitch is a human psychoacoustic phenomena, and often very different from spectral peak frequency. For reliable results, you will need to use a pitch detection or estimation method, not a peak frequency estimator. Such pitch estimation methods include weighted autocorrelation and similar lag evaluators, cepstrum/cepstral methods, harmonic product spectrum, and composite algorithms such as RAPT and YAAPT. Etc. There are lots of research papers on pitch estimation methods.
Upvotes: 0
Reputation: 1200
Option 1: Use a longer sampling window (increase the sample size).
Option 2: Store a ring-buffer containing multiple results and display the average of all the values in the ring buffer. A ring buffer is a buffer of some fixed length that you use to store your results where each new result is written to the next location until the buffer is full, at which time you overwrite the first value in the buffer.
Upvotes: 1