在我的项目中,我希望至少能够告知用户他们需要演奏的音符在哪个弦上。我可以得到音符及其八度音阶,但正如我所发现的那样,该音符及其八度音阶可以出现在吉他指板上的多个位置。
所以我的问题是:有没有办法将 midi 音符映射到吉他弦上?
这是获取 MIDI 音符值并返回吉他指板上最靠近乐器末端的位置的代码。零品是一个开弦。
static class Fingering {
int string;
int fret;
public String toString() {
return "String : " + stringNames[string] + ", fret : " + fret;
}
}
static String[] stringNames = new String[] {"Low E", "A", "D", "G", "B", "High E"};
/** Array showing guitar string's relative pitches, in semi-tones, with "0" being low E */
static int[] strings = new int[]{64, 69, 74, 79, 83, 88};
public static Fingering getIdealFingering(int note) {
if (note < strings[0])
throw new RuntimeException("Note " + note + " is not playable on a guitar in standard tuning.");
Fingering result = new Fingering();
int idealString = 0;
for (int x = 1; x < strings.length; x++) {
if (note < strings[x])
break;
idealString = x;
}
result.string = idealString;
result.fret = note - strings[idealString];
return result;
}
public static void main(String[] args) {
System.out.println(getIdealFingering(64)); // Low E
System.out.println(getIdealFingering(66)); // F#
System.out.println(getIdealFingering(72)); // C on A string
System.out.println(getIdealFingering(76)); // E on D string
System.out.println(getIdealFingering(88)); // guitar's high e string, open
System.out.println(getIdealFingering(100)); // high E, 12th fret
System.out.println(getIdealFingering(103)); // high G
}
结果:
String : Low E, fret : 0
String : Low E, fret : 2
String : A, fret : 3
String : D, fret : 2
String : High E, fret : 0
String : High E, fret : 12
String : High E, fret : 15
是的,通过简单的逻辑,您可以做到这一点。我会考虑使用一个 HashMap,<Note, MidiNote>
其中 Note 是你的类,它同时包含相对音符和八度音阶,并具有不错的等号和哈希码方法,而 MidiNote 是你代表 Midi 音符的类。
将 MIDI 视为定义钢琴键。代码和密钥是一对一的。这不像吉他或小提琴,可以在多个地方演奏相同的音调。
如果您想以某种数据格式表示您在吉他上拥有的更大自由度,您将不得不寻找或发明一种不同的格式。MIDI 不会编码你想要的。
但是,您可以通过一种间接的方式来解决此问题,它与开发启发式方法有关,在给定之前出现的音符滑动窗口的情况下,在哪里播放音符。一个给定的音符在一根或另一根弦上可能更容易,这取决于你刚刚弹奏的内容,你可以根据手的模型和手指的位置来计算它。基于此,您可以将 MIDI 转换为吉他,以使 MIDI 最容易演奏。如果你有一段吉他音乐已经遵循这些规则,那么你可以在 MIDI 中对其进行编码,然后再对其进行解码。
但也许你的问题更基本。是的,您可以将 MIDI 音符映射到吉他。最简单的方法是对吉他上可演奏的每个音符进行映射,然后通过选择最接近琴枕的一个来决定等效的替代方案。这将是一个简单的一对一映射,但不一定是最容易玩的。
如果你真的想把它做对,你将对音乐进行仔细分析,以确定最佳手部位置和手部位置应该改变的位置,然后你会根据最容易将 MIDI 音符与品格和弦乐相关联根据手的位置到达。最佳解决方案可能是 NP 完全或更糟的,您是否可能希望根据一些关于您可以改变手部位置的频率和距离的规则来开发一个近似解决方案。