@@ -80,6 +80,11 @@ class MidiFileReader:
8080 # Read header bytes in order.
8181 _file .get_32 () # Header size.
8282 format = _file .get_16 ()
83+
84+ if format != MidiFile .FileFormat .SINGLE_TRACK && format != MidiFile .FileFormat .MULTI_TRACK :
85+ printerr ("MidiImporter: Failed to read the file at '%s ', expected a single or multi track format, got format %d instead." % [ _file .get_path (), format ])
86+ return false
87+
8388 var track_num := _file .get_16 ()
8489 resolution = _file .get_16 ()
8590
@@ -220,19 +225,33 @@ class MidiFileReader:
220225 _extract_instrument (i , midi_payload , song )
221226
222227 if midi_payload .midi_type == MidiTrackEvent .MidiType .NOTE_ON :
223- _extract_note (i , midi_payload , event .timestamp )
228+ _extract_note (i , midi_payload , event .timestamp , song )
224229
225230 if midi_payload .midi_type == MidiTrackEvent .MidiType .NOTE_OFF :
226- _change_note_length (i , midi_payload , event .timestamp )
231+ _change_note_length (i , midi_payload , event .timestamp , song )
227232
228233 i += 1
229234
230235
231236 func _extract_instrument (track_idx : int , midi_payload : MidiTrackEvent .MidiPayload , song : Song ) -> void :
237+ _create_midi_instrument (track_idx , midi_payload .channel_num , midi_payload .data [0 ], song )
238+
239+
240+ func _ensure_instrument (track_idx : int , midi_payload : MidiTrackEvent .MidiPayload , song : Song ) -> void :
241+ # This check can fail if the track contains no PROGRAM CHANGE events, which is possible.
242+ # We can only create some fallback instrument in that case.
243+ var instrument_key := Vector2i (track_idx , midi_payload .channel_num )
244+ if _instruments_index_map .has (instrument_key ):
245+ return
246+
247+ _create_midi_instrument (track_idx , midi_payload .channel_num , 0 , song )
248+
249+
250+ func _create_midi_instrument (track_idx : int , channel_num : int , voice_idx : int , song : Song ) -> void :
232251 var midi_instrument := MidiInstrument .new ()
233252 midi_instrument .track_index = track_idx
234- midi_instrument .channel_num = midi_payload . channel_num
235- midi_instrument .midi_voice = midi_payload . data [ 0 ]
253+ midi_instrument .channel_num = channel_num
254+ midi_instrument .midi_voice = voice_idx
236255
237256 # Keep a map for future use by notes.
238257 var index_key := midi_instrument .get_index_key ()
@@ -258,11 +277,13 @@ class MidiFileReader:
258277 song .instruments .push_back (bosca_instrument )
259278
260279
261- func _extract_note (track_idx : int , midi_payload : MidiTrackEvent .MidiPayload , timestamp : int ) -> void :
280+ func _extract_note (track_idx : int , midi_payload : MidiTrackEvent .MidiPayload , timestamp : int , song : Song ) -> void :
281+ _ensure_instrument (track_idx , midi_payload , song )
282+
262283 var midi_volume := midi_payload .data [1 ]
263284 # When a note on event comes with zero velocity/volume, it's actually a note off event.
264285 if midi_volume == 0 :
265- _change_note_length (track_idx , midi_payload , timestamp )
286+ _change_note_length (track_idx , midi_payload , timestamp , song )
266287 return
267288
268289 var midi_track := _tracks [track_idx ]
@@ -283,7 +304,9 @@ class MidiFileReader:
283304 instrument_notes .push_back (midi_note )
284305
285306
286- func _change_note_length (track_idx : int , midi_payload : MidiTrackEvent .MidiPayload , timestamp : int ) -> void :
307+ func _change_note_length (track_idx : int , midi_payload : MidiTrackEvent .MidiPayload , timestamp : int , song : Song ) -> void :
308+ _ensure_instrument (track_idx , midi_payload , song )
309+
287310 var instrument_key := Vector2i (track_idx , midi_payload .channel_num )
288311 var instrument_notes : Array [MidiNote ] = _notes_instrument_map [instrument_key ]
289312 var midi_track := _tracks [track_idx ]
0 commit comments