Reputation: 63672
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];
Upvotes: 20
Views: 16833
Reputation: 210
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);
}
Upvotes: 1
Reputation: 19329
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).
noteNumber % 12
.Upvotes: 2
Reputation: 20824
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 of
60
to the string C5
getToneStringWithoutOctave(byte noteValue)
converts a value of 60
to the string C
getPercussionString(byte noteValue)
converts a
value of 60
to the string "[AGOGO]"
These replace the original getStringForNote()
method.
Upvotes: 4
Reputation: 881403
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);
}
}
}
Upvotes: 20