1

In my project I want to be able to at least inform the user what string the note they need to play is on. I can get the note and its octave but as I've discovered, that note and its octave can appear in multiple places on a guitar fret board.

So my question is: Is there anyway to map a midi note to a guitar string?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
JavaTime
  • 15
  • 6

3 Answers3

3

Here's code that takes the MIDI note value and returns the position on the guitar fretboard closest to the end of the instrument. Fret zero is an open string.

static class Fingering {
    int string;
    int fret;

    public String toString() {
        return "String : " + stringNames[string] + ", fret : " + fret;
    }
}

static String[] stringNames = new String[] {"Low E", "A", "D", "G", "B", "High E"}; 

    /** Array showing guitar string's relative pitches, in semi-tones, with "0" being low E */
static int[] strings = new int[]{64, 69, 74, 79, 83, 88};



public static Fingering getIdealFingering(int note) {
            if (note < strings[0])
                throw new RuntimeException("Note " + note + " is not playable on a guitar in standard tuning.");

    Fingering result = new Fingering();

    int idealString = 0;
    for (int x = 1; x < strings.length; x++) {
        if (note < strings[x])
            break;
        idealString = x; 
    }

    result.string = idealString;
    result.fret = note - strings[idealString];

    return result;
}

public static void main(String[] args) {
    System.out.println(getIdealFingering(64));  // Low E
    System.out.println(getIdealFingering(66));  // F#
    System.out.println(getIdealFingering(72));  // C on A string
    System.out.println(getIdealFingering(76));  // E on D string
    System.out.println(getIdealFingering(88));  // guitar's high e string, open
    System.out.println(getIdealFingering(100)); // high E, 12th fret
    System.out.println(getIdealFingering(103)); // high G
}

Result:

String : Low E, fret : 0
String : Low E, fret : 2
String : A, fret : 3
String : D, fret : 2
String : High E, fret : 0
String : High E, fret : 12
String : High E, fret : 15
cutchin
  • 1,177
  • 1
  • 8
  • 12
  • Would this work with sharp notes as well, and is the input to getIdealFingering the midi note number? – JavaTime Feb 19 '12 at 20:42
  • I rewrote it to use MIDI note numbers. It supports sharps or flats just fine. It's up to your app to figure out if a given note number is sharp or flat, this just thinks in semitones (or half steps, if you prefer). – cutchin Feb 19 '12 at 20:54
  • That seems to be great, thanks. Have you got a reference for the midi note to guitar map. The one I have seems to contradict the output of your program. Such as the C on A string, as a midi note it is C octave 5, but the output of your program gives where C octave 3 should be on a guitar. – JavaTime Feb 19 '12 at 21:07
  • I just double checked and I was off by an octave. I should have used 52 as the base, not 64. You would just need to subtract 12 from every item in the strings[] array. If your reference says I am 24 notes off, I am not sure. You might want to sit down with a guitar and a MIDI keyboard and see exactly how it all lines up. Either way, it's just a matter of adjusting the strings[] array. – cutchin Feb 19 '12 at 21:24
  • Don't worry I fixed it, ahh yeah noticed before I saw your comment. Well this little piece of code is brilliant. Thank you so much, works perfectly!!! I recommend this highly!!! – JavaTime Feb 19 '12 at 21:27
0

Yes, with simple logic you can do this. I would consider using a HashMap of <Note, MidiNote> where Note is your class that holds both relative note and octave and has decent equals and hashcode methods, and MidiNote is your class to represent a Midi note.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • But that doesn't solve my problem, I can't map a midi note to a guitar string because that note could be anywhere on the guitar - even while knowing it's octave number. For example E4 (E octave 4) appears on a guitar fret board 4 times (5 including open e on 1st string). – JavaTime Feb 19 '12 at 20:07
  • 1
    Yes you can use this to solve your problem. A guitar note is simply the base note incremented by the fret position. All you have to do is give your Note class a decent increment method, one that increments the note intelligently -- that knows to increase the octave once A-flat has been passed (or wherever the boundaries are ??C perhaps??) and then do simple math. It's nothing more than basic logic. – Hovercraft Full Of Eels Feb 19 '12 at 20:18
0

Think of MIDI as like defining piano keys. Codes and keys are one-to-one. This is unlike a guitar or violin, where the same tone can be played in multiple places.

If you want to represent the greater freedom you have on a guitar in some data format, you'll have to find or invent a different format. MIDI won't encode what you want.

However, there's an indirect way you might go about this, and it has to do with developing heuristics as to where to play a note given a sliding window of notes that came before. A given note may be easier on one string or another depending on what you've just played, and you can calculate that given a model of the hand and where fingers will have been. Based on this, you can convert MIDI to guitar in a way that makes the MIDI easiest to play. If you have a piece of guitar music that follows these rules already, then you can encode it in MIDI and then decode it later.

But perhaps your question is more basic. Yes, you can map a MIDI note to a guitar. The naive method is to make a mapping of each note playable on the guitar, and you decide between equivalent alternatives by picking the one closest to the nut. This would be an easy one-to-one mapping but wouldn't necessarily be the easiest to play.

If you REALLY want to do it right, you'll do a careful analysis of the music to decide the optimal hand position and where the hand position should change, and then you'd associate MIDI notes with frets and strings based on what's easiest to reach based on the hand position. The optimal solution is probably NP-complete or worse, do you'd probably want to develop an approximate solution based on some rules about how often and how far you can change hand position.

Timothy Miller
  • 1,527
  • 4
  • 28
  • 48
  • yeah, I thought it would be something like this. Funny enough, there is someone else in my year doing this in great depth, but mine doesn't need to be truly accurate I believe, so the one to one mapping maybe the road for me. – JavaTime Feb 19 '12 at 20:51