class Coltrane::Theory::RomanChord

This class deals with chords in roman notation. Ex: IVÂș.

Constants

DIGITS
NOTATION_REGEX
NOTATION_SUBSTITUTIONS

Public Class Methods

new(notation = nil, chord: nil, key: nil, scale: nil) click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 16
def initialize(notation = nil, chord: nil, key: nil, scale: nil)
  if notation.nil? && chord.nil? || key.nil? && scale.nil?
    raise WrongKeywordsError,
          '[notation, [scale: || key:]] '\
          '[chord:, [scale: || key:]] '\
  end
  @scale = scale || Key[key]
  if notation
    @notation = notation
  elsif chord
    @chord = chord.is_a?(String) ? Chord.new(name: chord) : chord
  end
end

Public Instance Methods

chord() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 47
def chord
  @chord ||= Chord.new root_note: root_note,
                       quality: quality
end
degree() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 30
def degree
  return @scale.degree_of_note(root_note) unless @chord.nil?
  d      = regexed_notation[:degree]
  @flats = d.count('b')
  d      = d.delete('b')
  @degree ||= DIGITS.index(d.upcase) + 1
end
function() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 91
def function
  return if @scale.name != 'Major'
  %w[Tonic Supertonic Mediant Subdominant
     Dominant Submediant Leading][degree - 1]
end
major?() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 56
def major?
  quality.has_major_third?
end
minor?() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 52
def minor?
  quality.has_minor_third?
end
notation() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 78
def notation
  q = case quality_name
      when 'm', 'M' then ''
      when 'm7', 'M' then '7'
      else quality_name
  end

  @notation ||= [
    roman_numeral,
    q
  ].join
end
quality() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 68
def quality
  return @chord.quality unless @chord.nil?
  ChordQuality.new(name: quality_name) if quality_name
end
quality_name() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 60
def quality_name
  return @chord.quality.name unless @chord.nil?
  q     = normalize_quality_name(regexed_notation[:quality])
  minor = 'm' if (!q.match? /dim|m7b5/) && !upcase?
  q     = [minor, q].join
  q.empty? ? 'M' : q
end
roman_numeral() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 38
def roman_numeral
  r = DIGITS[degree]
  minor? ? r.downcase : r
end
root_note() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 73
def root_note
  return @chord.root_note unless @chord.nil?
  @scale[degree] - @flats
end
upcase?() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 43
def upcase?
  !!(regexed_notation[:degree][0].match /[[:upper:]]/)
end

Private Instance Methods

normalize_quality_name(quality_name) click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 106
def normalize_quality_name(quality_name)
  NOTATION_SUBSTITUTIONS.reduce(quality_name) do |memo, subs|
    break memo if memo.empty?
    memo.gsub(*subs)
  end
end
regexed_notation() click to toggle source
# File lib/coltrane/theory/roman_chord.rb, line 99
def regexed_notation
  @regexed_notation ||= begin
    matchdata = @notation.match(NOTATION_REGEX)
    { degree: matchdata[1], quality: matchdata[2] }
  end
end