class MultimediaParadise::Chord

Attributes

notes[R]

Public Class Methods

new(notes) click to toggle source
#

initialize

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 16
def initialize(notes)
  if notes.size < 2
    raise ArgumentError, 'Chords must have at least two notes'
  end
  @notes = Set.new(notes) { |note|
    if note.is_a?(Note)
      note
    else
      Note.new(note)
    end
  }
end
parse_chord_string( chord_string, assumed_octave = nil ) click to toggle source
#

MultimediaParadise::Chord.parse_chord_string

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 151
def self.parse_chord_string(
    chord_string,
    assumed_octave = nil
  )
  if note_string_match = chord_string.match(/^([A-Ga-g])([#b]?)([^\d]*)(\d*)$/)
    full_string, note, accidental, interval, octave = note_string_match.to_a
    if note.empty? && assumed_octave.nil?
      raise ArgumentError, 'No octave found and no octave assumed.'
    end
    # ===================================================================== #
    # Build a new Note here, which will also be returned.
    # full_string is irrelevant though.
    # ===================================================================== #
    Note.new(
      note + accidental + octave, assumed_octave
    ).chord(interval) { full_string }
  end
end

Public Instance Methods

==(other_chord) click to toggle source
#

==

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 46
def ==(other_chord)
  self.eql?(other_chord)
end
describe() click to toggle source
#

describe

Describe the various minor and major chords.

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 64
def describe
  note_array = @notes.to_a.sort
  distances = (1...note_array.size).map { |i|
    note_array[0].distance_to(note_array[i])
  }
  quality = case distances
  when [4, 7]
    :major
  when [3, 7]
    :minor
  when [3, 6]
    :diminished
  when [4, 8]
    :augmented
  when [4, 7, 11]
    :major_7
  when [3, 7, 10]
    :minor_7
  when [3, 6, 9]
    :diminished_7
  when [3, 6, 10]
    :half_diminished_7
  when [4, 8, 10]
    :augmented_7
  end
  [note_array.first.letter, quality]
end
eql?(other_chord) click to toggle source
#

eql?

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 32
def eql?(other_chord)
  @notes == other_chord.notes
end
first_inversion() click to toggle source
#

first_inversion

Calls inversion(1)

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 126
def first_inversion
  self.inversion(1)
end
hash() click to toggle source
#

hash

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 39
def hash
  @notes.hash
end
inversion(amount) click to toggle source
#

inversion

Give the n-th inversion of the chord which simply adjusts the lowest N notes up by one octave.

@returns [Chord]: the specified inversion of chord

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 107
def inversion(amount)
  if amount < 1
    raise ArgumentError,
      'Inversion amount must be greater than or equal to 1'
  end
  if amount >= @notes.size
    raise ArgumentError,
      'Not enough notes in chord for a proper inversion.'
  end
  note_array = @notes.to_a.sort
  notes = (0 .. .amount).map { note_array.shift.adjust_by_semitones(12) }
  Chord.new(notes + note_array)
end
note_strings() click to toggle source
#

note_strings

Spec and implement.

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 55
def note_strings
  Set.new(@notes.map(&:note_string))
end
second_inversion() click to toggle source
#

second_inversion

Calls inversion(2)

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 135
def second_inversion
  self.inversion(2)
end
third_inversion() click to toggle source
#

third_inversion

Calls inversion(3)

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 144
def third_inversion
  self.inversion(3)
end
to_s() click to toggle source
#

to_s

#
# File lib/multimedia_paradise/multimedia/chord.rb, line 95
def to_s
  @notes.to_a.sort.map(&:to_s).join(' / ')
end