This plugin aims to make rhythm game development and music syncing easier than ever before. Import a midi file like you would any other Godot asset, this can then be paired with a "MidiPlayer" node that sends out signals every time a midi event is fired. This project is a work in progress and lacks some features, so feel free to contribute any code or ideas on the pull requests page.
2023-10-22.14-02-20_min.mp4
2024-03-25.08-45-16.mp4
This GDExtension addon is compatible with Godot version 4.2.2 and higher. Earlier 4.x versions may work, however they are not officially supported.
-
Download the latest release from https://github.com/nlaha/godot-midi/releases
-
Copy the
godot-midi
folder to your project'saddons
folder -
Enable the addon in Godot's project settings
-
Clone the repository with
git clone --recursive https://github.com/nlaha/godot-midi.git
-
Make sure you have SCons installed
-
Run
cd godot-cpp
andscons target=template_debug
orscons target=template_release
to build godot-cpp -
Run
scons target=template_debug
orscons target=template_release
in the root directory to build the extension -
Copy the
game/addons/godot_midi
folder to your project's addons folder -
Enable the plugin in the Godot project settings menu
- Import a midi file by adding it to your project folder
NOTE: If you run into import errors or problems with a midi file you downloaded from the internet, it's likely there is a midi event or format that isn't supported by Godot Midi. The best way to fix this is to import the midi file into a DAW (digital audio workstation) or similar software and re-export it. This should convert the midi file into a format easily readable by Godot Midi. I do all my testing with FL Studio so I'd recommend that, you can use the free demo version if you don't have a license.
- Add a "MidiPlayer" node to your scene
- Set the midi resource you want the MidiPlayer to play
-
Connect to the "note" signal in a GDScript
func _ready(): midi_player.note.connect(my_note_callback) midi_player.play() func my_note_callback(event, track): if (event['subtype'] == MIDI_MESSAGE_NOTE_ON): # note on # do something on note on elif (event['subtype'] == MIDI_MESSAGE_NOTE_OFF): # note off # do something on note off print("[Track: " + str(track) + "] Note played: " + str(event['note']))
Because the game thread frame time can fluctuate depending on the system load, GodotMidi's player is run on a separate thread. Because of this, it's best to use the built-in synchronization feature if you want to sync MIDI events to music.
The good news: it's easy to use! Just call link_audio_stream_player(...)
with your ASP and it will automatically start/stop/pause the ASP for you!
func _ready():
midi_player.loop = true
midi_player.note.connect(my_note_callback)
# link the AudioStreamPlayer in your scene
# that contains the music associated with the midi
# NOTE: this must be an array, you can link multiple ASPs or one as
# shown below and they will all sync with playback of the MIDI
midi_player.link_audio_stream_player([asp])
# this will also start the audio stream player (music)
midi_player.play()
func my_note_callback(event, track):
if (event['subtype'] == MIDI_MESSAGE_NOTE_ON): # note on
# do something on note on
elif (event['subtype'] == MIDI_MESSAGE_NOTE_OFF): # note off
# do something on note off
print("[Track: " + str(track) + "] Note played: " + str(event['note']))
Open the demo project for an included music visualizer script!