Class: HeadMusic::Analysis::ChordAnalysis
- Inherits:
-
Object
- Object
- HeadMusic::Analysis::ChordAnalysis
- Defined in:
- lib/head_music/analysis/chord_analysis.rb
Overview
Classifies a PitchCollection as a tertian chord: whether it is a triad, seventh, or extended chord; its triad quality (major/minor/diminished/ augmented); and its inversion. “Tertian” means the pitches, once reduced to within an octave and rotated, stack in thirds.
Constant Summary collapse
- TERTIAN_SONORITIES =
Scale-degree signatures (above the bass) of each tertian chord size, used to recognize a stack of thirds in any rotation.
{ 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
- TRIAD_PATTERNS =
The interval-shorthand pairs (bass-to-third, third-to-fifth) that spell each triad quality, in every inversion.
{ major: [%w[M3 m3], %w[m3 P4], %w[P4 M3]], minor: [%w[m3 M3], %w[M3 P4], %w[P4 m3]], diminished: [%w[m3 m3], %w[m3 A4], %w[A4 m3]], augmented: [%w[M3 M3], %w[M3 d4], %w[d4 M3]] }.freeze
Instance Attribute Summary collapse
-
#collection ⇒ Object
readonly
Returns the value of attribute collection.
Instance Method Summary collapse
-
#augmented_triad? ⇒ Boolean
-
#consonant_triad? ⇒ Boolean
-
#diminished_triad? ⇒ Boolean
-
#eleventh_chord? ⇒ Boolean
-
#first_inversion_seventh_chord? ⇒ Boolean
-
#first_inversion_triad? ⇒ Boolean
-
#initialize(collection) ⇒ ChordAnalysis
constructor
A new instance of ChordAnalysis.
-
#major_triad? ⇒ Boolean
-
#minor_triad? ⇒ Boolean
-
#ninth_chord? ⇒ Boolean
-
#root_position_seventh_chord? ⇒ Boolean
-
#root_position_triad? ⇒ Boolean
-
#second_inversion_seventh_chord? ⇒ Boolean
-
#second_inversion_triad? ⇒ Boolean
-
#seventh_chord? ⇒ Boolean
-
#stacked_in_thirds?(reduced_collection) ⇒ Boolean
private
-
#tertian? ⇒ Boolean
-
#third_inversion_seventh_chord? ⇒ Boolean
-
#thirteenth_chord? ⇒ Boolean
-
#triad? ⇒ Boolean
-
#triad_type?(type) ⇒ Boolean
private
Constructor Details
#initialize(collection) ⇒ ChordAnalysis
Returns a new instance of ChordAnalysis.
31 32 33 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 31 def initialize(collection) @collection = collection end |
Instance Attribute Details
#collection ⇒ Object (readonly)
Returns the value of attribute collection.
29 30 31 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 29 def collection @collection end |
Instance Method Details
#augmented_triad? ⇒ Boolean
55 56 57 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 55 def augmented_triad? triad_type?(:augmented) end |
#consonant_triad? ⇒ Boolean
39 40 41 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 39 def consonant_triad? major_triad? || minor_triad? end |
#diminished_triad? ⇒ Boolean
51 52 53 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 51 def diminished_triad? triad_type?(:diminished) end |
#eleventh_chord? ⇒ Boolean
95 96 97 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 95 def eleventh_chord? collection.hexachord? && tertian? end |
#first_inversion_seventh_chord? ⇒ Boolean
79 80 81 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 79 def first_inversion_seventh_chord? collection.tetrachord? && stacked_in_thirds?(collection.reduction.uninvert) end |
#first_inversion_triad? ⇒ Boolean
63 64 65 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 63 def first_inversion_triad? collection.trichord? && stacked_in_thirds?(collection.reduction.uninvert) end |
#major_triad? ⇒ Boolean
43 44 45 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 43 def major_triad? triad_type?(:major) end |
#minor_triad? ⇒ Boolean
47 48 49 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 47 def minor_triad? triad_type?(:minor) end |
#ninth_chord? ⇒ Boolean
91 92 93 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 91 def ninth_chord? collection.pentachord? && tertian? end |
#root_position_seventh_chord? ⇒ Boolean
75 76 77 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 75 def root_position_seventh_chord? collection.tetrachord? && stacked_in_thirds?(collection.reduction) end |
#root_position_triad? ⇒ Boolean
59 60 61 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 59 def root_position_triad? collection.trichord? && stacked_in_thirds?(collection.reduction) end |
#second_inversion_seventh_chord? ⇒ Boolean
83 84 85 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 83 def second_inversion_seventh_chord? collection.tetrachord? && stacked_in_thirds?(collection.reduction.uninvert.uninvert) end |
#second_inversion_triad? ⇒ Boolean
67 68 69 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 67 def second_inversion_triad? collection.trichord? && stacked_in_thirds?(collection.reduction.invert) end |
#seventh_chord? ⇒ Boolean
71 72 73 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 71 def seventh_chord? collection.tetrachord? && tertian? end |
#stacked_in_thirds?(reduced_collection) ⇒ Boolean (private)
120 121 122 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 120 def stacked_in_thirds?(reduced_collection) reduced_collection.diatonic_intervals.all?(&:third?) end |
#tertian? ⇒ Boolean
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 103 def tertian? return false unless collection.diatonic_intervals.any? inversion = collection.reduction collection.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
87 88 89 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 87 def third_inversion_seventh_chord? collection.tetrachord? && stacked_in_thirds?(collection.reduction.invert) end |
#thirteenth_chord? ⇒ Boolean
99 100 101 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 99 def thirteenth_chord? collection.heptachord? && tertian? end |
#triad? ⇒ Boolean
35 36 37 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 35 def triad? collection.trichord? && tertian? end |
#triad_type?(type) ⇒ Boolean (private)
116 117 118 |
# File 'lib/head_music/analysis/chord_analysis.rb', line 116 def triad_type?(type) TRIAD_PATTERNS[type].include?(collection.reduction_diatonic_intervals.map(&:shorthand)) end |