Class: Music::Chord

Inherits:
Object
  • Object
show all
Defined in:
lib/music/chord.rb

Constant Summary collapse

RULES =
{
  "5"  => ["1", "major 3", "5"],
  "m5" => ["1", "minor 3", "5"],

  "7"  => ["1", "major 3", "5", "major 7"],
  "m7" => ["1", "minor 3", "5", "minor 7"],
}
REGEXP =
/
  (?<root> [CDEFGAB][#♭b]? )
  (?<kind> m?\d*           )
/x

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Chord

Returns a new instance of Chord.

Examples:

Chord.new("Cm") == Chord.new("Cmin") #=> true

Parameters:

  • name (String)

    Name of the chord, in any form.



39
40
41
42
43
44
45
46
47
48
# File 'lib/music/chord.rb', line 39

def initialize(name)
  unless match = name.match(/^#{REGEXP}$/)
    raise ArgumentError, "invalid chord format: #{name}"
  end

  @root = Note.new(match[:root])

  @kind = match[:kind]
  @kind << "5" if @kind !~ /\d+/
end

Instance Attribute Details

#kindString (readonly)

Examples:

Chord.new("C7").kind #=> "7"

Returns:

  • (String)


32
33
34
# File 'lib/music/chord.rb', line 32

def kind
  @kind
end

#rootMusic::Note (readonly)

Examples:

Chord.new("C").root #=> #<Music::Note @letter="C">

Returns:



25
26
27
# File 'lib/music/chord.rb', line 25

def root
  @root
end

Instance Method Details

#==(other) ⇒ Object

Compares the names.



57
58
59
# File 'lib/music/chord.rb', line 57

def ==(other)
  self.name == other.name
end

#nameObject



50
51
52
# File 'lib/music/chord.rb', line 50

def name
  [root, kind].join
end

#notesArray<Music::Note>

Returns:



64
65
66
67
68
69
70
71
72
# File 'lib/music/chord.rb', line 64

def notes
  RULES[kind].map do |interval_name|
    quality  = interval_name[/^[a-z]+/] || "perfect"
    number   = interval_name[/\d+$/]
    interval = Interval.new(number.to_i, quality.to_sym)

    root.transpose_by(interval)
  end
end

#transpose_by(interval) ⇒ Music::Note

Examples:

major_third = Interval.new(3, :major)
Chord.new("C7").transpose_by(major_third) == Note.new("E7") #=> true
Note.new("E7").transpose_by(-major_third) == Note.new("C7") #=> true

Parameters:

Returns:



82
83
84
# File 'lib/music/chord.rb', line 82

def transpose_by(interval)
  Chord.new(root.transpose_by(interval).name + kind)
end

#transpose_down(interval) ⇒ Music::Note

Parameters:

Returns:

See Also:



102
103
104
# File 'lib/music/chord.rb', line 102

def transpose_down(interval)
  transpose_by(-interval)
end

#transpose_up(interval) ⇒ Music::Note

Parameters:

Returns:

See Also:



92
93
94
# File 'lib/music/chord.rb', line 92

def transpose_up(interval)
  transpose_by(interval)
end