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 # normalized 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.
51 52 53 |
# File 'lib/mtk/core/pitch_class.rb', line 51 def value @value end |
Class Method Details
.[](name_or_value) ⇒ Object
Lookup a PitchClass by name or value.
71 72 73 74 75 76 77 |
# File 'lib/mtk/core/pitch_class.rb', line 71 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
109 110 111 |
# File 'lib/mtk/core/pitch_class.rb', line 109 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.
81 82 83 84 85 86 87 |
# File 'lib/mtk/core/pitch_class.rb', line 81 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
99 100 101 |
# File 'lib/mtk/core/pitch_class.rb', line 99 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)
146 147 148 149 |
# File 'lib/mtk/core/pitch_class.rb', line 146 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)
154 155 156 157 |
# File 'lib/mtk/core/pitch_class.rb', line 154 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
124 125 126 |
# File 'lib/mtk/core/pitch_class.rb', line 124 def <=> other @value <=> other.to_i end |
#==(other) ⇒ Object
Compare 2 pitch classes for equal values.
116 117 118 |
# File 'lib/mtk/core/pitch_class.rb', line 116 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
168 169 170 171 172 173 174 175 176 177 |
# File 'lib/mtk/core/pitch_class.rb', line 168 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
161 162 163 164 |
# File 'lib/mtk/core/pitch_class.rb', line 161 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
140 141 142 |
# File 'lib/mtk/core/pitch_class.rb', line 140 def to_f @value.to_f end |
#to_i ⇒ Object
This pitch class’s integer #value
135 136 137 |
# File 'lib/mtk/core/pitch_class.rb', line 135 def to_i @value.to_i end |
#to_s ⇒ Object
This pitch class’s normalized #name.
130 131 132 |
# File 'lib/mtk/core/pitch_class.rb', line 130 def to_s @name.to_s end |