coltrane 1.0.2 → 1.0.11
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 +4 -4
- data/Gemfile +2 -5
- data/Gemfile.lock +3 -3
- data/coltrane.gemspec +1 -1
- data/db/schema.rb +30 -0
- data/exe/coltrane +21 -27
- data/lib/cli/bass_guitar.rb +1 -4
- data/lib/cli/chord.rb +3 -10
- data/lib/cli/errors.rb +4 -10
- data/lib/cli/guitar.rb +10 -12
- data/lib/cli/notes.rb +4 -7
- data/lib/cli/piano.rb +8 -11
- data/lib/cli/representation.rb +14 -14
- data/lib/cli/scale.rb +11 -15
- data/lib/cli/text.rb +3 -6
- data/lib/cli/ukulele.rb +2 -5
- data/lib/{cli.rb → coltrane-cli.rb} +2 -4
- data/lib/coltrane.rb +1 -4
- data/lib/coltrane/cache.rb +9 -10
- data/lib/coltrane/cadence.rb +1 -3
- data/lib/coltrane/chord.rb +8 -16
- data/lib/coltrane/chord_cache.rb +4 -0
- data/lib/coltrane/chord_quality.rb +8 -7
- data/lib/coltrane/classic_progressions.rb +7 -10
- data/lib/coltrane/classic_scales.rb +43 -30
- data/lib/coltrane/errors.rb +10 -17
- data/lib/coltrane/interval.rb +23 -24
- data/lib/coltrane/interval_sequence.rb +7 -8
- data/lib/coltrane/interval_set.rb +0 -1
- data/lib/coltrane/note.rb +46 -23
- data/lib/coltrane/note_set.rb +14 -12
- data/lib/coltrane/pitch.rb +4 -5
- data/lib/coltrane/progression.rb +20 -9
- data/lib/coltrane/qualities.rb +112 -114
- data/lib/coltrane/roman_chord.rb +5 -8
- data/lib/coltrane/scale.rb +33 -25
- data/lib/coltrane/scale_chord.rb +4 -0
- data/lib/coltrane/version.rb +1 -3
- data/lib/core_ext.rb +4 -7
- metadata +10 -7
- data/.rubocop.yml +0 -19
data/lib/coltrane/interval.rb
CHANGED
@@ -1,42 +1,41 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Coltrane
|
4
2
|
# It describes a interval between 2 pitches
|
5
3
|
class Interval
|
6
4
|
attr_reader :semitones
|
7
5
|
|
8
|
-
NAMES =
|
9
|
-
1P
|
10
|
-
2m
|
11
|
-
2M
|
12
|
-
3m
|
13
|
-
3M
|
14
|
-
4P
|
15
|
-
4A
|
16
|
-
5P
|
17
|
-
6m
|
18
|
-
6M
|
19
|
-
7m
|
20
|
-
7M
|
6
|
+
NAMES = [
|
7
|
+
'1P',
|
8
|
+
'2m',
|
9
|
+
'2M',
|
10
|
+
'3m',
|
11
|
+
'3M',
|
12
|
+
'4P',
|
13
|
+
'4A',
|
14
|
+
'5P',
|
15
|
+
'6m',
|
16
|
+
'6M',
|
17
|
+
'7m',
|
18
|
+
'7M'
|
21
19
|
].freeze
|
22
20
|
|
23
21
|
def initialize(arg)
|
24
22
|
@semitones = (case arg
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
when Interval then arg.semitones
|
24
|
+
when String then NAMES.index(arg)
|
25
|
+
when Numeric then arg
|
26
|
+
end) % 12
|
29
27
|
end
|
30
28
|
|
31
29
|
def name
|
32
30
|
NAMES[semitones]
|
33
31
|
end
|
34
32
|
|
35
|
-
def +(
|
36
|
-
case
|
37
|
-
when Numeric then Interval.new(semitones +
|
38
|
-
when Interval then Interval.new(semitones +
|
33
|
+
def +(x)
|
34
|
+
case x
|
35
|
+
when Numeric then Interval.new(semitones + x)
|
36
|
+
when Interval then Interval.new(semitones + x.semitones)
|
39
37
|
end
|
40
38
|
end
|
39
|
+
|
41
40
|
end
|
42
|
-
end
|
41
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Coltrane
|
4
2
|
# It describes a sequence of intervals
|
5
3
|
class IntervalSequence
|
@@ -24,7 +22,7 @@ module Coltrane
|
|
24
22
|
|
25
23
|
def distances
|
26
24
|
intervals_semitones[1..-1].each_with_index.map do |n, i|
|
27
|
-
if i
|
25
|
+
if i == 0
|
28
26
|
n
|
29
27
|
elsif i < intervals_semitones.size
|
30
28
|
n - intervals_semitones[i]
|
@@ -47,7 +45,7 @@ module Coltrane
|
|
47
45
|
end
|
48
46
|
|
49
47
|
def zero_it
|
50
|
-
shift(-intervals.first.semitones)
|
48
|
+
self.shift(-intervals.first.semitones)
|
51
49
|
end
|
52
50
|
|
53
51
|
def inversion(index)
|
@@ -55,11 +53,11 @@ module Coltrane
|
|
55
53
|
end
|
56
54
|
|
57
55
|
def next_inversion
|
58
|
-
inversion(index
|
56
|
+
inversion(index+1)
|
59
57
|
end
|
60
58
|
|
61
59
|
def previous_inversion
|
62
|
-
inversion(index
|
60
|
+
inversion(index-1)
|
63
61
|
end
|
64
62
|
|
65
63
|
def inversions
|
@@ -68,7 +66,8 @@ module Coltrane
|
|
68
66
|
end
|
69
67
|
end
|
70
68
|
|
71
|
-
def quality
|
69
|
+
def quality
|
70
|
+
end
|
72
71
|
|
73
72
|
def intervals_semitones
|
74
73
|
map(&:semitones)
|
@@ -98,4 +97,4 @@ module Coltrane
|
|
98
97
|
notes.map { |n| notes.root - n }.sort_by(&:semitones)
|
99
98
|
end
|
100
99
|
end
|
101
|
-
end
|
100
|
+
end
|
data/lib/coltrane/note.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Coltrane
|
4
|
-
#
|
2
|
+
# It describes a musical note, independent of octave
|
3
|
+
|
5
4
|
class Note
|
6
5
|
include Multiton
|
7
6
|
|
8
7
|
attr_reader :name, :number
|
9
|
-
|
8
|
+
alias_method :id, :number
|
10
9
|
|
11
10
|
NOTES = {
|
12
11
|
'C' => 0,
|
@@ -29,8 +28,7 @@ module Coltrane
|
|
29
28
|
}.freeze
|
30
29
|
|
31
30
|
def initialize(name)
|
32
|
-
@name = name
|
33
|
-
@number = NOTES[name]
|
31
|
+
@name, @number = name, NOTES[name]
|
34
32
|
end
|
35
33
|
|
36
34
|
private_class_method :new
|
@@ -41,11 +39,10 @@ module Coltrane
|
|
41
39
|
when Note then return arg
|
42
40
|
when String then find_note(arg)
|
43
41
|
when Numeric then NOTES.key(arg % 12)
|
44
|
-
else
|
45
|
-
raise InvalidNoteError, "Wrong type: #{arg.class}"
|
42
|
+
else raise InvalidNote.new("Wrong type: #{arg.class}")
|
46
43
|
end
|
47
44
|
|
48
|
-
new(name) || (raise
|
45
|
+
new(name) || (raise InvalidNote.new("#{arg}"))
|
49
46
|
end
|
50
47
|
|
51
48
|
def self.all
|
@@ -53,37 +50,63 @@ module Coltrane
|
|
53
50
|
end
|
54
51
|
|
55
52
|
def self.find_note(str)
|
56
|
-
NOTES.
|
53
|
+
NOTES.each { |k, v| return k if str.casecmp?(k) }
|
57
54
|
nil
|
58
55
|
end
|
59
56
|
|
60
57
|
def pretty_name
|
61
|
-
@name.
|
58
|
+
@name.gsub('b',"\u266D").gsub('#',"\u266F")
|
62
59
|
end
|
63
60
|
|
64
|
-
|
61
|
+
alias_method :to_s, :name
|
65
62
|
|
66
63
|
def accident?
|
67
|
-
[1,
|
64
|
+
[1,3,6,8,10].include?(number)
|
68
65
|
end
|
69
66
|
|
70
|
-
def +(
|
71
|
-
case
|
72
|
-
|
73
|
-
|
74
|
-
|
67
|
+
def +(n)
|
68
|
+
case n
|
69
|
+
when Interval then Note[number + n.semitones]
|
70
|
+
when Numeric then Note[number + n]
|
71
|
+
when Note then Chord.new(number + n.number)
|
75
72
|
end
|
76
73
|
end
|
77
74
|
|
78
|
-
def -(
|
79
|
-
case
|
80
|
-
|
81
|
-
|
75
|
+
def -(n)
|
76
|
+
case n
|
77
|
+
when Numeric then Note.new(n - number)
|
78
|
+
when Note then Interval.new(n.number - number)
|
82
79
|
end
|
83
80
|
end
|
84
81
|
|
82
|
+
def valid_note?(note_name)
|
83
|
+
find_note(note_name)
|
84
|
+
end
|
85
|
+
|
85
86
|
def interval_to(note_name)
|
86
87
|
Note[note_name] - self
|
87
88
|
end
|
89
|
+
|
90
|
+
def transpose_by(semitones)
|
91
|
+
self + semitones
|
92
|
+
end
|
93
|
+
|
94
|
+
def guitar_notes
|
95
|
+
Guitar.strings.reduce([]) do |memo, guitar_string|
|
96
|
+
memo + in_guitar_string(guitar_string)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def on_guitar
|
101
|
+
GuitarNoteSet.new(guitar_notes).render
|
102
|
+
end
|
103
|
+
|
104
|
+
def in_guitar_string(guitar_string)
|
105
|
+
guitar_string.guitar_notes_for_note(self)
|
106
|
+
end
|
107
|
+
|
108
|
+
def in_guitar_string_region(guitar_string, region)
|
109
|
+
guitar_string.guitar_notes_for_note_in_region(self, region)
|
110
|
+
end
|
88
111
|
end
|
89
|
-
end
|
112
|
+
end
|
data/lib/coltrane/note_set.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Coltrane
|
4
2
|
# It describes a set of notes
|
5
3
|
class NoteSet
|
@@ -10,8 +8,8 @@ module Coltrane
|
|
10
8
|
|
11
9
|
attr_reader :notes
|
12
10
|
|
13
|
-
|
14
|
-
|
11
|
+
alias_method :root, :first
|
12
|
+
alias_method :all, :notes
|
15
13
|
|
16
14
|
def self.[](*notes)
|
17
15
|
new(notes)
|
@@ -21,21 +19,21 @@ module Coltrane
|
|
21
19
|
@notes =
|
22
20
|
case arg
|
23
21
|
when NoteSet then arg.notes
|
24
|
-
when Array then arg.map {
|
25
|
-
else raise
|
22
|
+
when Array then arg.map {|n| n.is_a?(Note) ? n : Note[n] }
|
23
|
+
else raise InvalidNotes.new(arg)
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
|
-
def &(
|
30
|
-
NoteSet[*(notes &
|
27
|
+
def &(another)
|
28
|
+
NoteSet[*(notes & another.notes)]
|
31
29
|
end
|
32
30
|
|
33
31
|
def degree(note)
|
34
|
-
index(note)
|
32
|
+
index(note)+1
|
35
33
|
end
|
36
34
|
|
37
|
-
def +(
|
38
|
-
NoteSet[*(notes +
|
35
|
+
def +(other_noteset)
|
36
|
+
NoteSet[*(notes + other_noteset.notes)]
|
39
37
|
end
|
40
38
|
|
41
39
|
def pretty_names
|
@@ -56,8 +54,12 @@ module Coltrane
|
|
56
54
|
end
|
57
55
|
end
|
58
56
|
|
57
|
+
def guitar_notes
|
58
|
+
GuitarNoteSet.new(notes.map(&:guitar_notes).flatten)
|
59
|
+
end
|
60
|
+
|
59
61
|
def interval_sequence
|
60
62
|
IntervalSequence.new(notes: self)
|
61
63
|
end
|
62
64
|
end
|
63
|
-
end
|
65
|
+
end
|
data/lib/coltrane/pitch.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Coltrane
|
4
2
|
# It describes a pitch, like E4 or Bb5. It's like a note, but it has an octave
|
5
3
|
class Pitch
|
@@ -30,8 +28,9 @@ module Coltrane
|
|
30
28
|
Note[number]
|
31
29
|
end
|
32
30
|
|
33
|
-
def +(
|
34
|
-
|
31
|
+
def +(arg)
|
32
|
+
n = arg.is_a?(Pitch) ? arg.number : arg
|
33
|
+
Pitch.new(number + n)
|
35
34
|
end
|
36
35
|
end
|
37
|
-
end
|
36
|
+
end
|
data/lib/coltrane/progression.rb
CHANGED
@@ -1,24 +1,35 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Coltrane
|
4
|
-
# Allows creation of chord progressions
|
5
2
|
class Progression
|
6
3
|
extend ClassicProgressions
|
7
4
|
|
8
5
|
attr_reader :scale
|
9
6
|
|
10
|
-
def initialize(
|
11
|
-
|
7
|
+
def initialize(roman_notation, key: nil, scale: nil)
|
8
|
+
if !key.nil?
|
9
|
+
@scale = get_scale_from_key(key)
|
10
|
+
end
|
12
11
|
end
|
13
12
|
|
14
|
-
|
13
|
+
def chords
|
14
|
+
all_chords.values_at(*chord_indexes)
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
+
def on_guitar
|
18
|
+
chords.map(&:on_guitar)
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_piano
|
22
|
+
chords.map(&:on_piano)
|
23
|
+
end
|
17
24
|
|
18
25
|
private
|
19
26
|
|
27
|
+
def all_chords
|
28
|
+
scale.sevenths
|
29
|
+
end
|
30
|
+
|
20
31
|
def chord_indexes
|
21
|
-
|
32
|
+
degrees.map { |d| d-1 }
|
22
33
|
end
|
23
34
|
end
|
24
|
-
end
|
35
|
+
end
|
data/lib/coltrane/qualities.rb
CHANGED
@@ -1,118 +1,116 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Coltrane
|
4
2
|
module Qualities
|
5
3
|
CHORD_QUALITIES = {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
4
|
+
"5" => [0, 7],
|
5
|
+
"Msus2" => [0, 2, 7],
|
6
|
+
"dim" => [0, 3, 6],
|
7
|
+
"m" => [0, 3, 7],
|
8
|
+
"m#5" => [0, 3, 8],
|
9
|
+
"Mb5" => [0, 4, 6],
|
10
|
+
"M" => [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
|
+
}
|
117
115
|
end
|
118
|
-
end
|
116
|
+
end
|