Thursday, August 17, 2006

On holidays and tuner tool

Hi friends,

I'm on holidays this days and I've restricted access to my computer, my wife don't let me play on it until September :)

During first week on September I believe that I'll be able to do some improvements on the tuner tool that has been suggested to me on comments and by mail.

This is a summary about the changes that I plan to do:

- Enlarge the text that reports the tone played as Tor-björn asked for.
- Add an autoplay func for guitar notes: "Play the six guitar strings in sequence, allow each string/tone to play for a configurable length of time, then play the next string/tone, ie: e-e-e-e-e a-a-a-a-a d-d-d-d-d g-g-g-g b-b-b-b-b e-e-e-e repeat" as Chris Warren-Smith suggested.
- Add a pair of buttons to let change octaves on the piano func.

About how improve the FFT and add better sensivity under 400 hz frequencies, I'm reallyy novice in this area and mainly I began this project as way to learn about gstreamer and N770 multimedia API. I chosen KISS FFT lib because it's easy to use and fourier transform can be calculated using fixed point integers, that's good for N770 which haven't FPU. If someone has a good idea about which improvements can be done on this area I'm able to write the code and testing it but by now I have a lack of info about what should be done.

Sometimes I'm in IRC channels at freenode, #maemo and #gstreamer, with nick ArthurDentN770 we can talk about if you want.

10 comments:

aki said...

i'm not familiar with your code or your program very well but a friend of mine demonstrated it in a bar and told me of your question about improving the fft resolution on low frequencies.

you can really improve fft resolution only by using more data and taking a longer fft. to get 1hz resolution you need one seconds worth of samples and there is really no way around it. this is probablly not what you want to do because with 1hz resolution the analyzers display would consequently lag about 1 second behind real-life no matter what tricks you play.

but you are not seeking resolution in the sense that you want to distinguish between a case where you have one sine at 441hz and another at 439hz from the case where you have a single sine with twice the amplitude at 440hz because for the ear it doesn't matter. the former case is just an amplitude modulated version of the latter and just as valid A4 as the latter. with this in mind you can play a trick called zero padding, which is mind-bogglingly simple. you append or prepend (it makes no difference which you do) your actual samples with zero samples and then take a long fft. if your samplerate is 8192hz and you want 1hz accuracy in pinpointing a fundamental frequency while having a lag of 1/8 second, you take 1024 samples, add 7168 zeros and take a 8192 point fft. it should really work. of course it sounds very wasteful because such accuracy is useless in the higher frequencies, but if you want to use fft for the work, this is what you get.

if you don't want zero-padding you can select a set of frequency bins arbitrarily and do discrete fourier transforms to get exactly the samples you need, but this is certainly going to execute slower than the zero padding approach (fft is O(n*log(n)), dft is O(n*n))

aki said...

hmm, it seems i got the problem completely wrong. the problem is not with the time/accuracy tradeoff but with the low frequencies getting lower amplitudes than their upper harmonics do. fft is not to blame for this as it does not lose information. if you determine the fundamental frequency by finding the frequency with highest amplitude you can increase sensitivity for low frequencies simply by multiplying the low frequencies in the spectrum by a value > 1, or by dividing the high frequencies with it (better because it avoids overflow problems, worse because it hurts sensitivity on the higher frequencies). you can incorporate this directly in the loop which finds the maximum. it's probably also wise to use a nicely increasing function instead of a constant value for generating the divisors to avoid strange corner cases.

a way to get rid of this problem for good would be to change the method for finding the fundamental frequency so that you first find all the local maximums (all "peaks" in the spectrum), then assume all the peaks are harmonics of the fundamental frequency. the fundamental frequency is then the greatest common divisor of the maximums, or if you assume all the harmonics are present, just the distance between any two consecutive local maximums. this way you should be able to find fundamental frequencies much below the mic cutoff frequency.

the biggest problem with the gcd approach is of course that it fails to find a fundamental frequency if some of the harmonics go off by few frequency bin, as they probably usually do. the fix for this is to replace gcd with an algorithm that finds the maximum value for which average of the remainders of the divisions is below some threshold.

i hope at least some of this is useful..

Anonymous said...

Nice site!
My homepage | Please visit

Morten said...

Hi
I really like the Tuner Tool and have some improvements ideas for you:
Add a method to stop the Nokia 770 to turn of the screen after x minutes. This is fairly easy - have a look at osso_display_blanking_pause

I think there is a bug somewhere in your code or in the Maemo framework. When I use Tuner Tool the application will quit by itself after approximately 20 minutes.

9a6or said...

I am (re-)learning to play the guitar (Christmas present) and so I use your Tuner tool quite often! Nice job.

Gabor from UK

Anonymous said...

This installs on N800, but it doesn't start up. When I run it in xterm, it outputs one Gobject CRITICAL, two Gstreamer CRITICALs
and exits.

Eduard said...

Hi there,
I am very interested in how you used the kissFFT library to perform a fixed-point fft for the N800. Only replacing the global "double" datatype wtih "short" in kissfft.h doesn't seem to be enough.
Maybe you have an short example?

Jep said...

You can read in source code at Makefile.am. CFLAGS=-DFIXED_POINT=16.

Anonymous said...

This is an interesting tool to me. I'm not particularly interested in using a 770 as a guitar tuner, but as a music composition tool, I think it could be something quite useful. It excites me that your utility seems to be the closest to something such as that for the 770.

How likely do you think it is that a tool such as yours or a similar tool could progress into a music composition tool? Do you think we are likely to ever see a music sequencing tool for the 770?

There are several tools for palm os, so I am hopeful for the 770.

Stephen said...

Look into denemo for music composition. Just installed it. Haven't finished reading the docs. But did enter 'Twinkle', and had it play back. Can print, and print to pdf, can export to lilypond.