Skip to content

Instantly share code, notes, and snippets.

@seki
Created April 28, 2025 14:54
Show Gist options
  • Save seki/9aa8875613c92dc0f60532ba0a1ab50c to your computer and use it in GitHub Desktop.
Save seki/9aa8875613c92dc0f60532ba0a1ab50c to your computer and use it in GitHub Desktop.
RubyKaigiの立ち話の際にお話しした遅延が蓄積されないsleepの件です!! (sequencer.rbは実際に動かして試していません)
class PeriodicCue
def initialize(*interval)
@interval = interval.cycle
@time = nil
end
def sleep_until(t)
sleep((t - Time.now).clamp(0..))
end
def sync
@time += @interval.next
sleep_until(@time)
end
def start
@time = Time.now unless @time
end
end
if __FILE__ == $0
cue = PeriodicCue.new(0.8, 0.2)
cue.start
s = t = Time.now
10.times do |n|
puts (n % 2 == 0) ? 'on' : 'off'
cue.sync
last, t = t, Time.now
puts "%.3f" % (t - s)
end
end
diff --git a/lib/sequencer.rb b/lib/sequencer.rb
index 7eceb64..16b121a 100644
--- a/lib/sequencer.rb
+++ b/lib/sequencer.rb
@@ -335,7 +335,9 @@ class Sequencer
Thread.new do
step_interval = 60.0 / @bpm / 4
play_position = 0
+ cue = PeriodicCue.new(step_interval * 0.8, step_interval * 0.2)
+ cue.start
while @playing
# 各トラックの現在位置のステップをチェック
@tracks.each do |track_info|
@@ -376,7 +378,7 @@ class Sequencer
end
# 少し待ってノートをオフにする
- sleep step_interval * 0.8
+ cue.sync
# ノートをオフにする
@tracks.each do |track_info|
@@ -408,7 +410,7 @@ class Sequencer
end
# 残りのステップ時間を待つ
- sleep step_interval * 0.2
+ cue.sync
# 次のステップへ
play_position = (play_position + 1) % @steps_per_track
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment