Class: MTK::Core::PitchClass
- Inherits:
-
Object
- Object
- MTK::Core::PitchClass
- Defined in:
- lib/mtk/core/pitch_class.rb
Overview
A set of all pitches that are an integer number of octaves apart. A Pitch has the same PitchClass as the pitches one or more octaves away.
Constant Summary collapse
- NAMES =
%w( C Db D Eb E F Gb G Ab A Bb B ).freeze
- VALID_NAMES_BY_VALUE =
All enharmonic names of the 12 pitch classes, including sharps, flats, double-sharps, and double-flats, organized such that each index contains the allowed names of the pitch class with a #value equal to that index.
[ # (valid names ), # value # preferred name %w( B# C Dbb ), # 0 # C %w( B## C# Db ), # 1 # Db %w( C## D Ebb ), # 2 # D %w( D# Eb Fbb ), # 3 # Eb %w( D## E Fb ), # 4 # E %w( E# F Gbb ), # 5 # F %w( E## F# Gb ), # 6 # Gb %w( F## G Abb ), # 7 # G %w( G# Ab ), # 8 # Ab %w( G## A Bbb ), # 9 # A %w( A# Bb Cbb ), # 10 # Bb %w( A## B Cb ) # 11 # B ].freeze
- VALID_NAMES =
All valid enharmonic pitch class names in a flat list.
VALID_NAMES_BY_VALUE.flatten.freeze
- VALUES_BY_NAME =
A mapping from valid names to the value of the pitch class with that name
Hash[ # a map from a list of name,value pairs VALID_NAMES_BY_VALUE.map.with_index do |valid_names,value| valid_names.map{|name| [name,value] } end.flatten(1) ].freeze
- PITCH_CLASSES =
All 12 pitch classes in the chromatic scale. The index of each pitch class is the pitch class’s numeric #value.
NAMES.map{|name| from_name name }.freeze
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
The name of this pitch class.
-
#value ⇒ Object
readonly
The value of this pitch class.
Class Method Summary collapse
-
.[](name_or_value) ⇒ Object
Lookup a PitchClass by name or value.
-
.from_f(value) ⇒ Object
return the pitch class with the given float rounded to the nearest integer, mod 12.
-
.from_name(name) ⇒ Object
(also: from_s)
Lookup a PitchClass by name.
-
.from_value(value) ⇒ Object
(also: from_i)
return the pitch class with the given integer value mod 12.
Instance Method Summary collapse
-
#+(interval) ⇒ Object
(also: #transpose)
Transpose this pitch class by adding it’s value to the value given (mod 12).
-
#-(interval) ⇒ Object
Transpose this pitch class by subtracing the given value from this value (mod 12).
-
#<=>(other) ⇒ Object
Compare a pitch class with another pitch class or integer value.
-
#==(other) ⇒ Object
Compare 2 pitch classes for equal values.
-
#distance_to(pitch_class) ⇒ Object
the smallest interval in semitones that needs to be added to this PitchClass to reach the given PitchClass.
-
#invert(center) ⇒ Object
Inverts (mirrors) the pitch class around the given center.
-
#to_f ⇒ Object
This pitch class’s #value as a floating point number.
-
#to_i ⇒ Object
This pitch class’s integer #value.
-
#to_s ⇒ Object
This pitch class’s normalized #name.
Instance Attribute Details
#name ⇒ Object (readonly)
The name of this pitch class. One of the NAMES defined by this class.
47 48 49 |
# File 'lib/mtk/core/pitch_class.rb', line 47 def name @name end |
#value ⇒ Object (readonly)
The value of this pitch class. An integer from 0..11 that indexes this pitch class in PITCH_CLASSES and the #name in NAMES.
This value is fairly arbitrary and just used for sorting purposes and mod 12 arithmetic when composing directly with pitch classes.
54 55 56 |
# File 'lib/mtk/core/pitch_class.rb', line 54 def value @value end |
Class Method Details
.[](name_or_value) ⇒ Object
Lookup a PitchClass by name or value.
74 75 76 77 78 79 80 |
# File 'lib/mtk/core/pitch_class.rb', line 74 def self.[] name_or_value @flyweight[name_or_value] ||= case name_or_value when String,Symbol then from_name(name_or_value) when Numeric then from_value(name_or_value.round) else raise ArgumentError.new("PitchClass.[] doesn't understand #{name_or_value.class}") end end |
.from_f(value) ⇒ Object
return the pitch class with the given float rounded to the nearest integer, mod 12
112 113 114 |
# File 'lib/mtk/core/pitch_class.rb', line 112 def self.from_f(value) from_i value.to_f.round end |
.from_name(name) ⇒ Object Also known as: from_s
Lookup a PitchClass by name.
84 85 86 87 88 89 90 |
# File 'lib/mtk/core/pitch_class.rb', line 84 def self.from_name(name) @flyweight[name] ||= ( valid_name = name.to_s.capitalize value = VALUES_BY_NAME[valid_name] or raise ArgumentError.new("Invalid PitchClass name: #{name}") new(valid_name,value) ) end |
.from_value(value) ⇒ Object Also known as: from_i
return the pitch class with the given integer value mod 12
102 103 104 |
# File 'lib/mtk/core/pitch_class.rb', line 102 def self.from_value(value) PITCH_CLASSES[value.to_i % 12] end |
Instance Method Details
#+(interval) ⇒ Object Also known as: transpose
Transpose this pitch class by adding it’s value to the value given (mod 12)
149 150 151 152 |
# File 'lib/mtk/core/pitch_class.rb', line 149 def + interval new_value = (value + interval.to_f).round self.class.from_value new_value end |
#-(interval) ⇒ Object
Transpose this pitch class by subtracing the given value from this value (mod 12)
157 158 159 160 |
# File 'lib/mtk/core/pitch_class.rb', line 157 def - interval new_value = (value - interval.to_f).round self.class.from_value new_value end |
#<=>(other) ⇒ Object
Compare a pitch class with another pitch class or integer value
127 128 129 |
# File 'lib/mtk/core/pitch_class.rb', line 127 def <=> other @value <=> other.to_i end |
#==(other) ⇒ Object
Compare 2 pitch classes for equal values.
119 120 121 |
# File 'lib/mtk/core/pitch_class.rb', line 119 def == other other.is_a? PitchClass and other.value == @value end |
#distance_to(pitch_class) ⇒ Object
the smallest interval in semitones that needs to be added to this PitchClass to reach the given PitchClass
171 172 173 174 175 176 177 178 179 180 |
# File 'lib/mtk/core/pitch_class.rb', line 171 def distance_to(pitch_class) delta = (pitch_class.value - value) % 12 if delta > 6 delta -= 12 elsif delta == 6 and to_i >= 6 # this is a special edge case to prevent endlessly ascending pitch sequences when alternating between two pitch classes a tritone apart delta = -6 end delta end |
#invert(center) ⇒ Object
Inverts (mirrors) the pitch class around the given center
164 165 166 167 |
# File 'lib/mtk/core/pitch_class.rb', line 164 def invert(center) delta = (2*(center.to_f - value)).round self + delta end |
#to_f ⇒ Object
This pitch class’s #value as a floating point number
143 144 145 |
# File 'lib/mtk/core/pitch_class.rb', line 143 def to_f @value.to_f end |
#to_i ⇒ Object
This pitch class’s integer #value
138 139 140 |
# File 'lib/mtk/core/pitch_class.rb', line 138 def to_i @value.to_i end |
#to_s ⇒ Object
This pitch class’s normalized #name.
133 134 135 |
# File 'lib/mtk/core/pitch_class.rb', line 133 def to_s @name.to_s end |