Class: Webmidi::Clock

Inherits:
Object
  • Object
show all
Defined in:
lib/webmidi/clock.rb

Constant Summary collapse

PPQN =
24

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bpm: 120) ⇒ Clock

Returns a new instance of Clock.



13
14
15
16
17
18
19
20
21
22
# File 'lib/webmidi/clock.rb', line 13

def initialize(bpm: 120)
  validate_bpm!(bpm)
  @bpm = bpm
  @running = false
  @callbacks = []
  @error_callbacks = []
  @mutex = Mutex.new
  @thread = nil
  @tick_count = 0
end

Instance Attribute Details

#bpmObject

Returns the value of attribute bpm.



9
10
11
# File 'lib/webmidi/clock.rb', line 9

def bpm
  @bpm
end

#runningObject (readonly) Also known as: running?

Returns the value of attribute running.



9
10
11
# File 'lib/webmidi/clock.rb', line 9

def running
  @running
end

Instance Method Details

#beat_countObject



84
85
86
# File 'lib/webmidi/clock.rb', line 84

def beat_count
  @mutex.synchronize { @tick_count / PPQN }
end

#on_error(&block) ⇒ Object

Raises:

  • (ArgumentError)


59
60
61
62
63
64
65
66
# File 'lib/webmidi/clock.rb', line 59

def on_error(&block)
  raise ArgumentError, "on_error requires a block" unless block

  @mutex.synchronize { @error_callbacks << block }
  CallbackSubscription.new do
    @mutex.synchronize { @error_callbacks.delete(block) }
  end
end

#on_tick(&block) ⇒ Object

Raises:

  • (ArgumentError)


50
51
52
53
54
55
56
57
# File 'lib/webmidi/clock.rb', line 50

def on_tick(&block)
  raise ArgumentError, "on_tick requires a block" unless block

  @mutex.synchronize { @callbacks << block }
  CallbackSubscription.new do
    @mutex.synchronize { @callbacks.delete(block) }
  end
end

#pipe_to(output) ⇒ Object



68
69
70
# File 'lib/webmidi/clock.rb', line 68

def pipe_to(output)
  on_tick { output.send(Message.clock) }
end

#startObject



29
30
31
32
33
34
35
36
37
38
# File 'lib/webmidi/clock.rb', line 29

def start
  @mutex.synchronize do
    return self if @running

    @running = true
    @tick_count = 0
    @thread = Thread.new { clock_loop }
  end
  self
end

#start_messageObject



72
73
74
# File 'lib/webmidi/clock.rb', line 72

def start_message
  Message.start
end

#stopObject



40
41
42
43
44
45
46
47
48
# File 'lib/webmidi/clock.rb', line 40

def stop
  thread = @mutex.synchronize do
    @running = false
    @thread
  end
  thread&.join(1) if thread && thread != Thread.current
  @mutex.synchronize { @thread = nil if @thread == thread }
  self
end

#stop_messageObject



76
77
78
# File 'lib/webmidi/clock.rb', line 76

def stop_message
  Message.stop
end

#tick_countObject



80
81
82
# File 'lib/webmidi/clock.rb', line 80

def tick_count
  @mutex.synchronize { @tick_count }
end