This repository has been archived by the owner on Aug 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
taptempo.cr
69 lines (56 loc) · 1.66 KB
/
taptempo.cr
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
require "option_parser"
class TapTempo
@taps = Array(Time::Span).new
@sample = 5
@resetTime = 5
@precision = 0
def initialize
generateHelp
end
def tap
currentTap = Time.monotonic
checkResetTime
@taps.shift if @taps.size == @sample
@taps << currentTap
end
def loop
STDIN.raw &.each_char do |char|
break if char == 'q'
tap
displayBPM
end
puts "Bye Bye!"
end
private def checkResetTime
return if @taps.empty?
@taps.clear if Time.monotonic - @taps[-1] > Time::Span.new(0, 0, @resetTime)
end
private def displayBPM
if @taps.size == 1
puts "[Hit a key one more time to start bpm computation...]\r"
return
end
puts sprintf "Tempo: %." + normalizePrecision + "f bpm\r", getBPM
end
private def getBPM
60.0 / ((@taps[-1] - @taps[0]) / (@taps.size.to_f - 1)).to_f
end
private def normalizePrecision
return "" if @precision == 0
@precision.to_s
end
private def generateHelp
OptionParser.parse! do |parser|
parser.banner = "Usage: #{PROGRAM_NAME} [options]"
parser.on("-h", "--help", "display this help message") do
puts parser
exit
end
parser.on("-p", "--precision=#{@precision}", "set the decimal precision of the tempo display") { |precision| @precision = precision.to_i }
parser.on("-r", "--reset-time=#{@resetTime}", "set the time in second to reset the computation") { |resetTime| @resetTime = resetTime.to_i }
parser.on("-s", "--sample-size=#{@sample}", "set the number of samples needed to compute the tempo") { |sample| @sample = sample.to_i }
end
end
end
tapTempo = TapTempo.new
tapTempo.loop