coltrane 0.0.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +15 -10
- data/Gemfile.lock +47 -128
- data/README.md +30 -8
- data/Rakefile +0 -4
- data/bin/bundle +105 -0
- data/bin/byebug +29 -0
- data/bin/coderay +12 -0
- data/bin/coltrane +25 -7
- data/bin/htmldiff +12 -0
- data/bin/kill-pry-rescue +12 -0
- data/bin/ldiff +12 -0
- data/bin/pry +12 -0
- data/bin/rake +12 -0
- data/bin/rescue +12 -0
- data/bin/rspec +12 -0
- data/bin/rubocop +12 -0
- data/bin/ruby-parse +12 -0
- data/bin/ruby-rewrite +12 -0
- data/exe/coltrane +173 -0
- data/lib/cli/bass_guitar.rb +9 -0
- data/lib/cli/chord.rb +24 -0
- data/lib/cli/errors.rb +28 -0
- data/lib/cli/guitar.rb +55 -0
- data/lib/cli/notes.rb +18 -0
- data/lib/cli/piano.rb +54 -0
- data/lib/cli/representation.rb +47 -0
- data/lib/cli/scale.rb +48 -0
- data/lib/cli/text.rb +13 -0
- data/lib/cli/ukulele.rb +11 -0
- data/lib/coltrane-cli.rb +12 -0
- data/lib/coltrane.rb +16 -31
- data/lib/coltrane/cache.rb +34 -0
- data/lib/coltrane/chord.rb +28 -41
- data/lib/coltrane/chord_quality.rb +14 -39
- data/lib/coltrane/classic_progressions.rb +37 -0
- data/lib/coltrane/classic_scales.rb +92 -118
- data/lib/coltrane/errors.rb +54 -0
- data/lib/coltrane/interval.rb +25 -17
- data/lib/coltrane/interval_sequence.rb +57 -27
- data/lib/coltrane/note.rb +44 -30
- data/lib/coltrane/note_set.rb +37 -22
- data/lib/coltrane/piano_representation.rb +0 -58
- data/lib/coltrane/pitch.rb +12 -3
- data/lib/coltrane/progression.rb +31 -0
- data/lib/coltrane/qualities.rb +115 -114
- data/lib/coltrane/roman_chord.rb +36 -0
- data/lib/coltrane/scale.rb +85 -77
- data/lib/coltrane/version.rb +1 -1
- data/lib/core_ext.rb +12 -0
- data/pkg/coltrane-0.0.2.gem +0 -0
- metadata +27 -14
- data/lib/coltrane/essential_guitar_chords.rb +0 -82
- data/lib/coltrane/fret_set.rb +0 -0
- data/lib/coltrane/guitar.rb +0 -15
- data/lib/coltrane/guitar_chord.rb +0 -50
- data/lib/coltrane/guitar_chord_finder.rb +0 -98
- data/lib/coltrane/guitar_note.rb +0 -50
- data/lib/coltrane/guitar_note_set.rb +0 -61
- data/lib/coltrane/guitar_representation.rb +0 -96
- data/lib/coltrane/guitar_string.rb +0 -52
- data/lib/coltrane/scale_cache.rb +0 -4
@@ -0,0 +1,36 @@
|
|
1
|
+
module Coltrane
|
2
|
+
class RomanChord
|
3
|
+
DIGITS = {
|
4
|
+
'I' => 1,
|
5
|
+
'V' => 5,
|
6
|
+
}
|
7
|
+
|
8
|
+
def initialize(scale, roman_numeral)
|
9
|
+
@scale = scale
|
10
|
+
@roman_numeral = roman_numeral
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_chord
|
14
|
+
Chord.new root_note: root_note,
|
15
|
+
quality: quality
|
16
|
+
end
|
17
|
+
|
18
|
+
def root_note
|
19
|
+
@scale[degree]
|
20
|
+
end
|
21
|
+
|
22
|
+
def degree
|
23
|
+
@roman_numeral.split('').reduce(0) do |memo, r|
|
24
|
+
memo + (DIGITS[r] || 0) + (DIGITS[r.swapcase] || 0)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def quality
|
29
|
+
ChordQuality.new(name: is_major? ? 'M' : 'm')
|
30
|
+
end
|
31
|
+
|
32
|
+
def is_major?
|
33
|
+
@roman_numeral[0] =~ /[[:upper]]/
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/coltrane/scale.rb
CHANGED
@@ -3,23 +3,51 @@ module Coltrane
|
|
3
3
|
extend ClassicScales
|
4
4
|
attr_reader :interval_sequence, :tone
|
5
5
|
|
6
|
-
def initialize(*
|
7
|
-
@
|
8
|
-
|
9
|
-
|
6
|
+
def initialize(*distances, tone: 'C', mode: 1, name: nil, notes: nil)
|
7
|
+
@name = name
|
8
|
+
if !distances.nil? && !tone.nil?
|
9
|
+
@tone = Note[tone]
|
10
|
+
distances = distances.rotate(mode-1)
|
11
|
+
@interval_sequence = IntervalSequence.new(distances: distances)
|
12
|
+
elsif !notes.nil?
|
13
|
+
ds = NoteSet[*notes].interval_sequence.distances
|
14
|
+
self.new(*ds, tone: notes.first)
|
15
|
+
else raise WrongKeywords.new('[*distances, (tone: "C", mode: 1)] || [notes:]')
|
10
16
|
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def id
|
20
|
+
[(name || @interval_sequence), tone.number]
|
21
|
+
end
|
22
|
+
|
23
|
+
def name
|
24
|
+
@name = begin
|
25
|
+
is = self.interval_sequence.distances
|
26
|
+
(0...is.size).each do |i|
|
27
|
+
if (scale_name = Coltrane::ClassicScales::SCALES.key(is.rotate(i)))
|
28
|
+
return scale_name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
11
34
|
|
12
|
-
|
35
|
+
def pretty_name
|
36
|
+
"#{tone.name} #{name}"
|
13
37
|
end
|
14
38
|
|
15
|
-
|
16
|
-
|
17
|
-
|
39
|
+
alias_method :full_name, :pretty_name
|
40
|
+
|
41
|
+
def degree(d)
|
42
|
+
if d < 1 || d > size
|
43
|
+
raise WrongDegree.new(d)
|
18
44
|
end
|
19
45
|
|
20
|
-
tone + interval_sequence[
|
46
|
+
tone + interval_sequence[d - 1].semitones
|
21
47
|
end
|
22
48
|
|
49
|
+
alias_method :[], :degree
|
50
|
+
|
23
51
|
def degrees
|
24
52
|
(1..size)
|
25
53
|
end
|
@@ -35,14 +63,22 @@ module Coltrane
|
|
35
63
|
return note + 1 unless note.nil?
|
36
64
|
end
|
37
65
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
end
|
66
|
+
def &(something)
|
67
|
+
raise HasNoNotes unless something.respond_to?(:notes)
|
68
|
+
notes & something
|
42
69
|
end
|
43
70
|
|
71
|
+
def include_notes?(arg)
|
72
|
+
noteset = arg.is_a?(Note) ? NoteSet[arg] : arg
|
73
|
+
(self & noteset).size == noteset.size
|
74
|
+
end
|
75
|
+
|
76
|
+
alias_method :include?, :include_notes?
|
77
|
+
|
44
78
|
def notes
|
45
|
-
|
79
|
+
Coltrane::Cache.find_or_record(cache_key("notes")) do
|
80
|
+
NoteSet[*degrees.map { |d| degree(d) }]
|
81
|
+
end
|
46
82
|
end
|
47
83
|
|
48
84
|
def interval(i)
|
@@ -50,89 +86,61 @@ module Coltrane
|
|
50
86
|
end
|
51
87
|
|
52
88
|
def size
|
53
|
-
interval_sequence.
|
89
|
+
interval_sequence.size
|
54
90
|
end
|
55
91
|
|
56
|
-
def tertians
|
57
|
-
degrees.reduce([]) do |
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
92
|
+
def tertians(n=3)
|
93
|
+
degrees.size.times.reduce([]) do |memo, d|
|
94
|
+
ns = NoteSet[
|
95
|
+
*n.times.map { |i| notes[(d + (i*2)) % (size)]}
|
96
|
+
]
|
97
|
+
chord = Chord.new(notes: ns)
|
98
|
+
chord.named? ? memo + [chord] : memo
|
62
99
|
end
|
63
100
|
end
|
64
101
|
|
65
|
-
def
|
66
|
-
|
67
|
-
intervals = IntervalSequence.new(4.times.map { |i| interval(degree+(i*2)) })
|
68
|
-
intervals = intervals.shift(-intervals.numbers[0])
|
69
|
-
chord_name = "#{self[degree].name}#{ChordQuality.new(intervals).name}"
|
70
|
-
chords << Chord.new(chord_name)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def on_guitar
|
75
|
-
NoteSet.new(notes).guitar_notes.render
|
102
|
+
def triads
|
103
|
+
tertians(3)
|
76
104
|
end
|
77
105
|
|
78
|
-
def
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
def degrees_on_guitar
|
83
|
-
GuitarRepresentation.render_degrees(NoteSet.new(notes).guitar_notes, self)
|
84
|
-
end
|
85
|
-
|
86
|
-
def notes_on_guitar
|
87
|
-
GuitarRepresentation.render_notes(NoteSet.new(notes).guitar_notes, self)
|
88
|
-
end
|
89
|
-
|
90
|
-
def intervals_on_piano
|
91
|
-
PianoRepresentation.render_intervals(notes, tone)
|
106
|
+
def sevenths
|
107
|
+
tertians(4)
|
92
108
|
end
|
93
109
|
|
94
|
-
def
|
95
|
-
|
110
|
+
def pentads
|
111
|
+
tertians(5)
|
96
112
|
end
|
97
113
|
|
98
|
-
|
99
|
-
|
100
|
-
ScaleCache.find_or_create_by(
|
101
|
-
interval_sequence: interval_sequence.numbers.to_s,
|
102
|
-
tone: tone.name
|
103
|
-
)
|
114
|
+
def progression(*degrees)
|
115
|
+
Progression.new(self, degrees)
|
104
116
|
end
|
105
117
|
|
106
|
-
def
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
118
|
+
def cache_key(extra)
|
119
|
+
[
|
120
|
+
@tone.name,
|
121
|
+
@interval_sequence.intervals_semitones.join(),
|
122
|
+
extra
|
123
|
+
].join('-')
|
111
124
|
end
|
112
125
|
|
113
|
-
def
|
114
|
-
[]
|
115
|
-
|
116
|
-
cache.chord_caches.create name: chord.name, size: chord.size
|
126
|
+
def all_chords
|
127
|
+
(3..size).reduce([]) do |memo, s|
|
128
|
+
memo + chords(s)
|
117
129
|
end
|
118
130
|
end
|
119
131
|
|
120
132
|
def chords(size)
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
133
|
+
Coltrane::Cache.find_or_record(cache_key("chords-#{size}")) do
|
134
|
+
included_names = []
|
135
|
+
notes.permutation(size).reduce([]) do |memo, ns|
|
136
|
+
chord = Chord.new(notes: ns)
|
137
|
+
if chord.named? && !included_names.include?(chord.name)
|
138
|
+
included_names << chord.name
|
139
|
+
memo + [chord]
|
140
|
+
else
|
141
|
+
memo
|
126
142
|
end
|
127
|
-
|
128
|
-
quality = ChordQuality.new(c.zero_it)
|
129
|
-
unless quality.name.nil?
|
130
|
-
Chord.new "#{(tone + c[0].number).name}#{quality.name}"
|
131
|
-
end
|
132
|
-
end.compact
|
133
|
-
end)
|
134
|
-
else
|
135
|
-
cchords
|
143
|
+
end
|
136
144
|
end
|
137
145
|
end
|
138
146
|
end
|
data/lib/coltrane/version.rb
CHANGED
data/lib/core_ext.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
class String
|
2
|
+
# Stolen from Active Support and changed a bit
|
3
|
+
def underscore
|
4
|
+
return self unless /[A-Z-]|::/.match?(self)
|
5
|
+
word = self.to_s.gsub("::", "/")
|
6
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
7
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
8
|
+
word.tr!("-", "_")
|
9
|
+
word.downcase!
|
10
|
+
word
|
11
|
+
end
|
12
|
+
end
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coltrane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Maciel
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -41,12 +41,15 @@ dependencies:
|
|
41
41
|
description:
|
42
42
|
email:
|
43
43
|
- pedro@pedromaciel.com
|
44
|
-
executables:
|
44
|
+
executables:
|
45
|
+
- coltrane
|
45
46
|
extensions: []
|
46
47
|
extra_rdoc_files: []
|
47
48
|
files:
|
48
49
|
- ".bundle/config"
|
50
|
+
- ".gitignore"
|
49
51
|
- ".rspec"
|
52
|
+
- ".ruby-version"
|
50
53
|
- CODE_OF_CONDUCT.md
|
51
54
|
- Gemfile
|
52
55
|
- Gemfile.lock
|
@@ -55,7 +58,9 @@ files:
|
|
55
58
|
- README.md
|
56
59
|
- Rakefile
|
57
60
|
- bin/_guard-core
|
61
|
+
- bin/bundle
|
58
62
|
- bin/bundler
|
63
|
+
- bin/byebug
|
59
64
|
- bin/coderay
|
60
65
|
- bin/coltrane
|
61
66
|
- bin/console
|
@@ -86,21 +91,27 @@ files:
|
|
86
91
|
- db/cache_test.sqlite3
|
87
92
|
- db/config.yml
|
88
93
|
- db/schema.rb
|
94
|
+
- exe/coltrane
|
95
|
+
- lib/cli/bass_guitar.rb
|
96
|
+
- lib/cli/chord.rb
|
97
|
+
- lib/cli/errors.rb
|
98
|
+
- lib/cli/guitar.rb
|
99
|
+
- lib/cli/notes.rb
|
100
|
+
- lib/cli/piano.rb
|
101
|
+
- lib/cli/representation.rb
|
102
|
+
- lib/cli/scale.rb
|
103
|
+
- lib/cli/text.rb
|
104
|
+
- lib/cli/ukulele.rb
|
105
|
+
- lib/coltrane-cli.rb
|
89
106
|
- lib/coltrane.rb
|
107
|
+
- lib/coltrane/cache.rb
|
90
108
|
- lib/coltrane/cadence.rb
|
91
109
|
- lib/coltrane/chord.rb
|
92
110
|
- lib/coltrane/chord_cache.rb
|
93
111
|
- lib/coltrane/chord_quality.rb
|
112
|
+
- lib/coltrane/classic_progressions.rb
|
94
113
|
- lib/coltrane/classic_scales.rb
|
95
|
-
- lib/coltrane/
|
96
|
-
- lib/coltrane/fret_set.rb
|
97
|
-
- lib/coltrane/guitar.rb
|
98
|
-
- lib/coltrane/guitar_chord.rb
|
99
|
-
- lib/coltrane/guitar_chord_finder.rb
|
100
|
-
- lib/coltrane/guitar_note.rb
|
101
|
-
- lib/coltrane/guitar_note_set.rb
|
102
|
-
- lib/coltrane/guitar_representation.rb
|
103
|
-
- lib/coltrane/guitar_string.rb
|
114
|
+
- lib/coltrane/errors.rb
|
104
115
|
- lib/coltrane/interval.rb
|
105
116
|
- lib/coltrane/interval_sequence.rb
|
106
117
|
- lib/coltrane/interval_set.rb
|
@@ -111,10 +122,12 @@ files:
|
|
111
122
|
- lib/coltrane/pitch.rb
|
112
123
|
- lib/coltrane/progression.rb
|
113
124
|
- lib/coltrane/qualities.rb
|
125
|
+
- lib/coltrane/roman_chord.rb
|
114
126
|
- lib/coltrane/scale.rb
|
115
|
-
- lib/coltrane/scale_cache.rb
|
116
127
|
- lib/coltrane/scale_chord.rb
|
117
128
|
- lib/coltrane/version.rb
|
129
|
+
- lib/core_ext.rb
|
130
|
+
- pkg/coltrane-0.0.2.gem
|
118
131
|
homepage: http://github.com/pedrozath/coltrane
|
119
132
|
licenses:
|
120
133
|
- MIT
|
@@ -136,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
149
|
version: '0'
|
137
150
|
requirements: []
|
138
151
|
rubyforge_project:
|
139
|
-
rubygems_version: 2.
|
152
|
+
rubygems_version: 2.7.3
|
140
153
|
signing_key:
|
141
154
|
specification_version: 4
|
142
155
|
summary: It deals with all sorts of calculations around music theory and allows for
|
@@ -1,82 +0,0 @@
|
|
1
|
-
module Coltrane
|
2
|
-
module EssentialGuitarChords
|
3
|
-
CHORDS = {
|
4
|
-
'C' => [nil, 3, 2, 0, 1, 0],
|
5
|
-
'Cm' => [nil, 10, 10, 8, 6, 4],
|
6
|
-
'Cmaj7' => [nil, 3, 5, 4, 5, nil],
|
7
|
-
'C7' => [nil, 10, 10, 9, 11, nil],
|
8
|
-
'Cm7' => [6,6,5,5,nil,nil],
|
9
|
-
'Cm7b5' => [nil, 3,4,3,4, nil],
|
10
|
-
'C#' => [nil,8,6,6,6,nil],
|
11
|
-
'C#m' => [nil,5,6,6,5,nil],
|
12
|
-
'C#maj7' => [4,4,3,5,nil,nil],
|
13
|
-
'C#7' => [nil, nil, 6,6,6,7],
|
14
|
-
'C#m7' => [nil, 2,2,1,2],
|
15
|
-
'C#m7b5' => [nil, 4,5,4,5, nil],
|
16
|
-
'D' => [5,5,4,nil,nil,nil],
|
17
|
-
'Dm' => [10,nil,nil,10,10,nil],
|
18
|
-
'Dmaj7' => [5,5,4,6,nil,nil],
|
19
|
-
'D7' => [5,5,4,5,nil,nil],
|
20
|
-
'Dm7' => [nil,3,3,2,3,nil],
|
21
|
-
'Dm7b5' => [],
|
22
|
-
'D#' => [],
|
23
|
-
'D#m' => [],
|
24
|
-
'D#maj7' => [],
|
25
|
-
'D#7' => [],
|
26
|
-
'D#m7' => [],
|
27
|
-
'D#m7b5' => [],
|
28
|
-
'E' => [],
|
29
|
-
'Em' => [],
|
30
|
-
'Emaj7' => [],
|
31
|
-
'E7' => [],
|
32
|
-
'Em7' => [],
|
33
|
-
'Em7b5' => [],
|
34
|
-
'F' => [],
|
35
|
-
'Fm' => [],
|
36
|
-
'Fmaj7' => [],
|
37
|
-
'F7' => [],
|
38
|
-
'Fm7' => [],
|
39
|
-
'Fm7b5' => [],
|
40
|
-
'F#' => [],
|
41
|
-
'F#m' => [],
|
42
|
-
'F#maj7' => [],
|
43
|
-
'F#7' => [],
|
44
|
-
'F#m7' => [],
|
45
|
-
'F#m7b5' => [],
|
46
|
-
'G' => [],
|
47
|
-
'Gm' => [],
|
48
|
-
'Gmaj7' => [],
|
49
|
-
'G7' => [],
|
50
|
-
'Gm7' => [],
|
51
|
-
'Gm7b5' => [],
|
52
|
-
'G#' => [],
|
53
|
-
'G#m' => [],
|
54
|
-
'G#maj7' => [],
|
55
|
-
'G#7' => [],
|
56
|
-
'G#m7' => [],
|
57
|
-
'G#m7b5' => [],
|
58
|
-
'A' => [],
|
59
|
-
'Am' => [],
|
60
|
-
'Amaj7' => [],
|
61
|
-
'A7' => [],
|
62
|
-
'Am7' => [],
|
63
|
-
'Am7b5' => [],
|
64
|
-
'A#' => [],
|
65
|
-
'A#m' => [],
|
66
|
-
'A#maj7' => [],
|
67
|
-
'A#7' => [],
|
68
|
-
'A#m7' => [],
|
69
|
-
'A#m7b5' => [],
|
70
|
-
'B' => [],
|
71
|
-
'Bm' => [],
|
72
|
-
'Bmaj7' => [],
|
73
|
-
'B7' => [],
|
74
|
-
'Bm7' => [],
|
75
|
-
'Bm7b5' => []
|
76
|
-
}
|
77
|
-
|
78
|
-
def [](name)
|
79
|
-
GuitarChord.new_from_frets(*CHORDS[name])
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|