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.
33 34 35 36 |
# File 'lib/head_music/rudiment/meter.rb', line 33 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
25 26 27 |
# File 'lib/head_music/rudiment/meter.rb', line 25 def self.common_time get(:common_time) end |
.cut_time ⇒ Object
29 30 31 |
# File 'lib/head_music/rudiment/meter.rb', line 29 def self.cut_time get(:cut_time) end |
.default ⇒ Object
21 22 23 |
# File 'lib/head_music/rudiment/meter.rb', line 21 def self.default get("4/4") end |
.get(identifier) ⇒ Object
13 14 15 16 17 18 19 |
# 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 @meters ||= {} @meters[hash_key] ||= new(*time_signature_string.split("/")) end |
Instance Method Details
#==(other) ⇒ Object
115 116 117 |
# File 'lib/head_music/rudiment/meter.rb', line 115 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.
100 101 102 103 104 105 106 107 108 109 |
# File 'lib/head_music/rudiment/meter.rb', line 100 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)
178 179 180 |
# File 'lib/head_music/rudiment/meter.rb', line 178 def beat?(tick) tick.to_i.zero? end |
#beat_strength(count, tick: 0) ⇒ Object
70 71 72 73 74 75 76 77 |
# File 'lib/head_music/rudiment/meter.rb', line 70 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
90 91 92 |
# File 'lib/head_music/rudiment/meter.rb', line 90 def beat_value @beat_value ||= compound? ? dotted_denominator_value(bottom_number / 2) : count_unit_value end |
#beats_per_bar ⇒ Object
58 59 60 |
# File 'lib/head_music/rudiment/meter.rb', line 58 def compound? ? top_number / 3 : top_number end |
#compound? ⇒ Boolean
42 43 44 |
# File 'lib/head_music/rudiment/meter.rb', line 42 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”
86 87 88 |
# File 'lib/head_music/rudiment/meter.rb', line 86 def count_unit HeadMusic::Rudiment::RhythmicUnit.for_denominator_value(bottom_number) end |
#count_unit_value ⇒ Object (private)
144 145 146 |
# File 'lib/head_music/rudiment/meter.rb', line 144 def count_unit_value HeadMusic::Rudiment::RhythmicValue.new(count_unit) end |
#counts_per_bar ⇒ Object
62 63 64 |
# File 'lib/head_music/rudiment/meter.rb', line 62 def top_number end |
#counts_per_quarter_note ⇒ Object
66 67 68 |
# File 'lib/head_music/rudiment/meter.rb', line 66 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).
150 151 152 153 |
# File 'lib/head_music/rudiment/meter.rb', line 150 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)
155 156 157 |
# File 'lib/head_music/rudiment/meter.rb', line 155 def downbeat?(count, tick = 0) beat?(tick) && count == 1 end |
#duple? ⇒ Boolean
46 47 48 |
# File 'lib/head_music/rudiment/meter.rb', line 46 def duple? top_number == 2 end |
#quadruple? ⇒ Boolean
54 55 56 |
# File 'lib/head_music/rudiment/meter.rb', line 54 def quadruple? top_number == 4 end |
#simple? ⇒ Boolean
38 39 40 |
# File 'lib/head_music/rudiment/meter.rb', line 38 def simple? !compound? end |
#strong_beat?(count, tick = 0) ⇒ Boolean (private)
159 160 161 |
# File 'lib/head_music/rudiment/meter.rb', line 159 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)
163 164 165 166 167 168 |
# File 'lib/head_music/rudiment/meter.rb', line 163 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)
170 171 172 173 174 175 176 |
# File 'lib/head_music/rudiment/meter.rb', line 170 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
119 120 121 122 123 |
# File 'lib/head_music/rudiment/meter.rb', line 119 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
125 126 127 |
# File 'lib/head_music/rudiment/meter.rb', line 125 def strong_ticks @strong_ticks ||= [2, 3, 4].map { |sixths| ticks_per_count * (sixths / 6.0) } end |
#ticks_per_count ⇒ Object
79 80 81 |
# File 'lib/head_music/rudiment/meter.rb', line 79 def ticks_per_count @ticks_per_count ||= count_unit.ticks end |
#to_s ⇒ Object
111 112 113 |
# File 'lib/head_music/rudiment/meter.rb', line 111 def to_s [top_number, bottom_number].join("/") end |
#triple? ⇒ Boolean
50 51 52 |
# File 'lib/head_music/rudiment/meter.rb', line 50 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.
137 138 139 140 141 142 |
# File 'lib/head_music/rudiment/meter.rb', line 137 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 |