java 将 Midi 音符编号转换为名称和八度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/712679/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 13:28:53  来源:igfitidea点击:

Convert Midi Note Numbers To Name and Octave

javaaudiomidijavasound

提问by Jon

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:

有没有人知道 Java 世界中有什么东西可以将 MIDI 音符编号映射到特定的音符名称和八度音阶编号。例如,参见参考表:

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

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?

我想将一个 MIDI 音符编号 60 映射到它在八度音阶中对应的音符名称 (MiddleC)。我可以为此编写一个实用程序类/枚举,但这会很乏味。有人知道吗?

I'm specifically using this to write a Tenori-On/Monome clone in Java, so far so good...

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

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

采纳答案by paxdiablo

I'm not convinced your suggestion is thattedious. 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:

在真正的 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);
    }
  }
}

回答by David Koelle

In JFugue, the Noteclass has a utility method that does exactly this - see public static String getStringForNote(byte noteValue).

JFugue 中Note该类有一个实用程序方法可以完成此操作 - 请参阅public static String getStringForNote(byte noteValue)

EDIT:As of JFugue 5.0 and later, the Noteclass has several utility methods for getting a string representation from a MIDI note value:

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

  • getToneString(byte noteValue)converts a value of 60to the string C5
  • getToneStringWithoutOctave(byte noteValue)converts a value of 60to the string C
  • getPercussionString(byte noteValue)converts a value of 60to the string "[AGOGO]"
  • getToneString(byte noteValue)将 的值转换为 60字符串C5
  • getToneStringWithoutOctave(byte noteValue)将 的值转换为60字符串C
  • getPercussionString(byte noteValue)将 的值转换为60字符串"[AGOGO]"

These replace the original getStringForNote()method.

这些取代了原来的getStringForNote()方法。

回答by A-Sharabiani

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

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

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

  • 注意名称索引是noteNumber % 12.