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?
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