19

有谁知道 Java 世界中存在将 midi 音符编号映射到特定音符名称和八度音阶编号的任何东西。例如,参见参考表:

http://www.harmony-central.com/MIDI/Doc/table2.html

我想将 60 号 midi 音符映射到 octave 4 中相应的音符名称 (MiddleC)。我可以为此编写一个实用程序类/枚举,但这会相当乏味。有人知道吗?

我专门用它来用 Java 编写 Tenori-On/Monome 克隆,到目前为止一切都很好......

解决方案

这就是我最终使用的:

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];
4

4 回答 4

17

我不相信你的建议是那么乏味。它实际上只是一个除模运算,一个得到八度,另一个得到音符。

octave = int (notenum / 12) - 1;
note = substring("C C#D D#E F F#G G#A A#B ",(notenum % 12) * 2, 2);

在真正的 Java 中,与上面的伪代码相反,您可以使用如下内容:

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);
    }
  }
}
于 2009-04-03T05:48:04.967 回答
4

JFugue中,Note该类有一个实用方法可以做到这一点 - 请参阅public static String getStringForNote(byte noteValue)

编辑:从 JFugue 5.0 及更高版本开始,Note该类有几个实用方法用于从 MIDI 音符值获取字符串表示:

  • getToneString(byte noteValue)将 的值转换为 60字符串C5
  • getToneStringWithoutOctave(byte noteValue)将 的值转换为60字符串C
  • getPercussionString(byte noteValue)将 的值转换为60字符串"[AGOGO]"

这些替换了原始getStringForNote()方法。

于 2010-01-05T18:59:55.180 回答
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;
}

解释:

  • midi中的A0是第一个音符,编号为21。我们将索引调整为从0开始(因此noteNumber -= 21;在开头)。如果您的音符编号是从 0 开始的,例如在钢琴中从 0 到 88,那么您可以注释掉这一行。

  • 请注意,在此解决方案中,数组中的音符名称从 A 到 G 开始。

  • 八度是noteNumber / 12 + 1(或 num / 12 的上限)。

  • 注释名称索引为noteNumber % 12.
于 2019-02-06T03:34:56.570 回答
1

这是没有太多命名常量的最短形式。也不需要任何循环。

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);
 }
于 2020-10-18T01:17:46.187 回答