Class: HeadMusic::Rudiment::RhythmicUnit
- Includes:
- Comparable, Named
- Defined in:
- lib/head_music/rudiment/rhythmic_unit.rb
Overview
A rhythmic unit is a rudiment of duration consisting of doublings and divisions of a whole note.
Defined Under Namespace
Classes: Parser
Constant Summary collapse
- RHYTHMIC_UNITS_DATA =
YAML.load_file(File.("rhythmic_units.yml", __dir__)).freeze
- AMERICAN_MULTIPLES_NAMES =
[ "whole", "double whole", "longa", "maxima" ].freeze
- AMERICAN_DIVISIONS_NAMES =
[ "whole", "half", "quarter", "eighth", "sixteenth", "thirty-second", "sixty-fourth", "hundred twenty-eighth", "two hundred fifty-sixth" ].freeze
- AMERICAN_DURATIONS =
(AMERICAN_MULTIPLES_NAMES + AMERICAN_DIVISIONS_NAMES).freeze
- PATTERN =
/#{Regexp.union(AMERICAN_DURATIONS)}/i- BRITISH_MULTIPLES_NAMES =
British terminology for note values longer than a whole note
%w[semibreve breve longa maxima].freeze
- BRITISH_DIVISIONS_NAMES =
British terminology for standard note divisions
%w[ semibreve minim crotchet quaver semiquaver demisemiquaver hemidemisemiquaver semihemidemisemiquaver demisemihemidemisemiquaver ].freeze
- NOTEHEADS =
Notehead symbols used for different note values
{ maxima: 8.0, longa: 4.0, breve: 2.0, open: [0.5, 1.0], closed: :default }.freeze
Instance Attribute Summary collapse
-
#alias_name_keys ⇒ Object
included
from Named
readonly
Returns the value of attribute alias_name_keys.
-
#denominator ⇒ Object
readonly
Returns the value of attribute denominator.
-
#name_key ⇒ Object
included
from Named
readonly
Returns the value of attribute name_key.
-
#numerator ⇒ Object
readonly
Returns the value of attribute numerator.
Class Method Summary collapse
-
.all ⇒ Object
-
.all_normalized_names ⇒ Object
-
.for_denominator_value(denominator) ⇒ Object
-
.get(name) ⇒ Object
-
.normalize_name(name) ⇒ Object
-
.valid_name?(name) ⇒ Boolean
Check if a name represents a valid rhythmic unit.
Instance Method Summary collapse
-
#<=>(other) ⇒ Object
-
#british_equivalent(american_names, british_names) ⇒ Object
private
Translate this unit’s American name to its British equivalent, matched by position in the parallel American/British name arrays.
-
#british_name ⇒ Object
-
#common? ⇒ Boolean
Returns true if this note value is commonly used in modern notation.
-
#denominator_exponent ⇒ Object
private
-
#ensure_localized_name(name:, locale_code: Locale::DEFAULT_CODE, abbreviation: nil) ⇒ Object
included
from Named
-
#exponent_from(american_names, british_names) ⇒ Object
private
-
#flags ⇒ Object
-
#initialize(canonical_name) ⇒ RhythmicUnit
constructor
A new instance of RhythmicUnit.
-
#localized_name(locale_code: Locale::DEFAULT_CODE) ⇒ Object
included
from Named
-
#localized_name_in_default_locale ⇒ Object
included
from Named
private
-
#localized_name_in_locale_matching_language(locale) ⇒ Object
included
from Named
private
-
#localized_name_in_matching_locale(locale) ⇒ Object
included
from Named
private
-
#localized_names ⇒ Object
included
from Named
Returns an array of LocalizedName instances that are synonymous with the name.
-
#name(locale_code: Locale::DEFAULT_CODE) ⇒ Object
included
from Named
-
#name=(name) ⇒ Object
included
from Named
-
#normalized_keys(names) ⇒ Object
private
-
#notehead ⇒ Object
-
#numerator_exponent ⇒ Object
private
-
#own_british_name ⇒ Object
private
-
#relative_value ⇒ Object
-
#stemmed? ⇒ Boolean
-
#ticks ⇒ Object
Constructor Details
#initialize(canonical_name) ⇒ RhythmicUnit
Returns a new instance of RhythmicUnit.
79 80 81 82 83 84 85 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 79 def initialize(canonical_name) raise ArgumentError, "Name cannot be nil or empty" if canonical_name.to_s.strip.empty? self.name = canonical_name @numerator = 2**numerator_exponent @denominator = 2**denominator_exponent end |
Instance Attribute Details
#alias_name_keys ⇒ Object (readonly) Originally defined in module Named
Returns the value of attribute alias_name_keys.
#denominator ⇒ Object (readonly)
Returns the value of attribute denominator.
52 53 54 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 52 def denominator @denominator end |
#name_key ⇒ Object (readonly) Originally defined in module Named
Returns the value of attribute name_key.
#numerator ⇒ Object (readonly)
Returns the value of attribute numerator.
52 53 54 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 52 def numerator @numerator end |
Class Method Details
.all ⇒ Object
62 63 64 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 62 def self.all @all ||= (AMERICAN_MULTIPLES_NAMES.reverse + AMERICAN_DIVISIONS_NAMES).uniq.map { |name| get(name) }.compact end |
.all_normalized_names ⇒ Object
72 73 74 75 76 77 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 72 def self.all_normalized_names @all_normalized_names ||= [ AMERICAN_MULTIPLES_NAMES, AMERICAN_DIVISIONS_NAMES, BRITISH_MULTIPLES_NAMES, BRITISH_DIVISIONS_NAMES ].flat_map { |names| names.map { |name| normalize_name(name) } }.uniq end |
.for_denominator_value(denominator) ⇒ Object
42 43 44 45 46 47 48 49 50 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 42 def self.for_denominator_value(denominator) return nil unless denominator.is_a?(Numeric) && denominator > 0 return nil unless (denominator & (denominator - 1)) == 0 # Check if power of 2 index = Math.log2(denominator).to_i return nil if index >= AMERICAN_DIVISIONS_NAMES.length get(AMERICAN_DIVISIONS_NAMES[index]) end |
.get(name) ⇒ Object
54 55 56 57 58 59 60 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 54 def self.get(name) # Use the parser to handle tempo shorthand and other formats parsed_name = HeadMusic::Rudiment::RhythmicUnit::Parser.parse(name) return nil unless parsed_name get_by_name(parsed_name) end |
.normalize_name(name) ⇒ Object
132 133 134 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 132 def self.normalize_name(name) name.to_s.gsub(/\W+/, "_") end |
.valid_name?(name) ⇒ Boolean
Check if a name represents a valid rhythmic unit
67 68 69 70 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 67 def self.valid_name?(name) normalized = normalize_name(name) all_normalized_names.include?(normalized) end |
Instance Method Details
#<=>(other) ⇒ Object
118 119 120 121 122 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 118 def <=>(other) return nil unless other.is_a?(self.class) relative_value <=> other.relative_value end |
#british_equivalent(american_names, british_names) ⇒ Object (private)
Translate this unit’s American name to its British equivalent, matched by position in the parallel American/British name arrays.
140 141 142 143 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 140 def british_equivalent(american_names, british_names) index = american_names.index(name) index && british_names[index] end |
#british_name ⇒ Object
124 125 126 127 128 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 124 def british_name british_equivalent(AMERICAN_MULTIPLES_NAMES, BRITISH_MULTIPLES_NAMES) || british_equivalent(AMERICAN_DIVISIONS_NAMES, BRITISH_DIVISIONS_NAMES) || own_british_name end |
#common? ⇒ Boolean
Returns true if this note value is commonly used in modern notation
114 115 116 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 114 def common? AMERICAN_DIVISIONS_NAMES[0..6].include?(name) || BRITISH_DIVISIONS_NAMES[0..6].include?(name) end |
#denominator_exponent ⇒ Object (private)
153 154 155 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 153 def denominator_exponent exponent_from(AMERICAN_DIVISIONS_NAMES, BRITISH_DIVISIONS_NAMES) end |
#ensure_localized_name(name:, locale_code: Locale::DEFAULT_CODE, abbreviation: nil) ⇒ Object Originally defined in module Named
#exponent_from(american_names, british_names) ⇒ Object (private)
157 158 159 160 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 157 def exponent_from(american_names, british_names) key = self.class.normalize_name(name) normalized_keys(american_names).index(key) || normalized_keys(british_names).index(key) || 0 end |
#flags ⇒ Object
105 106 107 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 105 def flags AMERICAN_DIVISIONS_NAMES.include?(name) ? [AMERICAN_DIVISIONS_NAMES.index(name) - 2, 0].max : 0 end |
#localized_name(locale_code: Locale::DEFAULT_CODE) ⇒ Object Originally defined in module Named
#localized_name_in_default_locale ⇒ Object (private) Originally defined in module Named
#localized_name_in_locale_matching_language(locale) ⇒ Object (private) Originally defined in module Named
#localized_name_in_matching_locale(locale) ⇒ Object (private) Originally defined in module Named
#localized_names ⇒ Object Originally defined in module Named
Returns an array of LocalizedName instances that are synonymous with the name.
#name(locale_code: Locale::DEFAULT_CODE) ⇒ Object Originally defined in module Named
#name=(name) ⇒ Object Originally defined in module Named
#normalized_keys(names) ⇒ Object (private)
162 163 164 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 162 def normalized_keys(names) names.map { |name| self.class.normalize_name(name) } end |
#notehead ⇒ Object
95 96 97 98 99 100 101 102 103 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 95 def notehead value = relative_value return :maxima if value == NOTEHEADS[:maxima] return :longa if value == NOTEHEADS[:longa] return :breve if value == NOTEHEADS[:breve] return :open if NOTEHEADS[:open].include?(value) :closed end |
#numerator_exponent ⇒ Object (private)
149 150 151 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 149 def numerator_exponent exponent_from(AMERICAN_MULTIPLES_NAMES, BRITISH_MULTIPLES_NAMES) end |
#own_british_name ⇒ Object (private)
145 146 147 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 145 def own_british_name name if BRITISH_MULTIPLES_NAMES.include?(name) || BRITISH_DIVISIONS_NAMES.include?(name) end |
#relative_value ⇒ Object
87 88 89 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 87 def relative_value @numerator.to_f / @denominator end |
#stemmed? ⇒ Boolean
109 110 111 |
# File 'lib/head_music/rudiment/rhythmic_unit.rb', line 109 def stemmed? relative_value < 1 end |