Closed glaurent closed 8 years ago
Yes I've been mainly using a piano to test this, and I think once I get to around G3 or lower it's not detecting properly. It either thinks it's an octave higher or an octave and a fifth higher. That means it's detecting the first or second partial in the harmonic overtone series instead of the fundamental, but I don't know enough about the inner workings of the code as to why it's picking that up. I even cycled through the different sounds on my digital piano and had more or less the same results.
@glaurent It is actually an issue that ideally should be solved. The main reason is that FFT is not very efficient when it has to detect the pitch of signals with missing fundamentals. As I know autocorrelation can give better results, and it should be possible to calculate it using FFT as well. There are also some algorithms based on autocorrelation, for example, the YIN algorithm, The McLeod Pitch Method (MPM).
Actually I'm trying to implement the YIN algorithm (see YINalgorithm branch on my fork of your repository - which also contains the Swift3 port of GuitarTuner), but either my implementation is buggy (highly likely) or the algorithm is not that efficient because I'm not getting exploitable results out of it.
I tried YIN before the initial release of this library and didn't get any exploitable results neither.
But I would guess the algorithm itself should work, so most likely the problem is hidden somewhere in implementation.
Any chance you could either commit your code or mail it to me, so I can compare implementations and try to find what's wrong ?
@glaurent Unfortunately I'm not able to find this code, I think it was in some sort of local experimental branch that has been deleted. I can play with your implementation or try other algorithms when I get some time. But I don't promise it's gonna be during this week.
Thanks a lot. I'll keep investigating and try to find what's going on. For one thing, I've realized I probably should apply a Hamm window (just learned about this a few days ago :-D ) on before computation, which is something the implementation I've used as reference doesn't do. But I figure that would partially explain the widely fluctuating results I get.
I've just implemented another version of the difference() function and am having much better results, except for some octave errors, and sometimes a negative frequency. This version of the function is slower (not relying on the Accelerate framework), but at least it points me to the location of the problem.
Having finally solved all the issues, I've just created a pullreq for my implementation of YIN. It seems to works pretty well :).
(Not really an issue)
From my "real-world" tests, the default configuration works very well with an electric guitar plugged in an amp with no effects. However, I tried with a acoustic one, and while pitch detection is still accurate for the higher strings, it's consistently wrong with the lower ones (open low E is detected as B3, open A is E4...). Do you have any pointers to other pitch detection algorithms that would be worth looking into ? I've already skimmed through the wikipedia page.
(add: the Fender Tune app works perfectly with that same guitar).