godot-demo-projects/audio/bpm_sync/bpm_sync.gd

60 lines
1.4 KiB
GDScript3
Raw Normal View History

2019-04-27 19:14:17 +02:00
extends Panel
const BPM = 116
const BARS = 4
var playing = false
const COMPENSATE_FRAMES = 2
const COMPENSATE_HZ = 60.0
2020-03-09 08:48:22 +01:00
enum SyncSource {
SYSTEM_CLOCK,
SOUND_CLOCK,
}
2020-03-09 08:48:22 +01:00
var sync_source = SyncSource.SYSTEM_CLOCK
2019-09-01 07:03:32 +02:00
# Used by system clock.
var time_begin
var time_delay
2019-04-27 19:14:17 +02:00
func strsec(secs):
var s = str(secs)
2019-09-01 07:03:32 +02:00
if (secs < 10):
s = "0" + s
2019-04-27 19:14:17 +02:00
return s
2019-09-01 07:03:32 +02:00
func _process(_delta):
2020-03-09 08:48:22 +01:00
if !playing or !$Player.playing:
2019-04-27 19:14:17 +02:00
return
2019-09-01 07:03:32 +02:00
var time = 0.0
2020-03-09 08:48:22 +01:00
if sync_source == SyncSource.SYSTEM_CLOCK:
2019-09-01 07:03:32 +02:00
# Obtain from ticks.
time = (OS.get_ticks_usec() - time_begin) / 1000000.0
2019-09-01 07:03:32 +02:00
# Compensate.
time -= time_delay
2020-03-09 08:48:22 +01:00
elif sync_source == SyncSource.SOUND_CLOCK:
2019-09-01 07:03:32 +02:00
time = $Player.get_playback_position() + AudioServer.get_time_since_last_mix() - AudioServer.get_output_latency() + (1 / COMPENSATE_HZ) * COMPENSATE_FRAMES
2019-04-27 19:14:17 +02:00
var beat = int(time * BPM / 60.0)
var seconds = int(time)
var seconds_total = int($Player.stream.get_length())
2019-09-01 07:03:32 +02:00
$Label.text = str("BEAT: ", beat % BARS + 1, "/", BARS, " TIME: ", seconds / 60, ":", strsec(seconds % 60), " / ", seconds_total / 60, ":", strsec(seconds_total % 60))
2019-04-27 19:14:17 +02:00
func _on_PlaySystem_pressed():
2020-03-09 08:48:22 +01:00
sync_source = SyncSource.SYSTEM_CLOCK
time_begin = OS.get_ticks_usec()
time_delay = AudioServer.get_time_to_next_mix() + AudioServer.get_output_latency()
2019-09-01 07:03:32 +02:00
playing = true
2019-04-27 19:14:17 +02:00
$Player.play()
func _on_PlaySound_pressed():
2020-03-09 08:48:22 +01:00
sync_source = SyncSource.SOUND_CLOCK
2019-09-01 07:03:32 +02:00
playing = true
$Player.play()