class HeadMusic::Meter

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

Constants

NAMED

Attributes

bottom_number[R]
top_number[R]

Public Class Methods

common_time() click to toggle source
# File lib/head_music/meter.rb, line 24
def self.common_time
  get(:common_time)
end
cut_time() click to toggle source
# File lib/head_music/meter.rb, line 28
def self.cut_time
  get(:cut_time)
end
default() click to toggle source
# File lib/head_music/meter.rb, line 20
def self.default
  get('4/4')
end
get(identifier) click to toggle source
# File lib/head_music/meter.rb, line 12
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
new(top_number, bottom_number) click to toggle source
# File lib/head_music/meter.rb, line 32
def initialize(top_number, bottom_number)
  @top_number = top_number
  @bottom_number = bottom_number
end

Public Instance Methods

==(other) click to toggle source
# File lib/head_music/meter.rb, line 95
def ==(other)
  to_s == other.to_s
end
beat_strength(count, tick: 0) click to toggle source
# File lib/head_music/meter.rb, line 65
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_unit() click to toggle source
# File lib/head_music/meter.rb, line 82
def beat_unit
  @beat_unit ||=
    if compound?
      HeadMusic::RhythmicValue.new(HeadMusic::RhythmicUnit.for_denominator_value(bottom_number / 2), dots: 1)
    else
      HeadMusic::RhythmicValue.new(count_unit)
    end
end
beats_per_bar() click to toggle source
# File lib/head_music/meter.rb, line 57
def beats_per_bar
  compound? ? top_number / 3 : top_number
end
compound?() click to toggle source
# File lib/head_music/meter.rb, line 41
def compound?
  top_number > 3 && top_number / 3 == top_number / 3.0
end
count_unit() click to toggle source
# File lib/head_music/meter.rb, line 78
def count_unit
  HeadMusic::RhythmicUnit.for_denominator_value(bottom_number)
end
counts_per_bar() click to toggle source
# File lib/head_music/meter.rb, line 61
def counts_per_bar
  top_number
end
duple?() click to toggle source
# File lib/head_music/meter.rb, line 45
def duple?
  top_number == 2
end
quadruple?() click to toggle source
# File lib/head_music/meter.rb, line 53
def quadruple?
  top_number == 4
end
simple?() click to toggle source
# File lib/head_music/meter.rb, line 37
def simple?
  !compound?
end
strong_counts() click to toggle source
# File lib/head_music/meter.rb, line 99
def strong_counts
  @strong_counts ||= begin
    (1..counts_per_bar).select do |count|
      downbeat?(count) || strong_beat_in_duple?(count) || strong_beat_in_triple?(count)
    end
  end
end
strong_ticks() click to toggle source
# File lib/head_music/meter.rb, line 107
def strong_ticks
  @strong_ticks ||= [2, 3, 4].map { |sixths| ticks_per_count * (sixths / 6.0) }
end
ticks_per_count() click to toggle source
# File lib/head_music/meter.rb, line 74
def ticks_per_count
  @ticks_per_count ||= count_unit.ticks
end
to_s() click to toggle source
# File lib/head_music/meter.rb, line 91
def to_s
  [top_number, bottom_number].join('/')
end
triple?() click to toggle source
# File lib/head_music/meter.rb, line 49
def triple?
  (top_number % 3).zero?
end

Private Instance Methods

beat?(tick) click to toggle source
# File lib/head_music/meter.rb, line 129
def beat?(tick)
  tick.zero?
end
downbeat?(count, tick = 0) click to toggle source
# File lib/head_music/meter.rb, line 113
def downbeat?(count, tick = 0)
  beat?(tick) && count == 1
end
strong_beat?(count, tick = 0) click to toggle source
# File lib/head_music/meter.rb, line 117
def strong_beat?(count, tick = 0)
  beat?(tick) && (strong_beat_in_duple?(count, tick) || strong_beat_in_triple?(count, tick))
end
strong_beat_in_duple?(count, tick = 0) click to toggle source
# File lib/head_music/meter.rb, line 121
def strong_beat_in_duple?(count, tick = 0)
  beat?(tick) && (count == counts_per_bar / 2.0 + 1)
end
strong_beat_in_triple?(count, tick = 0) click to toggle source
# File lib/head_music/meter.rb, line 125
def strong_beat_in_triple?(count, tick = 0)
  beat?(tick) && (counts_per_bar % 3).zero? && counts_per_bar > 6 && count % 3 == 1
end