coltrane 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.bundle/config +2 -0
- data/.rspec +2 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +164 -0
- data/Guardfile +71 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +6 -0
- data/bin/_guard-core +17 -0
- data/bin/bundler +17 -0
- data/bin/coderay +17 -0
- data/bin/coltrane +11 -0
- data/bin/console +14 -0
- data/bin/erubis +17 -0
- data/bin/guard +17 -0
- data/bin/htmldiff +17 -0
- data/bin/kill-pry-rescue +17 -0
- data/bin/ldiff +17 -0
- data/bin/listen +17 -0
- data/bin/nokogiri +17 -0
- data/bin/pry +17 -0
- data/bin/rackup +17 -0
- data/bin/rails +17 -0
- data/bin/rake +17 -0
- data/bin/rdoc +17 -0
- data/bin/rescue +17 -0
- data/bin/ri +17 -0
- data/bin/rspec +17 -0
- data/bin/rubocop +17 -0
- data/bin/ruby-parse +17 -0
- data/bin/ruby-rewrite +17 -0
- data/bin/setup +8 -0
- data/bin/sprockets +17 -0
- data/bin/thor +17 -0
- data/bin/tilt +17 -0
- data/coltrane.gemspec +35 -0
- data/db/cache.sqlite3 +0 -0
- data/db/cache_test.sqlite3 +0 -0
- data/db/config.yml +11 -0
- data/db/schema.rb +30 -0
- data/lib/coltrane.rb +48 -0
- data/lib/coltrane/cadence.rb +4 -0
- data/lib/coltrane/chord.rb +81 -0
- data/lib/coltrane/chord_cache.rb +4 -0
- data/lib/coltrane/chord_quality.rb +48 -0
- data/lib/coltrane/classic_scales.rb +134 -0
- data/lib/coltrane/essential_guitar_chords.rb +82 -0
- data/lib/coltrane/fret_set.rb +0 -0
- data/lib/coltrane/guitar.rb +15 -0
- data/lib/coltrane/guitar_chord.rb +50 -0
- data/lib/coltrane/guitar_chord_finder.rb +98 -0
- data/lib/coltrane/guitar_note.rb +50 -0
- data/lib/coltrane/guitar_note_set.rb +61 -0
- data/lib/coltrane/guitar_representation.rb +96 -0
- data/lib/coltrane/guitar_string.rb +52 -0
- data/lib/coltrane/interval.rb +33 -0
- data/lib/coltrane/interval_sequence.rb +70 -0
- data/lib/coltrane/interval_set.rb +23 -0
- data/lib/coltrane/mode.rb +0 -0
- data/lib/coltrane/note.rb +98 -0
- data/lib/coltrane/note_set.rb +50 -0
- data/lib/coltrane/piano_representation.rb +58 -0
- data/lib/coltrane/pitch.rb +27 -0
- data/lib/coltrane/progression.rb +4 -0
- data/lib/coltrane/qualities.rb +115 -0
- data/lib/coltrane/scale.rb +139 -0
- data/lib/coltrane/scale_cache.rb +4 -0
- data/lib/coltrane/scale_chord.rb +4 -0
- data/lib/coltrane/version.rb +3 -0
- metadata +144 -0
| @@ -0,0 +1,70 @@ | |
| 1 | 
            +
            module Coltrane
         | 
| 2 | 
            +
              # It describes a sequence of intervals
         | 
| 3 | 
            +
              class IntervalSequence
         | 
| 4 | 
            +
                attr_reader :intervals
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def initialize(arg)
         | 
| 7 | 
            +
                  arg = [arg] if arg.class != Array
         | 
| 8 | 
            +
                  @intervals = arg.reduce([]) do |memo, arg_item|
         | 
| 9 | 
            +
                    case arg_item
         | 
| 10 | 
            +
                    when Numeric  then memo << Interval.new(arg_item)
         | 
| 11 | 
            +
                    when Interval then memo << arg_item
         | 
| 12 | 
            +
                    when NoteSet  then memo + intervals_from_note_set(arg_item)
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def intervals_from_note_set(note_set)
         | 
| 18 | 
            +
                  note_numbers = note_set.notes.collect(&:number)
         | 
| 19 | 
            +
                  root         = note_numbers.shift
         | 
| 20 | 
            +
                  note_numbers.reduce([Interval.new(0)]) do |memo, number|
         | 
| 21 | 
            +
                    number += 12 if number < root
         | 
| 22 | 
            +
                    memo << Interval.new(number - root)
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def reordered
         | 
| 27 | 
            +
                  IntervalSequence.new @intervals.sort_by!(&:number)
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def all
         | 
| 31 | 
            +
                  intervals
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def [](x)
         | 
| 35 | 
            +
                  intervals[x]
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def shift(ammount)
         | 
| 39 | 
            +
                  IntervalSequence.new(intervals.map do |i|
         | 
| 40 | 
            +
                    (i.number + ammount) % 12
         | 
| 41 | 
            +
                  end)
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def zero_it
         | 
| 45 | 
            +
                  self.shift(-intervals.first.number)
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def next_inversion
         | 
| 49 | 
            +
                  IntervalSequence.new(intervals.rotate(+1))
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def previous_inversion
         | 
| 53 | 
            +
                  IntervalSequence.new(intervals.rotate(-1))
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def inversions
         | 
| 57 | 
            +
                  Array.new(intervals.length) do |index|
         | 
| 58 | 
            +
                    IntervalSequence.new(interval.rotate(index))
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def numbers
         | 
| 63 | 
            +
                  intervals.collect(&:number)
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                def names
         | 
| 67 | 
            +
                  intervals.collect(&:name)
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            # class IntervalSet
         | 
| 3 | 
            +
            #   def initialize(*intervals)
         | 
| 4 | 
            +
            #     @intervals = intervals
         | 
| 5 | 
            +
            #     @number_of_frets = 24
         | 
| 6 | 
            +
            #     sum = @intervals.reduce(:+)
         | 
| 7 | 
            +
            #     sum < 12 && @intervals << 12 - sum
         | 
| 8 | 
            +
            #   end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            #   def to_s
         | 
| 11 | 
            +
            #     @intervals.to_s
         | 
| 12 | 
            +
            #   end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            #   def to_frets(offset = 0)
         | 
| 15 | 
            +
            #     frets = [-offset]
         | 
| 16 | 
            +
            #     i = 0
         | 
| 17 | 
            +
            #     while frets.last < @number_of_frets
         | 
| 18 | 
            +
            #       frets << frets.last + @intervals[i % @intervals.length]
         | 
| 19 | 
            +
            #       i += 1
         | 
| 20 | 
            +
            #     end
         | 
| 21 | 
            +
            #     frets
         | 
| 22 | 
            +
            #   end
         | 
| 23 | 
            +
            # end
         | 
| 
            File without changes
         | 
| @@ -0,0 +1,98 @@ | |
| 1 | 
            +
            module Coltrane
         | 
| 2 | 
            +
              # It describes a musical note, independent of octave
         | 
| 3 | 
            +
              class Note
         | 
| 4 | 
            +
                attr_reader :name
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                NOTES = {
         | 
| 7 | 
            +
                  'C'  => 0,
         | 
| 8 | 
            +
                  'C#' => 1,
         | 
| 9 | 
            +
                  'Db' => 1,
         | 
| 10 | 
            +
                  'D'  => 2,
         | 
| 11 | 
            +
                  'D#' => 3,
         | 
| 12 | 
            +
                  'Eb' => 3,
         | 
| 13 | 
            +
                  'E'  => 4,
         | 
| 14 | 
            +
                  'F'  => 5,
         | 
| 15 | 
            +
                  'F#' => 6,
         | 
| 16 | 
            +
                  'Gb' => 6,
         | 
| 17 | 
            +
                  'G'  => 7,
         | 
| 18 | 
            +
                  'G#' => 8,
         | 
| 19 | 
            +
                  'Ab' => 8,
         | 
| 20 | 
            +
                  'A'  => 9,
         | 
| 21 | 
            +
                  'A#' => 10,
         | 
| 22 | 
            +
                  'Bb' => 10,
         | 
| 23 | 
            +
                  'B'  => 11
         | 
| 24 | 
            +
                }.freeze
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def self.all
         | 
| 27 | 
            +
                  NOTES.keys.map {|n| Note.new(n)}
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def accident?
         | 
| 31 | 
            +
                  [1,3,6,8,10].include?(number)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def initialize(arg)
         | 
| 35 | 
            +
                  case arg
         | 
| 36 | 
            +
                  when String
         | 
| 37 | 
            +
                    raise "invalid note: #{arg}" unless valid_note?(arg)
         | 
| 38 | 
            +
                    @name = arg
         | 
| 39 | 
            +
                  when Numeric then @name = name_from_number(arg)
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def +(n)
         | 
| 44 | 
            +
                  case n
         | 
| 45 | 
            +
                    when Numeric then Note.new(number + n)
         | 
| 46 | 
            +
                    when Note then Chord.new(number + n.number)
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def -(n)
         | 
| 51 | 
            +
                  case n
         | 
| 52 | 
            +
                    when Numeric then Note.new(number + n)
         | 
| 53 | 
            +
                    when Note then Interval.new((number - n.number) % 12)
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def valid_note?(note_name)
         | 
| 58 | 
            +
                  NOTES.key?(note_name)
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                def number
         | 
| 62 | 
            +
                  NOTES[name]
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                def interval_to(note_name)
         | 
| 66 | 
            +
                  Interval.new(Note.new(note_name).number - number)
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def transpose_by(interval_number)
         | 
| 70 | 
            +
                  @name = name_from_number(number + interval_number)
         | 
| 71 | 
            +
                  self
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def guitar_notes
         | 
| 75 | 
            +
                  Guitar.strings.reduce([]) do |memo, guitar_string|
         | 
| 76 | 
            +
                    memo + in_guitar_string(guitar_string)
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                def on_guitar
         | 
| 81 | 
            +
                  GuitarNoteSet.new(guitar_notes).render
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                def in_guitar_string(guitar_string)
         | 
| 85 | 
            +
                  guitar_string.guitar_notes_for_note(self)
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                def in_guitar_string_region(guitar_string, region)
         | 
| 89 | 
            +
                  guitar_string.guitar_notes_for_note_in_region(self, region)
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                protected
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                def name_from_number(number)
         | 
| 95 | 
            +
                  NOTES.key(number % 12)
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            module Coltrane
         | 
| 2 | 
            +
              # It describes a set of notes
         | 
| 3 | 
            +
              class NoteSet
         | 
| 4 | 
            +
                attr_reader :notes
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def initialize(arg)
         | 
| 7 | 
            +
                  @notes = case arg
         | 
| 8 | 
            +
                           when String then notes_from_note_string(arg)
         | 
| 9 | 
            +
                           when Array  then notes_from_note_array(arg)
         | 
| 10 | 
            +
                           end
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def root_note
         | 
| 14 | 
            +
                  notes.sort_by(&:number).first
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def transpose_to(note_name)
         | 
| 18 | 
            +
                  transpose_by(root_note.interval_to(note_name).number)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def transpose_by(interval)
         | 
| 22 | 
            +
                  notes.map do |note|
         | 
| 23 | 
            +
                    note.transpose_by(interval)
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def guitar_notes
         | 
| 28 | 
            +
                  GuitarNoteSet.new(notes.map(&:guitar_notes).flatten)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def interval_sequence
         | 
| 32 | 
            +
                  IntervalSequence.new(self)
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                protected
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def notes_from_note_string(note_string)
         | 
| 38 | 
            +
                  notes_from_note_array(note_string.split(' '))
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def notes_from_note_array(note_array)
         | 
| 42 | 
            +
                  note_array.collect do |note|
         | 
| 43 | 
            +
                    case note
         | 
| 44 | 
            +
                    when String then Note.new(note)
         | 
| 45 | 
            +
                    when Note   then note
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            module Coltrane
         | 
| 2 | 
            +
              class PianoRepresentation
         | 
| 3 | 
            +
                PIANO_TEMPLATE = <<~ASCII
         | 
| 4 | 
            +
                  ┌─┬─┬┬─┬─╥─┬─┬┬─┬┬─┬─╥─┬─┬┬─┬─╥─┬─┬┬─┬┬─┬─┐
         | 
| 5 | 
            +
                  │ │ ││ │ ║ │ ││ ││ │ ║ │ ││ │ ║ │ ││ ││ │ │
         | 
| 6 | 
            +
                  │ │X││X│ ║ │X││X││X│ ║ │X││X│ ║ │X││X││X│ │
         | 
| 7 | 
            +
                  │ │X││X│ ║ │X││X││X│ ║ │X││X│ ║ │X││X││X│ │
         | 
| 8 | 
            +
                  │ ┕╥┙┕╥┙ ║ ┕╥┙┕╥┙┕╥┙ ║ ┕╥┙┕╥┙ ║ ┕╥┙┕╥┙┕╥┙ │
         | 
| 9 | 
            +
                  │XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX│
         | 
| 10 | 
            +
                  └──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──┘
         | 
| 11 | 
            +
                ASCII
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                class << self
         | 
| 14 | 
            +
                  def render_intervals(notes, ref_note)
         | 
| 15 | 
            +
                    output = place_black_notes(Paint[PIANO_TEMPLATE, 'gray'], notes, ref_note)
         | 
| 16 | 
            +
                    place_white_notes(output, notes, ref_note)
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  def place_white_notes(input, notes, ref_note)
         | 
| 20 | 
            +
                    white_notes = Scale.major.notes
         | 
| 21 | 
            +
                    i = 0
         | 
| 22 | 
            +
                    output_array = input.split("\n")
         | 
| 23 | 
            +
                    output_array[5].gsub!('XX') do |match|
         | 
| 24 | 
            +
                      note = white_notes[i%7]
         | 
| 25 | 
            +
                      interval_name = (note - ref_note).name
         | 
| 26 | 
            +
                      i += 1
         | 
| 27 | 
            +
                      notes.map(&:name).include?(note.name) ? Paint[interval_name, 'red'] : '  '
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                    output_array.join("\n")
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def place_black_notes(input, notes, ref_note)
         | 
| 34 | 
            +
                    black_notes  = Scale.pentatonic_major('C#',4).notes
         | 
| 35 | 
            +
                    output_array = input.split("\n")
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    i = 0
         | 
| 38 | 
            +
                    output_array[2].gsub!('X') do |match|
         | 
| 39 | 
            +
                      note = black_notes[i%5]
         | 
| 40 | 
            +
                      interval_name = (note - ref_note).name
         | 
| 41 | 
            +
                      i += 1
         | 
| 42 | 
            +
                      notes.map(&:name).include?(note.name) ? Paint[interval_name[0], 'red'] : ' '
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    i = 0
         | 
| 46 | 
            +
                    output_array[3].gsub!('X') do |match|
         | 
| 47 | 
            +
                      note = black_notes[i%5]
         | 
| 48 | 
            +
                      interval_name = (black_notes[i%5] - ref_note).name
         | 
| 49 | 
            +
                      i += 1
         | 
| 50 | 
            +
                      notes.map(&:name).include?(note.name) ? Paint[interval_name[1], 'red'] : ' '
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    output_array.join("\n")
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
            end
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            module Coltrane
         | 
| 2 | 
            +
              # It describes a pitch, like E4 or Bb5. It's like a note, but it has an octave
         | 
| 3 | 
            +
              class Pitch
         | 
| 4 | 
            +
                attr_reader :number
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def initialize(pitch)
         | 
| 7 | 
            +
                  case pitch
         | 
| 8 | 
            +
                  when String  then @number = number_from_name(pitch)
         | 
| 9 | 
            +
                  when Numeric then @number = pitch
         | 
| 10 | 
            +
                  when Pitch   then @number = pitch.number
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def number_from_name(pitch_string)
         | 
| 15 | 
            +
                  _, note, octaves = pitch_string.match(/(.*)(\d)/).to_a
         | 
| 16 | 
            +
                  Note.new(note).number + 12 * octaves.to_i
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def name
         | 
| 20 | 
            +
                  "#{note.name}#{number / 12}"
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def note
         | 
| 24 | 
            +
                  Note.new(number)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
| @@ -0,0 +1,115 @@ | |
| 1 | 
            +
            module Qualities
         | 
| 2 | 
            +
              CHORD_QUALITIES = {
         | 
| 3 | 
            +
               "5"          => [0, 7],
         | 
| 4 | 
            +
               "Msus2"      => [0, 2, 7],
         | 
| 5 | 
            +
               "dim"        => [0, 3, 6],
         | 
| 6 | 
            +
               "m"          => [0, 3, 7],
         | 
| 7 | 
            +
               "m#5"        => [0, 3, 8],
         | 
| 8 | 
            +
               "Mb5"        => [0, 4, 6],
         | 
| 9 | 
            +
               "M"          => [0, 4, 7],
         | 
| 10 | 
            +
               ""           => [0, 4, 7],
         | 
| 11 | 
            +
               "M#5"        => [0, 4, 8],
         | 
| 12 | 
            +
               "Mb6"        => [0, 4, 8],
         | 
| 13 | 
            +
               "7ndim5"     => [0, 4, 10],
         | 
| 14 | 
            +
               "Msus4"      => [0, 5, 7],
         | 
| 15 | 
            +
               "mb6b9"      => [0, 1, 3, 8],
         | 
| 16 | 
            +
               "addb9"      => [0, 1, 4, 7],
         | 
| 17 | 
            +
               "madd9"      => [0, 2, 3, 7],
         | 
| 18 | 
            +
               "Madd9"      => [0, 2, 4, 7],
         | 
| 19 | 
            +
               "sus24"      => [0, 2, 5, 7],
         | 
| 20 | 
            +
               "M#5add9"    => [0, 2, 4, 8],
         | 
| 21 | 
            +
               "9ndim5"     => [0, 2, 4, 10],
         | 
| 22 | 
            +
               "+add#9"     => [0, 3, 4, 8],
         | 
| 23 | 
            +
               "madd4"      => [0, 3, 5, 7],
         | 
| 24 | 
            +
               "4"          => [0, 3, 5, 10],
         | 
| 25 | 
            +
               "dim7"       => [0, 3, 6, 9],
         | 
| 26 | 
            +
               "m7"         => [0, 3, 7, 10],
         | 
| 27 | 
            +
               "mM7"        => [0, 3, 7, 11],
         | 
| 28 | 
            +
               "m7#5"       => [0, 3, 8, 10],
         | 
| 29 | 
            +
               "7b5"        => [0, 4, 6, 10],
         | 
| 30 | 
            +
               "7"          => [0, 4, 7, 10],
         | 
| 31 | 
            +
               "7#5"        => [0, 4, 8, 10],
         | 
| 32 | 
            +
               "7b13"       => [0, 4, 8, 10],
         | 
| 33 | 
            +
               "M7#5"       => [0, 4, 8, 11],
         | 
| 34 | 
            +
               "M7b6"       => [0, 4, 8, 11],
         | 
| 35 | 
            +
               "M7b5"       => [0, 4, 6, 11],
         | 
| 36 | 
            +
               "M7#5sus4"   => [0, 5, 8, 11],
         | 
| 37 | 
            +
               "7sus4"      => [0, 5, 7, 10],
         | 
| 38 | 
            +
               "7#5sus4"    => [0, 5, 8, 10],
         | 
| 39 | 
            +
               "M7sus4"     => [0, 5, 7, 11],
         | 
| 40 | 
            +
               "M6"         => [0, 4, 7, 9],
         | 
| 41 | 
            +
               "m7b5"       => [0, 3, 6, 10],
         | 
| 42 | 
            +
               "M7"         => [0, 4, 7, 11],
         | 
| 43 | 
            +
               "maj7"       => [0, 4, 7, 11],
         | 
| 44 | 
            +
               "mb6M7"      => [0, 3, 8, 11],
         | 
| 45 | 
            +
               "dimM7"      => [0, 3, 6, 11],
         | 
| 46 | 
            +
               "m6"         => [0, 3, 5, 7, 9],
         | 
| 47 | 
            +
               "m6/9"       => [0, 2, 3, 7, 9],
         | 
| 48 | 
            +
               "M6/9"       => [0, 2, 4, 7, 9],
         | 
| 49 | 
            +
               "M6#11"      => [0, 4, 6, 7, 9],
         | 
| 50 | 
            +
               "m7add11"    => [0, 3, 5, 7, 10],
         | 
| 51 | 
            +
               "dim7M7"     => [0, 3, 6, 9, 11],
         | 
| 52 | 
            +
               "m9"         => [0, 2, 3, 7, 10],
         | 
| 53 | 
            +
               "m9#5"       => [0, 2, 3, 8, 10],
         | 
| 54 | 
            +
               "m9b5"       => [0, 2, 3, 6, 10],
         | 
| 55 | 
            +
               "mM7b6"      => [0, 3, 7, 8, 11],
         | 
| 56 | 
            +
               "mM9"        => [0, 2, 3, 7, 11],
         | 
| 57 | 
            +
               "M7b9"       => [0, 1, 4, 7, 11],
         | 
| 58 | 
            +
               "M9"         => [0, 2, 4, 7, 11],
         | 
| 59 | 
            +
               "M9#5"       => [0, 2, 4, 8, 11],
         | 
| 60 | 
            +
               "M9#5sus4"   => [0, 2, 5, 8, 11],
         | 
| 61 | 
            +
               "M9b5"       => [0, 2, 4, 6, 11],
         | 
| 62 | 
            +
               "M9sus4"     => [0, 2, 5, 7, 11],
         | 
| 63 | 
            +
               "M7#11"      => [0, 4, 6, 7, 11],
         | 
| 64 | 
            +
               "7#9"        => [0, 3, 4, 7, 10],
         | 
| 65 | 
            +
               "7#11"       => [0, 4, 6, 7, 10],
         | 
| 66 | 
            +
               "11"         => [0, 2, 5, 7, 10],
         | 
| 67 | 
            +
               "11b9"       => [0, 1, 5, 7, 10],
         | 
| 68 | 
            +
               "13ndim5"    => [0, 2, 4, 9, 10],
         | 
| 69 | 
            +
               "7#5#9"      => [0, 3, 4, 8, 10],
         | 
| 70 | 
            +
               "7#5b9"      => [0, 1, 4, 8, 10],
         | 
| 71 | 
            +
               "7add6"      => [0, 4, 7, 9, 10],
         | 
| 72 | 
            +
               "7b6"        => [0, 4, 7, 8, 10],
         | 
| 73 | 
            +
               "7b9"        => [0, 1, 4, 7, 10],
         | 
| 74 | 
            +
               "7sus4b9"    => [0, 1, 5, 7, 10],
         | 
| 75 | 
            +
               "9"          => [0, 2, 4, 7, 10],
         | 
| 76 | 
            +
               "9#5"        => [0, 2, 4, 8, 10],
         | 
| 77 | 
            +
               "9b13"       => [0, 2, 4, 8, 10],
         | 
| 78 | 
            +
               "9b5"        => [0, 2, 4, 6, 10],
         | 
| 79 | 
            +
               "9sus4"      => [0, 2, 5, 7, 10],
         | 
| 80 | 
            +
               "M6/9#11"    => [0, 2, 4, 6, 7, 9],
         | 
| 81 | 
            +
               "6/9#11"     => [0, 2, 4, 6, 7, 9],
         | 
| 82 | 
            +
               "9#5#11"     => [0, 2, 4, 6, 8, 10],
         | 
| 83 | 
            +
               "Blues"      => [0, 3, 5, 6, 7, 10],
         | 
| 84 | 
            +
               "m11"        => [0, 2, 3, 5, 7, 10],
         | 
| 85 | 
            +
               "m11#5"      => [0, 2, 3, 5, 8, 10],
         | 
| 86 | 
            +
               "m11b5"      => [0, 2, 3, 5, 6, 10],
         | 
| 87 | 
            +
               "13b5"       => [0, 2, 4, 6, 9, 10],
         | 
| 88 | 
            +
               "13b9"       => [0, 1, 4, 7, 9, 10],
         | 
| 89 | 
            +
               "13sus4"     => [0, 2, 5, 7, 9, 10],
         | 
| 90 | 
            +
               "7#11b13"    => [0, 4, 6, 7, 8, 10],
         | 
| 91 | 
            +
               "7#5b9#11"   => [0, 1, 4, 6, 8, 10],
         | 
| 92 | 
            +
               "7#9#11"     => [0, 3, 4, 6, 7, 10],
         | 
| 93 | 
            +
               "7#9b13"     => [0, 3, 4, 7, 8, 10],
         | 
| 94 | 
            +
               "13#9"       => [0, 3, 4, 7, 9, 10],
         | 
| 95 | 
            +
               "13"         => [0, 2, 4, 7, 9, 10],
         | 
| 96 | 
            +
               "7b9#11"     => [0, 1, 4, 6, 7, 10],
         | 
| 97 | 
            +
               "7b9#9"      => [0, 1, 3, 4, 7, 10],
         | 
| 98 | 
            +
               "7b9b13"     => [0, 1, 4, 7, 8, 10],
         | 
| 99 | 
            +
               "7sus4b9b13" => [0, 1, 5, 7, 8, 10],
         | 
| 100 | 
            +
               "9#11"       => [0, 2, 4, 6, 7, 10],
         | 
| 101 | 
            +
               "M13"        => [0, 2, 4, 7, 9, 11],
         | 
| 102 | 
            +
               "M7#9#11"    => [0, 3, 4, 6, 7, 11],
         | 
| 103 | 
            +
               "M7add13"    => [0, 2, 4, 7, 9, 11],
         | 
| 104 | 
            +
               "M9#11"      => [0, 2, 4, 6, 7, 11],
         | 
| 105 | 
            +
               "mM9b6"      => [0, 2, 3, 7, 8, 11],
         | 
| 106 | 
            +
               "7b9b13#11"  => [0, 1, 4, 6, 7, 8, 10],
         | 
| 107 | 
            +
               "13b9#11"    => [0, 1, 4, 6, 7, 9, 10],
         | 
| 108 | 
            +
               "9#11b13"    => [0, 2, 4, 6, 7, 8, 10],
         | 
| 109 | 
            +
               "13#11"      => [0, 2, 4, 6, 7, 9, 10],
         | 
| 110 | 
            +
               "M13#11"     => [0, 2, 4, 6, 7, 9, 11],
         | 
| 111 | 
            +
               "m13"        => [0, 2, 3, 5, 7, 9, 10],
         | 
| 112 | 
            +
               "13#9#11"    => [0, 3, 4, 6, 7, 9, 10],
         | 
| 113 | 
            +
               "7#9#11b13"  => [0, 3, 4, 6, 7, 8, 10]
         | 
| 114 | 
            +
             }
         | 
| 115 | 
            +
            end
         |