coltrane 2.2.1 → 3.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +16 -1
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +25 -2
- data/README.md +3 -0
- data/bin/console +6 -2
- data/coltrane.gemspec +2 -1
- data/exe/coltrane +14 -224
- data/lib/coltrane.rb +3 -50
- data/lib/coltrane/commands.rb +14 -0
- data/lib/coltrane/commands/chords.rb +77 -0
- data/lib/coltrane/commands/command.rb +45 -0
- data/lib/coltrane/commands/common_chords.rb +33 -0
- data/lib/coltrane/commands/errors.rb +44 -0
- data/lib/coltrane/commands/find_progression.rb +28 -0
- data/lib/coltrane/commands/find_scale.rb +39 -0
- data/lib/coltrane/commands/notes.rb +44 -0
- data/lib/coltrane/commands/progression.rb +27 -0
- data/lib/{cli → coltrane/commands}/representation.rb +0 -0
- data/lib/coltrane/commands/scale.rb +46 -0
- data/lib/coltrane/renderers.rb +6 -0
- data/lib/coltrane/renderers/renderer.rb +42 -0
- data/lib/coltrane/renderers/text_renderer.rb +23 -0
- data/lib/coltrane/renderers/text_renderer/array_drawer.rb +45 -0
- data/lib/coltrane/renderers/text_renderer/base_drawer.rb +20 -0
- data/lib/coltrane/renderers/text_renderer/hash_drawer.rb +16 -0
- data/lib/coltrane/renderers/text_renderer/representation_guitar_chord_drawer.rb +95 -0
- data/lib/coltrane/renderers/text_renderer/representation_guitar_note_set_drawer.rb +76 -0
- data/lib/coltrane/renderers/text_renderer/representation_piano_note_set_drawer.rb +49 -0
- data/lib/coltrane/renderers/text_renderer/theory_chord_drawer.rb +14 -0
- data/lib/coltrane/renderers/text_renderer/theory_note_set_drawer.rb +17 -0
- data/lib/coltrane/renderers/text_renderer/theory_progression_drawer.rb +13 -0
- data/lib/coltrane/renderers/text_renderer/theory_progression_set_drawer.rb +22 -0
- data/lib/coltrane/renderers/text_renderer/theory_scale_drawer.rb +13 -0
- data/lib/coltrane/renderers/text_renderer/theory_scale_set_drawer.rb +27 -0
- data/lib/coltrane/representation.rb +12 -0
- data/lib/coltrane/representation/guitar.rb +34 -0
- data/lib/coltrane/representation/guitar/chord.rb +180 -0
- data/lib/coltrane/representation/guitar/note.rb +26 -0
- data/lib/coltrane/representation/guitar/note_set.rb +35 -0
- data/lib/coltrane/representation/guitar/string.rb +31 -0
- data/lib/coltrane/representation/guitar_like_instruments.rb +21 -0
- data/lib/coltrane/representation/piano.rb +36 -0
- data/lib/coltrane/representation/piano/note_set.rb +22 -0
- data/lib/{coltrane_synth.rb → coltrane/synth.rb.rb} +0 -0
- data/lib/{coltrane_synth → coltrane/synth}/base.rb +0 -0
- data/lib/{coltrane_synth → coltrane/synth}/synth.rb +0 -0
- data/lib/coltrane/theory.rb +54 -0
- data/lib/coltrane/theory/cadence.rb +9 -0
- data/lib/coltrane/{changes.rb → theory/changes.rb} +0 -0
- data/lib/coltrane/theory/chord.rb +101 -0
- data/lib/coltrane/theory/chord_quality.rb +113 -0
- data/lib/coltrane/theory/chord_substitutions.rb +11 -0
- data/lib/coltrane/theory/circle_of_fifths.rb +33 -0
- data/lib/coltrane/theory/classic_scales.rb +113 -0
- data/lib/coltrane/theory/diatonic_scale.rb +38 -0
- data/lib/coltrane/theory/errors.rb +97 -0
- data/lib/coltrane/theory/frequency.rb +52 -0
- data/lib/coltrane/theory/frequency_interval.rb +83 -0
- data/lib/coltrane/theory/interval.rb +209 -0
- data/lib/coltrane/theory/interval_class.rb +212 -0
- data/lib/coltrane/theory/interval_sequence.rb +157 -0
- data/lib/coltrane/theory/key.rb +18 -0
- data/lib/coltrane/{mode.rb → theory/mode.rb} +0 -0
- data/lib/coltrane/theory/notable_progressions.rb +30 -0
- data/lib/coltrane/theory/note.rb +104 -0
- data/lib/coltrane/theory/note_set.rb +101 -0
- data/lib/coltrane/theory/pitch.rb +94 -0
- data/lib/coltrane/theory/pitch_class.rb +154 -0
- data/lib/coltrane/theory/progression.rb +81 -0
- data/lib/coltrane/theory/progression_set.rb +18 -0
- data/lib/coltrane/{qualities.rb → theory/qualities.rb} +0 -0
- data/lib/coltrane/theory/roman_chord.rb +114 -0
- data/lib/coltrane/theory/scale.rb +161 -0
- data/lib/coltrane/theory/scale_search_result.rb +6 -0
- data/lib/coltrane/theory/scale_set.rb +40 -0
- data/lib/coltrane/theory/voicing.rb +41 -0
- data/lib/coltrane/version.rb +1 -1
- metadata +88 -63
- data/bin/rails +0 -17
- data/data/qualities.yml +0 -83
- data/db/cache.sqlite3 +0 -0
- data/db/cache_test.sqlite3 +0 -0
- data/db/config.yml +0 -11
- data/lib/cli.rb +0 -24
- data/lib/cli/bass_guitar.rb +0 -12
- data/lib/cli/chord.rb +0 -39
- data/lib/cli/config.rb +0 -39
- data/lib/cli/errors.rb +0 -46
- data/lib/cli/guitar.rb +0 -67
- data/lib/cli/guitar_chords.rb +0 -122
- data/lib/cli/notes.rb +0 -20
- data/lib/cli/piano.rb +0 -57
- data/lib/cli/scale.rb +0 -53
- data/lib/cli/text.rb +0 -16
- data/lib/cli/ukulele.rb +0 -14
- data/lib/coltrane/cache.rb +0 -43
- data/lib/coltrane/cadence.rb +0 -7
- data/lib/coltrane/chord.rb +0 -89
- data/lib/coltrane/chord_quality.rb +0 -111
- data/lib/coltrane/chord_substitutions.rb +0 -9
- data/lib/coltrane/circle_of_fifths.rb +0 -31
- data/lib/coltrane/classic_scales.rb +0 -94
- data/lib/coltrane/diatonic_scale.rb +0 -36
- data/lib/coltrane/errors.rb +0 -95
- data/lib/coltrane/frequency.rb +0 -50
- data/lib/coltrane/frequency_interval.rb +0 -81
- data/lib/coltrane/interval.rb +0 -208
- data/lib/coltrane/interval_class.rb +0 -210
- data/lib/coltrane/interval_sequence.rb +0 -155
- data/lib/coltrane/key.rb +0 -16
- data/lib/coltrane/notable_progressions.rb +0 -28
- data/lib/coltrane/note.rb +0 -98
- data/lib/coltrane/note_set.rb +0 -89
- data/lib/coltrane/pitch.rb +0 -92
- data/lib/coltrane/pitch_class.rb +0 -148
- data/lib/coltrane/progression.rb +0 -74
- data/lib/coltrane/roman_chord.rb +0 -112
- data/lib/coltrane/scale.rb +0 -154
- data/lib/coltrane/unordered_interval_class.rb +0 -7
- data/lib/coltrane/voicing.rb +0 -39
- data/lib/coltrane_game/question.rb +0 -7
- data/lib/coltrane_instruments.rb +0 -7
- data/lib/coltrane_instruments/guitar.rb +0 -10
- data/lib/coltrane_instruments/guitar/base.rb +0 -29
- data/lib/coltrane_instruments/guitar/chord.rb +0 -170
- data/lib/coltrane_instruments/guitar/note.rb +0 -24
- data/lib/coltrane_instruments/guitar/string.rb +0 -29
- data/lib/os.rb +0 -21
data/lib/coltrane/voicing.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Coltrane
|
4
|
-
# This class describes an actual implementation of a Chord, being aware
|
5
|
-
# of exact octaves of each pitch and even repeating pitches across octaves.
|
6
|
-
class Voicing
|
7
|
-
attr_reader :pitches
|
8
|
-
|
9
|
-
def initialize(*pitch_strings, pitches: nil)
|
10
|
-
@pitches = if pitch_strings.any?
|
11
|
-
pitch_strings.map { |s| Pitch[s] }
|
12
|
-
elsif pitches
|
13
|
-
pitches
|
14
|
-
else
|
15
|
-
raise WrongArgumentsError
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.[](*args)
|
20
|
-
new(*args)
|
21
|
-
end
|
22
|
-
|
23
|
-
def pitch_classes
|
24
|
-
NoteSet[*pitches.map(&:pitch_class).uniq]
|
25
|
-
end
|
26
|
-
|
27
|
-
alias notes pitch_classes
|
28
|
-
|
29
|
-
def chord
|
30
|
-
@chord ||= Chord.new(notes: notes)
|
31
|
-
rescue ChordNotFoundError
|
32
|
-
return false
|
33
|
-
end
|
34
|
-
|
35
|
-
def frequencies
|
36
|
-
pitches.map(&:frequency)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/lib/coltrane_instruments.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ColtraneInstruments
|
4
|
-
module Guitar
|
5
|
-
autoload :Base, 'coltrane_instruments/guitar/base'
|
6
|
-
autoload :Chord, 'coltrane_instruments/guitar/chord'
|
7
|
-
autoload :Note, 'coltrane_instruments/guitar/note'
|
8
|
-
autoload :String, 'coltrane_instruments/guitar/string'
|
9
|
-
end
|
10
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ColtraneInstruments
|
4
|
-
module Guitar
|
5
|
-
DEFAULT_TUNING = %w[E2 A2 D3 G3 B3 E4].freeze
|
6
|
-
DEFAULT_FRETS = 23
|
7
|
-
# A base class for operations involving Guitars
|
8
|
-
class Base
|
9
|
-
attr_reader :strings, :frets
|
10
|
-
|
11
|
-
def self.find_chords(target_chord)
|
12
|
-
unless target_chord.is_a?(Coltrane::Chord)
|
13
|
-
target_chord = Coltrane::Chord.new(name: target_chord)
|
14
|
-
end
|
15
|
-
|
16
|
-
ColtraneInstruments::Guitar::Chord.new(target_chord, guitar: new)
|
17
|
-
.fetch_descendant_chords
|
18
|
-
end
|
19
|
-
|
20
|
-
def initialize(tuning = DEFAULT_TUNING, frets = DEFAULT_FRETS)
|
21
|
-
@strings = tuning.map do |p|
|
22
|
-
String.new(Coltrane::Pitch[p], guitar: self)
|
23
|
-
end
|
24
|
-
|
25
|
-
@frets = frets
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,170 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ColtraneInstruments
|
4
|
-
module Guitar
|
5
|
-
# This class represents a group of guitar notes, strummed at the same time
|
6
|
-
class Chord
|
7
|
-
include Comparable
|
8
|
-
attr_reader :guitar_notes, :guitar, :free_fingers, :target_chord, :barre
|
9
|
-
|
10
|
-
MAX_FRET_SPAN = 3
|
11
|
-
|
12
|
-
def self.find(chord)
|
13
|
-
new(chord).fetch_descendant_chords
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize(target_chord,
|
17
|
-
guitar_notes: [],
|
18
|
-
free_fingers: 4,
|
19
|
-
barre: nil,
|
20
|
-
guitar:)
|
21
|
-
|
22
|
-
@target_chord = target_chord
|
23
|
-
@guitar_notes = guitar_notes
|
24
|
-
@free_fingers = free_fingers
|
25
|
-
@guitar = guitar
|
26
|
-
@barre = barre
|
27
|
-
end
|
28
|
-
|
29
|
-
def <=>(other)
|
30
|
-
rank <=> other.rank
|
31
|
-
end
|
32
|
-
|
33
|
-
def rank
|
34
|
-
+completeness * 10_000 +
|
35
|
-
+fullness * 1000 +
|
36
|
-
-spreadness * 100 +
|
37
|
-
+easyness * 1
|
38
|
-
end
|
39
|
-
|
40
|
-
def analysis
|
41
|
-
{
|
42
|
-
completeness: completeness,
|
43
|
-
fullness: fullness,
|
44
|
-
easyness: easyness,
|
45
|
-
spreadness: spreadness
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
def spreadness
|
50
|
-
fret_range.size.to_f / MAX_FRET_SPAN
|
51
|
-
end
|
52
|
-
|
53
|
-
def completeness
|
54
|
-
(target_chord.notes.size.to_f - notes_left.size) / target_chord.notes.size
|
55
|
-
end
|
56
|
-
|
57
|
-
def easyness
|
58
|
-
frets.count(0).to_f / guitar_notes.size
|
59
|
-
end
|
60
|
-
|
61
|
-
def fullness
|
62
|
-
(guitar.strings.size.to_f - frets.count(nil)) / guitar.strings.size
|
63
|
-
end
|
64
|
-
|
65
|
-
def barre?
|
66
|
-
!@barre.nil?
|
67
|
-
end
|
68
|
-
|
69
|
-
def fetch_descendant_chords
|
70
|
-
return [self] if guitar_notes.size >= guitar.strings.size
|
71
|
-
possible_new_notes(notes_available.positive?).reduce([]) do |memo, n|
|
72
|
-
barre = n.fret if guitar_notes.last == n.fret
|
73
|
-
fingers_change = n.fret == barre || n.fret.zero? ? 0 : 1
|
74
|
-
next memo if (free_fingers - fingers_change).negative?
|
75
|
-
Chord.new(target_chord, guitar_notes: guitar_notes + [n],
|
76
|
-
free_fingers: free_fingers - fingers_change,
|
77
|
-
guitar: guitar,
|
78
|
-
barre: barre)
|
79
|
-
.fetch_descendant_chords + memo
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def notes_available
|
84
|
-
strings_available - notes_left.size
|
85
|
-
end
|
86
|
-
|
87
|
-
def strings_available
|
88
|
-
guitar.strings.size - guitar_notes.size
|
89
|
-
end
|
90
|
-
|
91
|
-
def notes_left
|
92
|
-
@notes_left ||= begin
|
93
|
-
target_chord.notes - Coltrane::NoteSet[
|
94
|
-
*guitar_notes.map do |n|
|
95
|
-
next if n.pitch.nil?
|
96
|
-
n.pitch.pitch_class
|
97
|
-
end
|
98
|
-
]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def target_notes
|
103
|
-
notes_left.any? ? notes_left : target_chord.notes
|
104
|
-
end
|
105
|
-
|
106
|
-
def notes
|
107
|
-
guitar_notes.map(&:pitch)
|
108
|
-
end
|
109
|
-
|
110
|
-
def frets
|
111
|
-
@frets ||= guitar_notes.map(&:fret)
|
112
|
-
end
|
113
|
-
|
114
|
-
def non_zero_frets
|
115
|
-
frets.reject { |f| f.nil? || f.zero? }
|
116
|
-
end
|
117
|
-
|
118
|
-
def lowest_fret
|
119
|
-
non_zero_frets.any? ? non_zero_frets.min : 0
|
120
|
-
end
|
121
|
-
|
122
|
-
def highest_fret
|
123
|
-
non_zero_frets.max || 0
|
124
|
-
end
|
125
|
-
|
126
|
-
def fret_range
|
127
|
-
(lowest_fret..highest_fret)
|
128
|
-
end
|
129
|
-
|
130
|
-
def lowest_possible_fret
|
131
|
-
lowest_fret.zero? ? 0 : [(lowest_fret - possible_span), 0].max
|
132
|
-
end
|
133
|
-
|
134
|
-
def highest_possible_fret
|
135
|
-
[(possible_span + (highest_fret == 0 ? guitar.frets : highest_fret)), guitar.frets].min
|
136
|
-
end
|
137
|
-
|
138
|
-
def possible_span
|
139
|
-
MAX_FRET_SPAN - fret_range.size
|
140
|
-
end
|
141
|
-
|
142
|
-
def fret_expansion_range
|
143
|
-
(lowest_possible_fret..highest_possible_fret).to_a +
|
144
|
-
[(0 unless barre?)].compact
|
145
|
-
end
|
146
|
-
|
147
|
-
def to_s
|
148
|
-
guitar_notes.map { |n| n.fret.nil? ? 'x' : n.fret }.join('-')
|
149
|
-
end
|
150
|
-
|
151
|
-
def voicing
|
152
|
-
Coltrane::Voicing.new(pitches: guitar_notes.map(&:pitch).compact)
|
153
|
-
end
|
154
|
-
|
155
|
-
private
|
156
|
-
|
157
|
-
attr_writer :barre
|
158
|
-
|
159
|
-
def next_string
|
160
|
-
guitar.strings[guitar_notes.size]
|
161
|
-
end
|
162
|
-
|
163
|
-
def possible_new_notes(include_mute_note = false)
|
164
|
-
target_notes.notes.map do |note|
|
165
|
-
next_string.find(note, possible_frets: fret_expansion_range)
|
166
|
-
end.flatten + [(Guitar::Note.new(next_string, nil) if include_mute_note)].compact
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ColtraneInstruments
|
4
|
-
module Guitar
|
5
|
-
class Note
|
6
|
-
attr_reader :string, :fret
|
7
|
-
|
8
|
-
def initialize(string, fret = nil)
|
9
|
-
@string = string
|
10
|
-
@fret = fret
|
11
|
-
end
|
12
|
-
|
13
|
-
def pitch
|
14
|
-
string + fret unless fret.nil?
|
15
|
-
end
|
16
|
-
|
17
|
-
def pitch_class
|
18
|
-
pitch.pitch_class unless fret.nil?
|
19
|
-
end
|
20
|
-
|
21
|
-
alias note pitch_class
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ColtraneInstruments
|
4
|
-
module Guitar
|
5
|
-
class String
|
6
|
-
attr_reader :pitch, :guitar
|
7
|
-
|
8
|
-
def initialize(pitch, guitar:)
|
9
|
-
@guitar = guitar
|
10
|
-
@pitch = pitch
|
11
|
-
end
|
12
|
-
|
13
|
-
def find(pitch_class, possible_frets: (0..guitar.frets).to_a)
|
14
|
-
output = []
|
15
|
-
n = 0
|
16
|
-
loop do
|
17
|
-
f = (pitch_class.integer - pitch.integer) % 12 + 12 * n
|
18
|
-
possible_frets.include?(f) ? output << Note.new(self, f) : break
|
19
|
-
n += 1
|
20
|
-
end
|
21
|
-
output
|
22
|
-
end
|
23
|
-
|
24
|
-
def +(fret)
|
25
|
-
pitch + fret
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
data/lib/os.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module OS
|
4
|
-
class << self
|
5
|
-
def windows?
|
6
|
-
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
7
|
-
end
|
8
|
-
|
9
|
-
def mac?
|
10
|
-
(/darwin/ =~ RUBY_PLATFORM) != nil
|
11
|
-
end
|
12
|
-
|
13
|
-
def unix?
|
14
|
-
!windows?
|
15
|
-
end
|
16
|
-
|
17
|
-
def OS.linux?
|
18
|
-
unix? && !mac?
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|