coltrane 0.0.2 → 1.0.0
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 +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
|