-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmidi_file_player_example.gd
108 lines (93 loc) · 12.9 KB
/
midi_file_player_example.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""
Midi Player Demo
See comments bellow in _process, when to start/stop a note
@author BrainFooLong
@url https://github.com/brainfoolong/gdscript-midi-parser
"""
class_name MidiFilePlayerExample extends Node
signal event (eventData, trackData)
signal finished
var parser : MidiFileParser
var ms_per_tick = 60000 / (120 * 480)
var lastEventTime = 0
var currentEventIndex = 0
var playing = false
var audio_streams = {}
var sample_hz = 22050.0 # Keep the number of samples to mix low, GDScript is not super fast.
var pulse_hz = 220.0
var phase = 0.0
func play():
lastEventTime = -1
playing = true
func pause():
playing = false
func stop():
playing = false
func play_sound(note_name, hz = 0, volume = 0):
if note_name in audio_streams:
audio_streams[note_name].stop()
audio_streams[note_name].queue_free()
audio_streams.erase(note_name)
if volume > 0:
var audio_stream = AudioStreamPlayer.new()
audio_stream.stream = AudioStreamGenerator.new()
audio_stream.volume_db = -((1 - volume) * 20)
audio_stream.stream.mix_rate = 3675 # using low sample rate for performance, best is 44100
audio_streams[note_name] = audio_stream
add_child(audio_stream)
audio_stream.play()
var playback = audio_stream.get_stream_playback()
var increment = hz / audio_stream.stream.mix_rate
var to_fill = playback.get_frames_available()
while to_fill > 0:
playback.push_frame(Vector2.ONE * sin(phase * TAU)) # Audio frames are stereo.
phase = fmod(phase + increment, 1.0)
to_fill -= 1
func _ready():
# loading Beethoven - Fur Elise
parser = MidiFileParser.load_packed_byte_array(Marshalls.base64_to_raw("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"))
# use MidiFileParser.load_file() when you have a file on disk
play()
func _process(delta):
if !playing:
return
var all_finished = true
for track in parser.tracks:
var player_process
# storing internal player process in track data
if "player_process" not in track.additional_data:
track.additional_data.player_process = {"start_time" : Time.get_ticks_msec(), "delta_tick" : 0, "event_index" : 0}
player_process = track.additional_data.player_process
else:
player_process = track.additional_data.player_process
while player_process.event_index < track.events.size():
var elapsed_ms = Time.get_ticks_msec() - player_process.start_time
var delta_ticks = elapsed_ms / ms_per_tick
var event = track.events[player_process.event_index]
if player_process.delta_tick + event.delta_ticks > delta_ticks:
break
player_process.delta_tick += event.delta_ticks
player_process.event_index += 1
self.emit_signal("event", event, track)
if event.event_type == MidiFileParser.Event.EventType.META && event.type == MidiFileParser.Meta.Type.SET_TEMPO:
# tempo update
ms_per_tick = event.ms_per_tick
print("tempo now " +str(event.bpm)+ " bpm")
if event.event_type == event.EventType.MIDI && event.note_name != '':
var offset = event.param1 - 69
if event.velocity > 0:
play_sound(event.note_name, event.frequency, event.velocity)
print("Play "+event.note_name+" with velocity "+str(event.velocity)+" freq "+str(event.frequency))
else:
play_sound(event.note_name)
print("Stop "+event.note_name)
# event.velocity <= 0 = note off
# event.velocity > 0 = note on
# see MidiFileParser.Midi for more information about the midi data
pass
if all_finished && player_process.event_index != track.events.size():
all_finished = false
if all_finished:
print("finished")
self.emit_signal("finished")
stop()