class HeadMusic::PitchSet

A PitchSet is a collection of one or more pitches. See also: PitchClassSet

Constants

TERTIAN_SONORITIES

Attributes

pitches[R]

Public Class Methods

new(pitches) click to toggle source
# File lib/head_music/pitch_set.rb, line 24
def initialize(pitches)
  @pitches = pitches.map { |pitch| HeadMusic::Pitch.get(pitch) }.sort.uniq
end

Public Instance Methods

==(other) click to toggle source
# File lib/head_music/pitch_set.rb, line 87
def ==(other)
  pitches.sort == other.pitches.sort
end
augmented_triad?() click to toggle source
# File lib/head_music/pitch_set.rb, line 119
def augmented_triad?
  [%w[M3 M3], %w[M3 d4], %w[d4 M3]].include? reduction_diatonic_intervals.map(&:shorthand)
end
bass_pitch() click to toggle source
# File lib/head_music/pitch_set.rb, line 75
def bass_pitch
  @bass_pitch ||= pitches.first
end
consonant_triad?() click to toggle source
# File lib/head_music/pitch_set.rb, line 103
def consonant_triad?
  major_triad? || minor_triad?
end
diatonic_intervals() click to toggle source
# File lib/head_music/pitch_set.rb, line 40
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() click to toggle source
# File lib/head_music/pitch_set.rb, line 46
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?() click to toggle source
# File lib/head_music/pitch_set.rb, line 115
def diminished_triad?
  [%w[m3 m3], %w[m3 A4], %w[A4 m3]].include? reduction_diatonic_intervals.map(&:shorthand)
end
eleventh_chord?() click to toggle source
# File lib/head_music/pitch_set.rb, line 159
def eleventh_chord?
  hexachord? && tertian?
end
equivalent?(other) click to toggle source
# File lib/head_music/pitch_set.rb, line 91
def equivalent?(other)
  pitch_classes.sort == other.pitch_classes.sort
end
first_inversion_seventh_chord?() click to toggle source
# File lib/head_music/pitch_set.rb, line 143
def first_inversion_seventh_chord?
  tetrachord? && reduction.uninvert.diatonic_intervals.all?(&:third?)
end
first_inversion_triad?() click to toggle source
# File lib/head_music/pitch_set.rb, line 127
def first_inversion_triad?
  trichord? && reduction.uninvert.diatonic_intervals.all?(&:third?)
end
inspect() click to toggle source
# File lib/head_music/pitch_set.rb, line 79
def inspect
  pitches.map(&:to_s).join(' ')
end
integer_notation() click to toggle source
# File lib/head_music/pitch_set.rb, line 56
def integer_notation
  @integer_notation ||= begin
    return [] if pitches.empty?
    diatonic_intervals_above_bass_pitch.map { |interval| interval.semitones % 12 }.flatten.sort.unshift(0)
  end
end
invert() click to toggle source
# File lib/head_music/pitch_set.rb, line 63
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?() click to toggle source
# File lib/head_music/pitch_set.rb, line 107
def major_triad?
  [%w[M3 m3], %w[m3 P4], %w[P4 M3]].include? reduction_diatonic_intervals.map(&:shorthand)
end
minor_triad?() click to toggle source
# File lib/head_music/pitch_set.rb, line 111
def minor_triad?
  [%w[m3 M3], %w[M3 P4], %w[P4 m3]].include? reduction_diatonic_intervals.map(&:shorthand)
end
ninth_chord?() click to toggle source
# File lib/head_music/pitch_set.rb, line 155
def ninth_chord?
  pentachord? && tertian?
end
pitch_class_set() click to toggle source
# File lib/head_music/pitch_set.rb, line 32
def pitch_class_set
  @pitch_class_set ||= HeadMusic::PitchClassSet.new(pitch_classes)
end
pitch_classes() click to toggle source
# File lib/head_music/pitch_set.rb, line 28
def pitch_classes
  @pitch_classes ||= reduction_pitches.map(&:pitch_class).uniq
end
pitches_above_bass_pitch() click to toggle source
# File lib/head_music/pitch_set.rb, line 52
def pitches_above_bass_pitch
  @pitches_above_bass_pitch ||= pitches.drop(1)
end
reduction() click to toggle source
# File lib/head_music/pitch_set.rb, line 36
def reduction
  @reduction ||= HeadMusic::PitchSet.new(reduction_pitches)
end
root_position_seventh_chord?() click to toggle source
# File lib/head_music/pitch_set.rb, line 139
def root_position_seventh_chord?
  tetrachord? && reduction_diatonic_intervals.all?(&:third?)
end
root_position_triad?() click to toggle source
# File lib/head_music/pitch_set.rb, line 123
def root_position_triad?
  trichord? && reduction_diatonic_intervals.all?(&:third?)
end
scale_degrees() click to toggle source
# File lib/head_music/pitch_set.rb, line 178
def scale_degrees
  @scale_degrees ||= pitches.empty? ? [] : scale_degrees_above_bass_pitch.unshift(1)
end
scale_degrees_above_bass_pitch() click to toggle source
# File lib/head_music/pitch_set.rb, line 182
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?() click to toggle source
# File lib/head_music/pitch_set.rb, line 147
def second_inversion_seventh_chord?
  tetrachord? && reduction.uninvert.uninvert.diatonic_intervals.all?(&:third?)
end
second_inversion_triad?() click to toggle source
# File lib/head_music/pitch_set.rb, line 131
def second_inversion_triad?
  trichord? && reduction.invert.diatonic_intervals.all?(&:third?)
end
seventh_chord?() click to toggle source
# File lib/head_music/pitch_set.rb, line 135
def seventh_chord?
  tetrachord? && tertian?
end
size() click to toggle source
# File lib/head_music/pitch_set.rb, line 95
def size
  pitches.length
end
tertian?() click to toggle source
# File lib/head_music/pitch_set.rb, line 167
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?() click to toggle source
# File lib/head_music/pitch_set.rb, line 151
def third_inversion_seventh_chord?
  tetrachord? && reduction.invert.diatonic_intervals.all?(&:third?)
end
thirteenth_chord?() click to toggle source
# File lib/head_music/pitch_set.rb, line 163
def thirteenth_chord?
  heptachord? && tertian?
end
to_s() click to toggle source
# File lib/head_music/pitch_set.rb, line 83
def to_s
  pitches.map(&:to_s).join(' ')
end
triad?() click to toggle source
# File lib/head_music/pitch_set.rb, line 99
def triad?
  trichord? && tertian?
end
uninvert() click to toggle source
# File lib/head_music/pitch_set.rb, line 69
def uninvert
  inverted_pitch = pitches[-1] - HeadMusic::DiatonicInterval.get('perfect octave')
  new_pitches = [inverted_pitch] + pitches[0..-2]
  HeadMusic::PitchSet.new(new_pitches)
end

Private Instance Methods

reduction_pitches() click to toggle source
# File lib/head_music/pitch_set.rb, line 188
def reduction_pitches
  pitches.map do |pitch|
    pitch = HeadMusic::Pitch.fetch_or_create(pitch.spelling, pitch.register - 1) while pitch > bass_pitch + 12
    pitch
  end.sort
end