Search code examples
javaalgorithmmididata-conversion

Converting musical note Strings to MIDI pitch number


I have written the following method to convert notes (with the octave appended to the end) to the corresponding MIDI pitch:

// Converts a note string (MUST HAVE OCTAVE) to an integer pitch.
public static int convertToPitch(String note) {
    String sym = "";
    int oct = 0;

    String[] notes = { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" };

    char[] splitNote = note.toCharArray();

    // If the length is two, then grab the symbol and number.
    // Otherwise, it must be a two-char note.
    if (splitNote.length == 2) {
        sym += splitNote[0];
        oct = splitNote[1];
    } else if (splitNote.length == 3) {
        sym += Character.toString(splitNote[0]);
        sym += Character.toString(splitNote[1]);
        oct = splitNote[2];
    }

    // Find the corresponding note in the array.
    for (int i = 0; i < notes.length; i++) {
        if (notes[i].equals(sym)) {
            return Character.getNumericValue(oct) * 12 + i;
        }
    }

    // If nothing was found, we return -1.
    return -1;
}

And it works just great. However, I would also like to be able to use convertToPitch() with the alternate note value (Db becomes C#, etc.) for each note with an alternate name. Is there a way to do this without tearing my method apart?


Solution

  • You could do it like this

    public static int convertToPitch(String note) {
      String sym = "";
      int oct = 0;
      String[][] notes = { {"C"}, {"Db", "C#"}, {"D"}, {"Eb", "D#"}, {"E"},
        {"F"}, {"Gb", "F#"}, {"G"}, {"Ab", "G#"}, {"A"}, {"Bb", "A#"}, {"B"} };
    
      char[] splitNote = note.toCharArray();
    
      // If the length is two, then grab the symbol and number.
      // Otherwise, it must be a two-char note.
      if (splitNote.length == 2) {
        sym += splitNote[0];
        oct = splitNote[1];
      } else if (splitNote.length == 3) {
        sym += Character.toString(splitNote[0]);
        sym += Character.toString(splitNote[1]);
        oct = splitNote[2];
      }
    
      // Find the corresponding note in the array.
      for (int i = 0; i < notes.length; i++)
      for (int j = 0; j < notes[i].length; j++) {
        if (notes[i][j].equals(sym)) {
            return Character.getNumericValue(oct) * 12 + i;
        }
      }
    
      // If nothing was found, we return -1.
      return -1;
    }