Class: Clef::Core::Duration

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/clef/core/duration.rb

Constant Summary collapse

BASE_VALUES =
{
  whole: Rational(1, 1),
  half: Rational(1, 2),
  quarter: Rational(1, 4),
  eighth: Rational(1, 8),
  sixteenth: Rational(1, 16),
  thirty_second: Rational(1, 32),
  sixty_fourth: Rational(1, 64),
  one_twenty_eighth: Rational(1, 128),
  two_fifty_sixth: Rational(1, 256)
}.freeze
NUMBER_TO_BASE =
{
  1 => :whole,
  2 => :half,
  4 => :quarter,
  8 => :eighth,
  16 => :sixteenth,
  32 => :thirty_second,
  64 => :sixty_fourth,
  128 => :one_twenty_eighth,
  256 => :two_fifty_sixth
}.freeze
BASE_TO_NUMBER =
NUMBER_TO_BASE.invert.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base, dots: 0) ⇒ Duration

Returns a new instance of Duration.

Parameters:

  • base (Symbol)
  • dots (Integer) (defaults to: 0)


36
37
38
39
40
41
42
43
# File 'lib/clef/core/duration.rb', line 36

def initialize(base, dots: 0)
  validate_base!(base)
  validate_dots!(dots)

  @base = base
  @dots = dots
  freeze
end

Instance Attribute Details

#baseObject (readonly)

Returns the value of attribute base.



32
33
34
# File 'lib/clef/core/duration.rb', line 32

def base
  @base
end

#dotsObject (readonly)

Returns the value of attribute dots.



32
33
34
# File 'lib/clef/core/duration.rb', line 32

def dots
  @dots
end

Class Method Details

.from_lilypond(number, dots = 0) ⇒ Duration

Parameters:

  • number (Integer)
  • dots (Integer) (defaults to: 0)

Returns:



71
72
73
74
75
# File 'lib/clef/core/duration.rb', line 71

def self.from_lilypond(number, dots = 0)
  new(NUMBER_TO_BASE.fetch(number), dots: dots)
rescue KeyError
  raise ArgumentError, "unsupported lilypond duration: #{number}"
end

Instance Method Details

#<=>(other) ⇒ Integer?

Parameters:

Returns:

  • (Integer, nil)


57
58
59
60
61
# File 'lib/clef/core/duration.rb', line 57

def <=>(other)
  return nil unless other.is_a?(self.class)

  length <=> other.length
end

#base_valueRational

Returns:

  • (Rational)


46
47
48
# File 'lib/clef/core/duration.rb', line 46

def base_value
  BASE_VALUES.fetch(base)
end

#lengthRational

Returns:

  • (Rational)


51
52
53
# File 'lib/clef/core/duration.rb', line 51

def length
  base_value * (Rational(2, 1) - Rational(1, 2**dots))
end

#to_lilypondString

Returns:

  • (String)


64
65
66
# File 'lib/clef/core/duration.rb', line 64

def to_lilypond
  "#{BASE_TO_NUMBER.fetch(base)}#{"." * dots}"
end