Java midi note to string mapping via octave of a note

余生长醉 提交于 2019-12-24 07:58:18

问题


In my project I want to be able to at least inform the user what string the note they need to play is on. I can get the note and its octave but as I've discovered, that note and its octave can appear in multiple places on a guitar fret board.

So my question is: Is there anyway to map a midi note to a guitar string?


回答1:


Here's code that takes the MIDI note value and returns the position on the guitar fretboard closest to the end of the instrument. Fret zero is an open string.

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
}

Result:

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



回答2:


Yes, with simple logic you can do this. I would consider using a HashMap of <Note, MidiNote> where Note is your class that holds both relative note and octave and has decent equals and hashcode methods, and MidiNote is your class to represent a Midi note.




回答3:


Think of MIDI as like defining piano keys. Codes and keys are one-to-one. This is unlike a guitar or violin, where the same tone can be played in multiple places.

If you want to represent the greater freedom you have on a guitar in some data format, you'll have to find or invent a different format. MIDI won't encode what you want.

However, there's an indirect way you might go about this, and it has to do with developing heuristics as to where to play a note given a sliding window of notes that came before. A given note may be easier on one string or another depending on what you've just played, and you can calculate that given a model of the hand and where fingers will have been. Based on this, you can convert MIDI to guitar in a way that makes the MIDI easiest to play. If you have a piece of guitar music that follows these rules already, then you can encode it in MIDI and then decode it later.

But perhaps your question is more basic. Yes, you can map a MIDI note to a guitar. The naive method is to make a mapping of each note playable on the guitar, and you decide between equivalent alternatives by picking the one closest to the nut. This would be an easy one-to-one mapping but wouldn't necessarily be the easiest to play.

If you REALLY want to do it right, you'll do a careful analysis of the music to decide the optimal hand position and where the hand position should change, and then you'd associate MIDI notes with frets and strings based on what's easiest to reach based on the hand position. The optimal solution is probably NP-complete or worse, do you'd probably want to develop an approximate solution based on some rules about how often and how far you can change hand position.



来源:https://stackoverflow.com/questions/9352615/java-midi-note-to-string-mapping-via-octave-of-a-note

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!