Class: HeadMusic::Meter

Inherits:
Object
  • Object
show all
Defined in:
lib/head_music/meter.rb

Overview

Meter is the rhythmic size of a measure, such as 4/4 or 6/8

Constant Summary collapse

NAMED =
{
  common_time: "4/4",
  cut_time: "2/2"
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(top_number, bottom_number) ⇒ Meter

Returns a new instance of Meter.



30
31
32
33
# File 'lib/head_music/meter.rb', line 30

def initialize(top_number, bottom_number)
  @top_number = top_number
  @bottom_number = bottom_number
end

Instance Attribute Details

#bottom_numberObject (readonly)

Returns the value of attribute bottom_number.



3
4
5
# File 'lib/head_music/meter.rb', line 3

def bottom_number
  @bottom_number
end

#top_numberObject (readonly)

Returns the value of attribute top_number.



3
4
5
# File 'lib/head_music/meter.rb', line 3

def top_number
  @top_number
end

Class Method Details

.common_timeObject



22
23
24
# File 'lib/head_music/meter.rb', line 22

def self.common_time
  get(:common_time)
end

.cut_timeObject



26
27
28
# File 'lib/head_music/meter.rb', line 26

def self.cut_time
  get(:cut_time)
end

.defaultObject



18
19
20
# File 'lib/head_music/meter.rb', line 18

def self.default
  get("4/4")
end

.get(identifier) ⇒ Object



10
11
12
13
14
15
16
# File 'lib/head_music/meter.rb', line 10

def self.get(identifier)
  identifier = identifier.to_s
  hash_key = HeadMusic::Utilities::HashKey.for(identifier)
  time_signature_string = NAMED[hash_key] || identifier
  @meters ||= {}
  @meters[hash_key] ||= new(*time_signature_string.split("/").map(&:to_i))
end

Instance Method Details

#==(other) ⇒ Object



93
94
95
# File 'lib/head_music/meter.rb', line 93

def ==(other)
  to_s == other.to_s
end

#beat_strength(count, tick: 0) ⇒ Object



63
64
65
66
67
68
69
70
# File 'lib/head_music/meter.rb', line 63

def beat_strength(count, tick: 0)
  return 100 if downbeat?(count, tick)
  return 80 if strong_beat?(count, tick)
  return 60 if beat?(tick)
  return 40 if strong_ticks.include?(tick)

  20
end

#beat_unitObject



80
81
82
83
84
85
86
87
# File 'lib/head_music/meter.rb', line 80

def beat_unit
  @beat_unit ||=
    if compound?
      HeadMusic::Content::RhythmicValue.new(HeadMusic::RhythmicUnit.for_denominator_value(bottom_number / 2), dots: 1)
    else
      HeadMusic::Content::RhythmicValue.new(count_unit)
    end
end

#beats_per_barObject



55
56
57
# File 'lib/head_music/meter.rb', line 55

def beats_per_bar
  compound? ? top_number / 3 : top_number
end

#compound?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/head_music/meter.rb', line 39

def compound?
  top_number > 3 && (top_number % 3).zero?
end

#count_unitObject



76
77
78
# File 'lib/head_music/meter.rb', line 76

def count_unit
  HeadMusic::RhythmicUnit.for_denominator_value(bottom_number)
end

#counts_per_barObject



59
60
61
# File 'lib/head_music/meter.rb', line 59

def counts_per_bar
  top_number
end

#duple?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/head_music/meter.rb', line 43

def duple?
  top_number == 2
end

#quadruple?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/head_music/meter.rb', line 51

def quadruple?
  top_number == 4
end

#simple?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/head_music/meter.rb', line 35

def simple?
  !compound?
end

#strong_countsObject



97
98
99
100
101
# File 'lib/head_music/meter.rb', line 97

def strong_counts
  @strong_counts ||= (1..counts_per_bar).select do |count|
    downbeat?(count) || strong_beat_in_duple?(count) || strong_beat_in_triple?(count)
  end
end

#strong_ticksObject



103
104
105
# File 'lib/head_music/meter.rb', line 103

def strong_ticks
  @strong_ticks ||= [2, 3, 4].map { |sixths| ticks_per_count * (sixths / 6.0) }
end

#ticks_per_countObject



72
73
74
# File 'lib/head_music/meter.rb', line 72

def ticks_per_count
  @ticks_per_count ||= count_unit.ticks
end

#to_sObject



89
90
91
# File 'lib/head_music/meter.rb', line 89

def to_s
  [top_number, bottom_number].join("/")
end

#triple?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/head_music/meter.rb', line 47

def triple?
  (top_number % 3).zero?
end