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.
This extension is compatible with Windows, Mac and Linux. Support for Android is also availble but is not yet integrated into the CI pipelines. For more information on how to compile for Android, see this pull request: #35
- Download the latest release from https://github.com/nlaha/godot-midi/releases
If you'd like to download a newer version that hasn't been released, download it from the latest Github Actions run: https://github.com/nlaha/godot-midi/actions/workflows/builds.yml
- 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!