A 5K Java Guitar Tuner

So after writing a 5K Twitter Client, a 5K TODO app and a 5K Fullscreen Text Editor I thought that’d be enough example apps to get things started. However while adding a list of app ideas to the 5K App page I suddenly decide that one of the ideas really appealed. The idea was to write a guitar tuner, that would listen on the computers mic and show the user what pitch it thought the note played was. I’m not much of a guitar player, but when I do play it’s always nice to have a guitar that’s in tune. As I’m unable to tune a guitar by ear I rely on guitar tuners and I always seem to be out of the 9V batteries my electronic tuner needs. Given my laptop is usually nearby, being able to use it as a guitar tuner would be most useful.

Check out the video below or download 5KTuner for yourself (requires Java):



The app is more or less non-interactive. It simply starts up tries to work out what note is being played. It shows a simple slider that moves according to what note is being played and indicates how close to that note you are. In addition the raw frequency (in hz) is shown, as well a chart that shows the autocorrelation function of the input sound. A red line is drawn on this chart when a “valid” note is heard and indicates the wavelength of the overall frequency.

The vital statistics are:

  • Final (obfuscated) app size: 3538 bytes
  • Final (un-obfuscated) app size: 4649 bytes
  • Final Source-code size: 8532 bytes
  • Lines of code: 245

This was my first foray into audio programming and I’m grateful that in the end it wasn’t too tricky. Initially I’d been looking into using the Fast Fourier Transform to work out the frequencies, but the autocorrelation function was much easier. It’s essentially just two for loops and a bit of maths. You listen for a certain amount of audio and then compare the first half of the sample with itself, but shifted. By working out the amount of shift where the difference is smallest you can find the overall frequency of the sample.

It could probably be made more robust, but if you want to see how it works (or improve it) you can download the source code.

21 Responses to “A 5K Java Guitar Tuner”

  1. Alex Holsgrove

    Hi John

    This is a great little app – and it seems to run a lot faster than some of the ones using the FFT method.

    What I would like to ask you, is would it be possible to get this running on a web browser? I am looking to get something like this on a guitar website I am putting together?

    I am proficient in web languages, but Java is toally new to me. My only real programming experence is some VB and C++ a few years back.

    Would you be able to help me out? I will of course sing your praises over the new website :)

    All the best,

    Alex Holsgrove

  2. john

    Hi Alex,

    Glad you like the app. It’s really just a knock-around thing, but it might be possible to get it running in a web browser. There are two options:

    • Java Applet
    • Java Webstart

    They both have constraints on what kind of things you can do. I’m not sure whether one can access the microphone from a java applet (as it may be outside of the security sandbox), but I imagine it’s possible with Java webstart.

    You’re certainly welcome to take the source and do what you want with it – consider the code as in the public domain. Though some level of attribution would be nice. I might have a go at getting it turned into a webstart app, but can’t promise any sort of timescale on that – plenty to be getting on with at work and otherwise.

    cheers,

    John

  3. Alex Holsgrove

    Hi John, thanks for the reply.
    I am sure it’s possible to access the system sound as I have seen a similar application here: http://www.seventhstring.com/tuner/tuner.html
    It’s a bit over the top, but proves that it can be done.

    I can appreciate you having a lack of time to build the web version – I know that feeling all to well.
    If you do make any progress, I’d love to hear for you [webmaster at blind-summit.co.uk]
    Thanks again for making the source available.

    Alex

  4. mikronator

    John !
    I thank you very much.. I was looking a simple way to analyze notes from sound and you just handed it to me on a golden plate.

    I was so frustrated of trying to figure out how to use the FFT and what the hell is a complex number (I’m no mathematician that’s for sure ;)

    Thank you,
    and have a good day,
    Mikronator from Israel

  5. Tony

    Great application John! Very well done here.

    Are you able to provide me with an email address I can use to contact you on? Would like to request permission to make ues of your code in a non-commercial application I’m developing.

    Thank you

  6. jun :: realeyes » Blog Archive » Make Some Noise! Creating an analog audio controller with Merapi and AIR

    [...] I could have used FFT, I based the frequency analyzer on this Java-based guitar tuner app I found online. It was a much simpler solution for my needs. Thanks John [...]

  7. Mike

    Hi John,

    This is a great little app, its helped me a lot to understand frequency analysis. Do you know if the autocorrelation function can be used to analyse the amplitude as well?

    Cheers,

    Mike

  8. john

    Hi Mike,

    well the amplitudes are already present in the original data. The auto-correlation function is trying to take a set of amplitudes and work out their frequency. Analysing the amplitudes should be much more straightforward…

    John

  9. Mike

    Hi John,

    Do you know how I can extract the amplitudes from the original data? I’m a bit of a novice at signal processing. Any help you can give will be much appreciated.

    Thanks,

    Mike

  10. john

    Hi Mike,

    the actual data being read by the call to targetDataLine.read in the code just represents the pressure at a given point in time (so it’s actually the pressure on the microphone at that instance converted to a voltage). The raw data is just a bunch of bytes, so if you us a 16bit sample size (as my code does) you need to join every pair of bytes together to give you one pressure value. That’s the bit with the comment “convert two bytes into single value”.

    From there for example, the amplitude of the overall sample can then be worked out by just finding the difference between the highest and lowest values.

    Be aware though, this was my first audio programming experience, so you’ll want to double-check everything…

    cheers,

    John

  11. corly

    Great post!
    Do you think i can turn my tuner ( http://www.gcourses.com/?page_id=147 ) which already got a large file size to a tuern like yours, without making it bigger?
    Thanks!

  12. john

    @corly – I wouldn’t worry about the size too much. Your tuner seemed to load up fast enough. Though, as yours is in Flash you’ll need to wait for the latest version to come out. At the moment the current version can’t access the microphone, but that’s set to change with the new version.

  13. Kadir

    Hi John,

    i am doing a project for my studies and i needed some code to get the frequency out of the mic. so i found your tuner which helped me a lot, but there’s one little thing i have to get rid of though: theres always a delay of about half a second. could you tell me how i could do that. i can send you my project if it helps. thanks in advance

  14. john

    Hi Kadir,

    there is an artificial delay that I introduced to stop the app chewing up 100% CPU, so maybe start by removing/reducing that. Look at line 241 in GT.java and you should see a call to Thread.sleep() being passed a value of 250ms (quarter of a second).

    John

  15. Kadir

    Hi John,

    thanks. i am ashamed of myself to have not seen that one :)

  16. James Murphy

    Hi

    I’m new to java, what did you use to compile the jar program?
    Also would this work on a mobile, this is my eventual aim.

    Thanks

  17. john

    Hi James,

    I just manually compiled it using javac, then ran it through the jar command. There’s a build.sh script with with source code for compiling it – which I think contains an obfuscation step too.

    In principle you could adapt this to work on mobile – assuming you can access the microphone. However this really isn’t a very efficient way of pitch detection. For that you probably need to look at something like the “Fast Fourier Transform”, but that’s quite a bit more complex.

    John

  18. Josh

    Hi John,
    I found your code to this and found it to be extremely helpful for a project I am doing for a class. My project is a game-like program that will listen to guitar input and compare it to what is supposed to be played. Could I have permission to use your code and do you have any ideas on my project?

    Thanks!

  19. john

    Hi Josh,

    there’s some license info over here to look at:

    http://www.psychicorigami.com/license/

    Basically yep, you can use it, just make sure you give me some attribution.

    You may find though, that you will need to use the Fast-Fourier Transform to get your app working efficiently. However the correlation technique in my code will at least let you get started.

    cheers,

    John

  20. Online AS3 Guitar Tuner « Prlwytzkofsky

    [...] example code for an online Guitar Tuner, I came upon the very efficient Java 5Ktuner on Psychic Origami. All I had to do was convert it to Actionscript. The Flash AS3 version works great – thanks [...]

  21. Robin van Emden

    Hi John,
    Thank you for making the source code available! Needed an AS3 version and was able to convert your Java tuner into Flash Actionscript without much difficulty:
    http://prlwytzkofsky.com/online-as3-guitar-tuner/

Leave a Reply