Module: Webmidi::Music::Chord

Defined in:
lib/webmidi/music/chord.rb

Constant Summary collapse

TYPES =
{
  major: [0, 4, 7],
  minor: [0, 3, 7],
  dim: [0, 3, 6],
  aug: [0, 4, 8],
  sus2: [0, 2, 7],
  sus4: [0, 5, 7],
  dom7: [0, 4, 7, 10],
  maj7: [0, 4, 7, 11],
  min7: [0, 3, 7, 10],
  dim7: [0, 3, 6, 9],
  half_dim7: [0, 3, 6, 10],
  aug7: [0, 4, 8, 10],
  min_maj7: [0, 3, 7, 11],
  dom9: [0, 4, 7, 10, 14],
  maj9: [0, 4, 7, 11, 14],
  min9: [0, 3, 7, 10, 14],
  dom11: [0, 4, 7, 10, 14, 17],
  dom13: [0, 4, 7, 10, 14, 17, 21],
  add9: [0, 4, 7, 14],
  six: [0, 4, 7, 9],
  min6: [0, 3, 7, 9],
  power: [0, 7]
}.freeze

Class Method Summary collapse

Class Method Details

.build(root, type = :major, inversion: 0, range: :strict) ⇒ Object



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

def build(root, type = :major, inversion: 0, range: :strict)
  validate_inversion!(inversion)
  root_midi = Note.to_midi(root)
  intervals = TYPES[type] || @custom_types[type]
  raise InvalidMessageError, "Unknown chord type: #{type}" unless intervals

  notes = intervals.map { |i| root_midi + i }

  inversion.times do
    notes.push(notes.shift + 12)
  end

  apply_range_policy(notes, range)
end

.define(name, intervals = nil, &block) ⇒ Object



50
51
52
53
54
55
# File 'lib/webmidi/music/chord.rb', line 50

def define(name, intervals = nil, &block)
  intervals = block.call(0) if block
  validate_intervals!(intervals)
  @custom_types[name] = intervals.dup.freeze
  self
end

.typesObject



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

def types
  TYPES.keys + @custom_types.keys
end