Convert Midi Note Numbers To Name and Octave
Solution 1
I'm not convinced your suggestion is that tedious. It's really just a divide-and-modulo operation, one gets the octave, the other gets the note.
octave = int (notenum / 12) - 1;
note = substring("C C#D D#E F F#G G#A A#B ",(notenum % 12) * 2, 2);
In real Java, as opposed to that pseudo-code above, you can use something like:
public class Notes {
public static void main(String [] args) {
String notes = "C C#D D#E F F#G G#A A#B ";
int octv;
String nt;
for (int noteNum = 0; noteNum < 128; noteNum++) {
octv = noteNum / 12 - 1;
nt = notes.substring((noteNum % 12) * 2, (noteNum % 12) * 2 + 2);
System.out.println("Note # " + noteNum + " = octave " + octv + ", note " + nt);
}
}
}
Solution 2
In JFugue, the Note
class has a utility method that does exactly this - see public static String getStringForNote(byte noteValue)
.
EDIT: As of JFugue 5.0 and later, the Note
class has several utility methods for getting a string representation from a MIDI note value:
-
getToneString(byte noteValue)
converts a value of60
to the stringC5
-
getToneStringWithoutOctave(byte noteValue)
converts a value of60
to the stringC
-
getPercussionString(byte noteValue)
converts a value of60
to the string"[AGOGO]"
These replace the original getStringForNote()
method.
Solution 3
public static String getNoteName(int noteNumber){
noteNumber -= 21; // see the explanation below.
String[] notes = new String[] {"A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"};
int octave = noteNumber / 12 + 1;
String name = notes[noteNumber % 12];
return name + octave;
}
Explanation:
A0 in midi is the first note and its number is 21. We adjust the index to start from 0 (hence
noteNumber -= 21;
at the beginning). If your note numbers are 0 based, for example in piano from 0 to 88, then you can comment this line out.Note that in this solution, the note names in the array start from A to G.
Octave is
noteNumber / 12 + 1
(Or ceiling of num / 12).- Note name index is
noteNumber % 12
.
Solution 4
This is the shortest form without too many named constants. No need for any loops as well.
public static String getNoteFromMidiNumber(int midiNote){
String[] note_names = {"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};
return note_names[midiNote % 12] + ((midiNote / 12) - 1);
}
Related videos on Youtube
Jonathan Holloway
Consultant CTO and Architect with expertise in Java, Python, Ruby and Javascript http://www.jonathanholloway.co.uk/
Updated on October 18, 2020Comments
-
Jonathan Holloway over 3 years
Does anybody know of anything that exists in the Java world to map midi note numbers to specific note names and octave numbers. For example, see the reference table:
http://www.harmony-central.com/MIDI/Doc/table2.html
I want to map a midi note number 60 to it's corresponding note name (MiddleC) in octave 4. I could write a utility class/enum for this, but it would be rather tedious. Does anybody know of anything?
I'm specifically using this to write a Tenori-On/Monome clone in Java, so far so good...
Solution
This was what I ended up using:
String[] noteString = new String[] { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; int octave = (initialNote / 12) - 1; int noteIndex = (initialNote % 12); String note = noteString[noteIndex];
-
paxdiablo over 15 yearsJon, I added some real Java to my answer.
-
Jonathan Holloway over 15 yearsawesome, thanks for the pointers...
-
-
Smashery over 15 yearsPerhaps Jon was thinking of creating an enum for every single note+octave combination?
-
Jonathan Holloway over 15 yearsThat was the initial crazy suggestion. I was looking for the algorithm... I'm sure I can work something out given this, I don't think it's valid in Java... shouldn't take long to translate...
-
David Elson almost 9 yearsAlso, perhaps one might hope for an intrinsic com.<whatever>.Midi, that "ships" with Java, that contains such a method. However, it would still leave unresolved whether to call a note (61?) C# or Db. If one had a key signature, one could resolve that (for many cases) according to key signature. I.e., for the key of B, it would b C#. For the key of Gb it would be Db.
-
paxdiablo almost 8 yearsInteresting. It looks like jFugue 5 no longer has
org.jfugue.Note
. It hasorg.jfugue.theory.Note
but that one appears not to have thegetStringForNote
method. Not sure why people decide to take away useful functionality (especially since the cost of it wasn't that high) though it may be they're moved it somewhere else, not that I could find it though :-) -
David Koelle almost 8 yearsActually, the new Note class has several more utility functions than the older version. The new getStringForNote is getToneString(byte noteValue) - for a value of 60, this would return "C5". There is now also getToneStringWithoutOctave(byte noteValue), which will return "C" for 60. You can also find getPercussionString(byte noteValue), which for 60 will return "[AGOGO]". The new methods are richer than the originals, and required new function names to clarify their purpose.
-
LuaStart about 5 yearsI need to do the same in Lua but from note name and octave to note number.
-
Cerin about 4 yearsThis is wrong. If given 69, (the number for A4), your code returns A5. The octave calculation is off.
-
col000r almost 4 yearsWorks great once you fix one error: the octave has to be calculated from the original noteNumber before you adjust down by 21. - So move the line with the octave to the top and it works beautifully!