Java midi注意到通过八度音符的字符串映射

时间:2012-02-19 19:47:47

标签: java midi guitar

在我的项目中,我希望能够至少告知用户他们需要播放的音符是什么字符串。我可以得到音符和它的八度音,但正如我发现的那样,音符及其八度音阶可以出现在吉他音板上的多个位置。

所以我的问题是:无论如何将midi音符映射到吉他弦?

3 个答案:

答案 0 :(得分:3)

这是获取MIDI音符值并返回最靠近乐器末端的吉他指板上的位置的代码。 Fret zero是一个开放字符串。

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

答案 1 :(得分:0)

是的,用简单的逻辑就可以做到这一点。我会考虑使用<Note, MidiNote>的HashMap,其中Note是您的类,它包含相对音符和八度音程,并且具有相当的等号和哈希码方法,而MidiNote是您代表Midi音符的类。

答案 2 :(得分:0)

将MIDI视为定义钢琴键。代码和密钥是一对一的。这与吉他或小提琴不同,它可以在多个地方播放相同的音色。

如果您希望以某种数据格式表示您对吉他的更大自由,您必须找到或发明不同的格式。 MIDI不会编码您想要的内容。

然而,你可能会采取间接的方式来解决这个问题,而且它与开发启发式方法有关,可以在给出前面注释的滑动窗口的情况下播放音符。根据您刚玩过的内容,给定的音符在一个弦或另一个弦上可能更容易,并且您可以根据手的模型和手指的位置来计算。基于此,您可以将MIDI转换为吉他,使MIDI最容易播放。如果您已经有一段遵循这些规则的吉他音乐,那么您可以用MIDI编码,然后再解码。

但也许你的问题更基本。是的,您可以将MIDI音符映射到吉他。天真的方法是制作可在吉他上播放的每个音符的映射,并通过选择最接近螺母的音符来决定相应的音符。这将是一个简单的一对一映射,但不一定是最容易的。

如果你真的想要做得对,你会仔细分析音乐,以决定最佳的手位置以及手的位置应该改变的位置,然后你将MIDI音符与音品和字符串相关联根据手的位置最容易达到的是什么。最佳解决方案可能是NP完全或更糟,您是否可能希望根据有关更改手位置的频率和范围的规则来开发近似解决方案。