jam-buddy / MIDI_TO_GP5.md
salgadev's picture
Sync from GitHub 6feaf31d
b2e4883 verified
|
Raw
History Blame Contribute Delete
2.77 kB

MIDI β†’ GP5/6 converter β€” design

Goal

Convert a keyswitched MIDI file (one track at a time) back to a Guitar Pro 5/6 file.

Direction

Mirror of gp5_to_keyswitched_mid.py. Where the forward script uses detect_techniques to read articulations from note.effect.*, the reverse script needs to infer articulations from the keyswitch note that precedes each pitched note.

Architecture

midi_to_gp5.py
β”œβ”€β”€ parse MIDI β†’ flat list of (track_name, channel, notes, keyswitches)
β”œβ”€β”€ classify tracks (guitar / bass / drums)
β”œβ”€β”€ for each pitched note, look at the preceding keyswitch note and
β”‚   in the same tick β†’ infer the technique
β”œβ”€β”€ build a Song with one Track per MIDI track
└── write via guitarpro.write()

Inference rules (keyswitch β†’ technique)

Same dictionary as the forward script, inverted. Driven by KEYSWITCH_NOTES which maps MIDI note number β†’ technique name:

Note Technique GP5 effect
17 / 18 sustain (no effect β€” sustain is the default)
20 palm_mute effect.palmMute = True
9 harmonic effect.harmonic = HarmonicEffect(type=Natural)
23 slide_down effect.slides = [SlideType.shiftSlideTo] (with next-note direction)
24 slide_up same
26 hammer effect.hammer = True
27 slide_in effect.grace = GraceEffect(transition=slide)
91 bend effect.bend = BendEffect(points=[...])

Drum notes use standard GM mappings (MIDI 36 = kick, 38 = snare, 42 = hi-hat closed).

Open questions

  1. Tie detection: notes whose note_on happens before the previous note_off for the same pitch β†’ ties. Inferred from MIDI timing.
  2. Bend reconstruction: reading pitch wheel events from MIDI is possible but fragile. Most keyswitch-instrumented MIDIs don't include pitch bend. Initially: skip bend (write straight notes).
  3. Slide direction (up/down): target pitch is the next note on the same channel. We don't know the target string, so we use the pitch comparison and let the bar position fill in.
  4. String/fret selection: pick the lowest playable fret on the appropriate string. Not unique; heuristic only.
  5. Tuning: read from existing GP5 file or default to standard EADGBE.
  6. Track routing: user passes --track-name "Distortion Guitar" and --instrument guitar|bass|drums to control the new GP track.

File layout

midi_to_gp5.py    # the converter
tests/
  test_midi_to_gp5.py    # round-trip tests
  expected/
    *.mid    # input fixtures (committed)
    *.gp5    # expected outputs (committed)

Status

  • Design above
  • MIDI parser
  • Track classifier
  • Articulation inferer
  • Song builder
  • Tests