Class: HeadMusic::Rudiment::Meter
- Defined in:
- lib/head_music/rudiment/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
-
#bottom_number ⇒ Object
readonly
Returns the value of attribute bottom_number.
-
#top_number ⇒ Object
readonly
Returns the value of attribute top_number.
Class Method Summary collapse
Instance Method Summary collapse
-
#==(other) ⇒ Object
-
#beam_group_unit ⇒ Object
The span of one default beam group for this meter, as a RhythmicValue.
-
#beat?(tick) ⇒ Boolean
private
-
#beat_strength(count, tick: 0) ⇒ Object
-
#beat_value ⇒ Object
(also: #beat_unit)
-
#beats_per_bar ⇒ Object
-
#compound? ⇒ Boolean
-
#count_unit ⇒ Object
The rhythmic unit for the count (bottom number).
-
#count_unit_value ⇒ Object
private
-
#counts_per_bar ⇒ Object
-
#counts_per_quarter_note ⇒ Object
-
#dotted_denominator_value(denominator) ⇒ Object
private
A dotted value of the rhythmic unit for the given denominator (e.g. the dotted-quarter beat of a 6/8 meter for denominator 4).
-
#downbeat?(count, tick = 0) ⇒ Boolean
private
-
#duple? ⇒ Boolean
-
#initialize(top_number, bottom_number) ⇒ Meter
constructor
A new instance of Meter.
-
#quadruple? ⇒ Boolean
-
#simple? ⇒ Boolean
-
#strong_beat?(count, tick = 0) ⇒ Boolean
private
-
#strong_beat_in_duple?(count, tick = 0) ⇒ Boolean
private
-
#strong_beat_in_triple?(count, tick = 0) ⇒ Boolean
private
-
#strong_counts ⇒ Object
-
#strong_ticks ⇒ Object
-
#ticks_per_count ⇒ Object
-
#to_s ⇒ Object
-
#triple? ⇒ Boolean
-
#whole_bar_beam_group_unit ⇒ Object
private
For simple meters with an eighth-or-shorter denominator (e.g. 2/8, 3/8), the whole bar is a single beam group.
Constructor Details
#initialize(top_number, bottom_number) ⇒ Meter
Returns a new instance of Meter.
32 33 34 35 |
# File 'lib/head_music/rudiment/meter.rb', line 32 def initialize(top_number, bottom_number) @top_number = top_number.to_i @bottom_number = bottom_number.to_i end |
Instance Attribute Details
#bottom_number ⇒ Object (readonly)
Returns the value of attribute bottom_number.
6 7 8 |
# File 'lib/head_music/rudiment/meter.rb', line 6 def bottom_number @bottom_number end |
#top_number ⇒ Object (readonly)
Returns the value of attribute top_number.
6 7 8 |
# File 'lib/head_music/rudiment/meter.rb', line 6 def top_number @top_number end |
Class Method Details
.common_time ⇒ Object
24 25 26 |
# File 'lib/head_music/rudiment/meter.rb', line 24 def self.common_time get(:common_time) end |
.cut_time ⇒ Object
28 29 30 |
# File 'lib/head_music/rudiment/meter.rb', line 28 def self.cut_time get(:cut_time) end |
.default ⇒ Object
20 21 22 |
# File 'lib/head_music/rudiment/meter.rb', line 20 def self.default get("4/4") end |
.get(identifier) ⇒ Object
13 14 15 16 17 18 |
# File 'lib/head_music/rudiment/meter.rb', line 13 def self.get(identifier) identifier = identifier.to_s hash_key = HeadMusic::Utilities::HashKey.for(identifier) time_signature_string = NAMED[hash_key] || identifier fetch_or_register(hash_key, *time_signature_string.split("/")) end |
Instance Method Details
#==(other) ⇒ Object
114 115 116 |
# File 'lib/head_music/rudiment/meter.rb', line 114 def ==(other) to_s == other.to_s end |
#beam_group_unit ⇒ Object
The span of one default beam group for this meter, as a RhythmicValue. This is a distinct concern from #beat_value: it is the boundary unit used to decide where beams break.
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/head_music/rudiment/meter.rb', line 99 def beam_group_unit @beam_group_unit ||= if compound? beat_value elsif bottom_number >= 8 else count_unit_value end end |
#beat?(tick) ⇒ Boolean (private)
177 178 179 |
# File 'lib/head_music/rudiment/meter.rb', line 177 def beat?(tick) tick.to_i.zero? end |
#beat_strength(count, tick: 0) ⇒ Object
69 70 71 72 73 74 75 76 |
# File 'lib/head_music/rudiment/meter.rb', line 69 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_value ⇒ Object Also known as: beat_unit
89 90 91 |
# File 'lib/head_music/rudiment/meter.rb', line 89 def beat_value @beat_value ||= compound? ? dotted_denominator_value(bottom_number / 2) : count_unit_value end |
#beats_per_bar ⇒ Object
57 58 59 |
# File 'lib/head_music/rudiment/meter.rb', line 57 def compound? ? top_number / 3 : top_number end |
#compound? ⇒ Boolean
41 42 43 |
# File 'lib/head_music/rudiment/meter.rb', line 41 def compound? top_number > 3 && (top_number % 3).zero? end |
#count_unit ⇒ Object
The rhythmic unit for the count (bottom number). This unit is also used as “beats” in a sequencer context For example, “1:3:000”
85 86 87 |
# File 'lib/head_music/rudiment/meter.rb', line 85 def count_unit HeadMusic::Rudiment::RhythmicUnit.for_denominator_value(bottom_number) end |
#count_unit_value ⇒ Object (private)
143 144 145 |
# File 'lib/head_music/rudiment/meter.rb', line 143 def count_unit_value HeadMusic::Rudiment::RhythmicValue.new(count_unit) end |
#counts_per_bar ⇒ Object
61 62 63 |
# File 'lib/head_music/rudiment/meter.rb', line 61 def top_number end |
#counts_per_quarter_note ⇒ Object
65 66 67 |
# File 'lib/head_music/rudiment/meter.rb', line 65 def counts_per_quarter_note 0.25 / count_unit.relative_value end |
#dotted_denominator_value(denominator) ⇒ Object (private)
A dotted value of the rhythmic unit for the given denominator (e.g. the dotted-quarter beat of a 6/8 meter for denominator 4).
149 150 151 152 |
# File 'lib/head_music/rudiment/meter.rb', line 149 def dotted_denominator_value(denominator) unit = HeadMusic::Rudiment::RhythmicUnit.for_denominator_value(denominator) HeadMusic::Rudiment::RhythmicValue.new(unit, dots: 1) end |
#downbeat?(count, tick = 0) ⇒ Boolean (private)
154 155 156 |
# File 'lib/head_music/rudiment/meter.rb', line 154 def downbeat?(count, tick = 0) beat?(tick) && count == 1 end |
#duple? ⇒ Boolean
45 46 47 |
# File 'lib/head_music/rudiment/meter.rb', line 45 def duple? top_number == 2 end |
#quadruple? ⇒ Boolean
53 54 55 |
# File 'lib/head_music/rudiment/meter.rb', line 53 def quadruple? top_number == 4 end |
#simple? ⇒ Boolean
37 38 39 |
# File 'lib/head_music/rudiment/meter.rb', line 37 def simple? !compound? end |
#strong_beat?(count, tick = 0) ⇒ Boolean (private)
158 159 160 |
# File 'lib/head_music/rudiment/meter.rb', line 158 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) ⇒ Boolean (private)
162 163 164 165 166 167 |
# File 'lib/head_music/rudiment/meter.rb', line 162 def strong_beat_in_duple?(count, tick = 0) return false unless beat?(tick) return false unless .even? (count - 1) == / 2 end |
#strong_beat_in_triple?(count, tick = 0) ⇒ Boolean (private)
169 170 171 172 173 174 175 |
# File 'lib/head_music/rudiment/meter.rb', line 169 def strong_beat_in_triple?(count, tick = 0) return false unless beat?(tick) return false unless ( % 3).zero? return false if < 6 count % 3 == 1 end |
#strong_counts ⇒ Object
118 119 120 121 122 |
# File 'lib/head_music/rudiment/meter.rb', line 118 def strong_counts @strong_counts ||= (1..).select do |count| downbeat?(count) || strong_beat_in_duple?(count) || strong_beat_in_triple?(count) end end |
#strong_ticks ⇒ Object
124 125 126 |
# File 'lib/head_music/rudiment/meter.rb', line 124 def strong_ticks @strong_ticks ||= [2, 3, 4].map { |sixths| ticks_per_count * (sixths / 6.0) } end |
#ticks_per_count ⇒ Object
78 79 80 |
# File 'lib/head_music/rudiment/meter.rb', line 78 def ticks_per_count @ticks_per_count ||= count_unit.ticks end |
#to_s ⇒ Object
110 111 112 |
# File 'lib/head_music/rudiment/meter.rb', line 110 def to_s [top_number, bottom_number].join("/") end |
#triple? ⇒ Boolean
49 50 51 |
# File 'lib/head_music/rudiment/meter.rb', line 49 def triple? (top_number % 3).zero? end |
#whole_bar_beam_group_unit ⇒ Object (private)
For simple meters with an eighth-or-shorter denominator (e.g. 2/8, 3/8), the whole bar is a single beam group. A triple grouping (3/8) is a dotted value of the half-denominator unit; a duple grouping (2/8) spans the bar. Asymmetric meters (5/8, 7/16, …) are out of scope: their bar has no single power-of-two unit, so the group unit falls back to the count unit (each count its own group) rather than raising on a nil unit.
136 137 138 139 140 141 |
# File 'lib/head_music/rudiment/meter.rb', line 136 def return dotted_denominator_value(bottom_number / 2) if (top_number % 3).zero? unit = HeadMusic::Rudiment::RhythmicUnit.for_denominator_value(bottom_number / top_number) HeadMusic::Rudiment::RhythmicValue.new(unit || count_unit) end |