Class: HeadMusic::PitchSet
- Inherits:
-
Object
- Object
- HeadMusic::PitchSet
- Defined in:
- lib/head_music/pitch_set.rb
Overview
A PitchSet is a collection of one or more pitches. See also: PitchClassSet
Constant Summary collapse
- TERTIAN_SONORITIES =
{ implied_triad: [3], triad: [3, 5], seventh_chord: [3, 5, 7], ninth_chord: [2, 3, 5, 7], eleventh_chord: [2, 3, 4, 5, 7], thirteenth_chord: [2, 3, 4, 5, 6, 7] # a.k.a. diatonic scale }.freeze
Instance Attribute Summary collapse
-
#pitches ⇒ Object
readonly
Returns the value of attribute pitches.
Instance Method Summary collapse
- #==(other) ⇒ Object
- #augmented_triad? ⇒ Boolean
- #bass_pitch ⇒ Object
- #consonant_triad? ⇒ Boolean
- #diatonic_intervals ⇒ Object
- #diatonic_intervals_above_bass_pitch ⇒ Object
- #diminished_triad? ⇒ Boolean
- #eleventh_chord? ⇒ Boolean
- #equivalent?(other) ⇒ Boolean
- #first_inversion_seventh_chord? ⇒ Boolean
- #first_inversion_triad? ⇒ Boolean
-
#initialize(pitches) ⇒ PitchSet
constructor
A new instance of PitchSet.
- #inspect ⇒ Object
- #integer_notation ⇒ Object
- #invert ⇒ Object
- #major_triad? ⇒ Boolean
- #minor_triad? ⇒ Boolean
- #ninth_chord? ⇒ Boolean
- #pitch_class_set ⇒ Object
- #pitch_classes ⇒ Object
- #pitches_above_bass_pitch ⇒ Object
- #reduction ⇒ Object
- #root_position_seventh_chord? ⇒ Boolean
- #root_position_triad? ⇒ Boolean
- #scale_degrees ⇒ Object
- #scale_degrees_above_bass_pitch ⇒ Object
- #second_inversion_seventh_chord? ⇒ Boolean
- #second_inversion_triad? ⇒ Boolean
- #seventh_chord? ⇒ Boolean
- #size ⇒ Object
- #tertian? ⇒ Boolean
- #third_inversion_seventh_chord? ⇒ Boolean
- #thirteenth_chord? ⇒ Boolean
- #to_s ⇒ Object
- #triad? ⇒ Boolean
- #uninvert ⇒ Object
Constructor Details
Instance Attribute Details
#pitches ⇒ Object (readonly)
Returns the value of attribute pitches.
13 14 15 |
# File 'lib/head_music/pitch_set.rb', line 13 def pitches @pitches end |
Instance Method Details
#==(other) ⇒ Object
88 89 90 |
# File 'lib/head_music/pitch_set.rb', line 88 def ==(other) pitches.sort == other.pitches.sort end |
#augmented_triad? ⇒ Boolean
120 121 122 |
# File 'lib/head_music/pitch_set.rb', line 120 def augmented_triad? [%w[M3 M3], %w[M3 d4], %w[d4 M3]].include? reduction_diatonic_intervals.map(&:shorthand) end |
#bass_pitch ⇒ Object
76 77 78 |
# File 'lib/head_music/pitch_set.rb', line 76 def bass_pitch @bass_pitch ||= pitches.first end |
#consonant_triad? ⇒ Boolean
104 105 106 |
# File 'lib/head_music/pitch_set.rb', line 104 def consonant_triad? major_triad? || minor_triad? end |
#diatonic_intervals ⇒ Object
38 39 40 41 42 |
# File 'lib/head_music/pitch_set.rb', line 38 def diatonic_intervals @diatonic_intervals ||= pitches.each_cons(2).map do |pitch_pair| HeadMusic::DiatonicInterval.new(*pitch_pair) end end |
#diatonic_intervals_above_bass_pitch ⇒ Object
44 45 46 47 48 |
# File 'lib/head_music/pitch_set.rb', line 44 def diatonic_intervals_above_bass_pitch @diatonic_intervals_above_bass_pitch ||= pitches_above_bass_pitch.map do |pitch| HeadMusic::DiatonicInterval.new(bass_pitch, pitch) end end |
#diminished_triad? ⇒ Boolean
116 117 118 |
# File 'lib/head_music/pitch_set.rb', line 116 def diminished_triad? [%w[m3 m3], %w[m3 A4], %w[A4 m3]].include? reduction_diatonic_intervals.map(&:shorthand) end |
#eleventh_chord? ⇒ Boolean
160 161 162 |
# File 'lib/head_music/pitch_set.rb', line 160 def eleventh_chord? hexachord? && tertian? end |
#equivalent?(other) ⇒ Boolean
92 93 94 |
# File 'lib/head_music/pitch_set.rb', line 92 def equivalent?(other) pitch_classes.sort == other.pitch_classes.sort end |
#first_inversion_seventh_chord? ⇒ Boolean
144 145 146 |
# File 'lib/head_music/pitch_set.rb', line 144 def first_inversion_seventh_chord? tetrachord? && reduction.uninvert.diatonic_intervals.all?(&:third?) end |
#first_inversion_triad? ⇒ Boolean
128 129 130 |
# File 'lib/head_music/pitch_set.rb', line 128 def first_inversion_triad? trichord? && reduction.uninvert.diatonic_intervals.all?(&:third?) end |
#inspect ⇒ Object
80 81 82 |
# File 'lib/head_music/pitch_set.rb', line 80 def inspect pitches.map(&:to_s).join(" ") end |
#integer_notation ⇒ Object
54 55 56 57 58 59 60 61 62 |
# File 'lib/head_music/pitch_set.rb', line 54 def integer_notation # questions: # - should this be absolute? 0 = C? # - should there be both absolute and relative versions? @integer_notation ||= begin return [] if pitches.empty? diatonic_intervals_above_bass_pitch.map { |interval| interval.semitones % 12 }.flatten.sort.unshift(0).uniq end end |
#invert ⇒ Object
64 65 66 67 68 |
# File 'lib/head_music/pitch_set.rb', line 64 def invert inverted_pitch = pitches[0] + HeadMusic::DiatonicInterval.get("perfect octave") new_pitches = pitches.drop(1) + [inverted_pitch] HeadMusic::PitchSet.new(new_pitches) end |
#major_triad? ⇒ Boolean
108 109 110 |
# File 'lib/head_music/pitch_set.rb', line 108 def major_triad? [%w[M3 m3], %w[m3 P4], %w[P4 M3]].include? reduction_diatonic_intervals.map(&:shorthand) end |
#minor_triad? ⇒ Boolean
112 113 114 |
# File 'lib/head_music/pitch_set.rb', line 112 def minor_triad? [%w[m3 M3], %w[M3 P4], %w[P4 m3]].include? reduction_diatonic_intervals.map(&:shorthand) end |
#ninth_chord? ⇒ Boolean
156 157 158 |
# File 'lib/head_music/pitch_set.rb', line 156 def ninth_chord? pentachord? && tertian? end |
#pitch_class_set ⇒ Object
30 31 32 |
# File 'lib/head_music/pitch_set.rb', line 30 def pitch_class_set @pitch_class_set ||= HeadMusic::PitchClassSet.new(pitch_classes) end |
#pitch_classes ⇒ Object
26 27 28 |
# File 'lib/head_music/pitch_set.rb', line 26 def pitch_classes @pitch_classes ||= reduction_pitches.map(&:pitch_class).uniq end |
#pitches_above_bass_pitch ⇒ Object
50 51 52 |
# File 'lib/head_music/pitch_set.rb', line 50 def pitches_above_bass_pitch @pitches_above_bass_pitch ||= pitches.drop(1) end |
#reduction ⇒ Object
34 35 36 |
# File 'lib/head_music/pitch_set.rb', line 34 def reduction @reduction ||= HeadMusic::PitchSet.new(reduction_pitches) end |
#root_position_seventh_chord? ⇒ Boolean
140 141 142 |
# File 'lib/head_music/pitch_set.rb', line 140 def root_position_seventh_chord? tetrachord? && reduction_diatonic_intervals.all?(&:third?) end |
#root_position_triad? ⇒ Boolean
124 125 126 |
# File 'lib/head_music/pitch_set.rb', line 124 def root_position_triad? trichord? && reduction_diatonic_intervals.all?(&:third?) end |
#scale_degrees ⇒ Object
179 180 181 |
# File 'lib/head_music/pitch_set.rb', line 179 def scale_degrees @scale_degrees ||= pitches.empty? ? [] : scale_degrees_above_bass_pitch.unshift(1) end |
#scale_degrees_above_bass_pitch ⇒ Object
183 184 185 |
# File 'lib/head_music/pitch_set.rb', line 183 def scale_degrees_above_bass_pitch @scale_degrees_above_bass_pitch ||= diatonic_intervals_above_bass_pitch.map(&:simple_number).sort - [8] end |
#second_inversion_seventh_chord? ⇒ Boolean
148 149 150 |
# File 'lib/head_music/pitch_set.rb', line 148 def second_inversion_seventh_chord? tetrachord? && reduction.uninvert.uninvert.diatonic_intervals.all?(&:third?) end |
#second_inversion_triad? ⇒ Boolean
132 133 134 |
# File 'lib/head_music/pitch_set.rb', line 132 def second_inversion_triad? trichord? && reduction.invert.diatonic_intervals.all?(&:third?) end |
#seventh_chord? ⇒ Boolean
136 137 138 |
# File 'lib/head_music/pitch_set.rb', line 136 def seventh_chord? tetrachord? && tertian? end |
#size ⇒ Object
96 97 98 |
# File 'lib/head_music/pitch_set.rb', line 96 def size pitches.length end |
#tertian? ⇒ Boolean
168 169 170 171 172 173 174 175 176 177 |
# File 'lib/head_music/pitch_set.rb', line 168 def tertian? return false unless diatonic_intervals.any? inversion = reduction pitches.length.times do return true if TERTIAN_SONORITIES.value?(inversion.scale_degrees_above_bass_pitch) inversion = inversion.invert end false end |
#third_inversion_seventh_chord? ⇒ Boolean
152 153 154 |
# File 'lib/head_music/pitch_set.rb', line 152 def third_inversion_seventh_chord? tetrachord? && reduction.invert.diatonic_intervals.all?(&:third?) end |
#thirteenth_chord? ⇒ Boolean
164 165 166 |
# File 'lib/head_music/pitch_set.rb', line 164 def thirteenth_chord? heptachord? && tertian? end |
#to_s ⇒ Object
84 85 86 |
# File 'lib/head_music/pitch_set.rb', line 84 def to_s pitches.map(&:to_s).join(" ") end |
#triad? ⇒ Boolean
100 101 102 |
# File 'lib/head_music/pitch_set.rb', line 100 def triad? trichord? && tertian? end |