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).
-
#counts_per_bar ⇒ Object
-
#counts_per_quarter_note ⇒ Object
-
#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
120 121 122 |
# File 'lib/head_music/rudiment/meter.rb', line 120 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.
105 106 107 108 109 110 111 112 113 114 |
# File 'lib/head_music/rudiment/meter.rb', line 105 def beam_group_unit @beam_group_unit ||= if compound? beat_value elsif bottom_number >= 8 else HeadMusic::Rudiment::RhythmicValue.new(count_unit) end end |
#beat?(tick) ⇒ Boolean (private)
174 175 176 |
# File 'lib/head_music/rudiment/meter.rb', line 174 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 93 94 95 96 97 |
# File 'lib/head_music/rudiment/meter.rb', line 90 def beat_value @beat_value ||= if compound? HeadMusic::Rudiment::RhythmicValue.new(HeadMusic::Rudiment::RhythmicUnit.for_denominator_value(bottom_number / 2), dots: 1) else HeadMusic::Rudiment::RhythmicValue.new(count_unit) end 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 |
#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 |
#downbeat?(count, tick = 0) ⇒ Boolean (private)
151 152 153 |
# File 'lib/head_music/rudiment/meter.rb', line 151 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)
155 156 157 |
# File 'lib/head_music/rudiment/meter.rb', line 155 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)
159 160 161 162 163 164 |
# File 'lib/head_music/rudiment/meter.rb', line 159 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)
166 167 168 169 170 171 172 |
# File 'lib/head_music/rudiment/meter.rb', line 166 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
124 125 126 127 128 |
# File 'lib/head_music/rudiment/meter.rb', line 124 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
130 131 132 |
# File 'lib/head_music/rudiment/meter.rb', line 130 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
116 117 118 |
# File 'lib/head_music/rudiment/meter.rb', line 116 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.
142 143 144 145 146 147 148 149 |
# File 'lib/head_music/rudiment/meter.rb', line 142 def if (top_number % 3).zero? HeadMusic::Rudiment::RhythmicValue.new(HeadMusic::Rudiment::RhythmicUnit.for_denominator_value(bottom_number / 2), dots: 1) else unit = HeadMusic::Rudiment::RhythmicUnit.for_denominator_value(bottom_number / top_number) HeadMusic::Rudiment::RhythmicValue.new(unit || count_unit) end end |