bpm_sync.gd 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. extends Panel
  2. const BPM = 116
  3. const BARS = 4
  4. var playing = false
  5. const COMPENSATE_FRAMES = 2
  6. const COMPENSATE_HZ = 60.0
  7. enum SyncSource {
  8. SYSTEM_CLOCK,
  9. SOUND_CLOCK,
  10. }
  11. var sync_source = SyncSource.SYSTEM_CLOCK
  12. # Used by system clock.
  13. var time_begin
  14. var time_delay
  15. func strsec(secs):
  16. var s = str(secs)
  17. if (secs < 10):
  18. s = "0" + s
  19. return s
  20. func _process(_delta):
  21. if not playing or not $Player.playing:
  22. return
  23. var time = 0.0
  24. if sync_source == SyncSource.SYSTEM_CLOCK:
  25. # Obtain from ticks.
  26. time = (Time.get_ticks_usec() - time_begin) / 1000000.0
  27. # Compensate.
  28. time -= time_delay
  29. elif sync_source == SyncSource.SOUND_CLOCK:
  30. time = $Player.get_playback_position() + AudioServer.get_time_since_last_mix() - AudioServer.get_output_latency() + (1 / COMPENSATE_HZ) * COMPENSATE_FRAMES
  31. var beat = int(time * BPM / 60.0)
  32. var seconds = int(time)
  33. var seconds_total = int($Player.stream.get_length())
  34. @warning_ignore("integer_division")
  35. $Label.text = str("BEAT: ", beat % BARS + 1, "/", BARS, " TIME: ", seconds / 60, ":", strsec(seconds % 60), " / ", seconds_total / 60, ":", strsec(seconds_total % 60))
  36. func _on_PlaySystem_pressed():
  37. sync_source = SyncSource.SYSTEM_CLOCK
  38. time_begin = Time.get_ticks_usec()
  39. time_delay = AudioServer.get_time_to_next_mix() + AudioServer.get_output_latency()
  40. playing = true
  41. $Player.play()
  42. func _on_PlaySound_pressed():
  43. sync_source = SyncSource.SOUND_CLOCK
  44. playing = true
  45. $Player.play()