coltrane 2.2.1 → 3.0.0.pre
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/.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
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'coltrane'
|
|
4
|
+
|
|
5
|
+
module Coltrane
|
|
6
|
+
module Representation
|
|
7
|
+
autoload :Guitar, 'coltrane/representation/guitar'
|
|
8
|
+
autoload :Ukulele, 'coltrane/representation/guitar_like_instruments'
|
|
9
|
+
autoload :Bass, 'coltrane/representation/guitar_like_instruments'
|
|
10
|
+
autoload :Piano, 'coltrane/representation/piano'
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'coltrane/representation/guitar/chord'
|
|
3
|
+
require 'coltrane/representation/guitar/note'
|
|
4
|
+
require 'coltrane/representation/guitar/note_set'
|
|
5
|
+
require 'coltrane/representation/guitar/string'
|
|
6
|
+
|
|
7
|
+
module Coltrane
|
|
8
|
+
module Representation
|
|
9
|
+
class Guitar
|
|
10
|
+
# A base class for operations involving Guitars
|
|
11
|
+
attr_reader :strings, :tuning, :frets, :special_frets
|
|
12
|
+
|
|
13
|
+
def self.find_chords(target_chord)
|
|
14
|
+
unless target_chord.is_a?(Theory::Chord)
|
|
15
|
+
target_chord = Theory::Chord.new(name: target_chord)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Guitar::Chord.find(target_chord, guitar: new)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.find_notes(notes)
|
|
22
|
+
Guitar::NoteSet.new(notes, guitar: new)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def initialize(tuning: nil, frets: nil, special_frets: nil)
|
|
26
|
+
@tuning = tuning || %w[E2 A2 D3 G3 B3 E4]
|
|
27
|
+
@special_frets = special_frets || [3, 5, 7, 9, 12, 15, 17, 19]
|
|
28
|
+
@frets = frets || 23
|
|
29
|
+
|
|
30
|
+
@strings = @tuning.map { |p| String.new(Theory::Pitch[p], guitar: self) }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coltrane
|
|
4
|
+
module Representation
|
|
5
|
+
class Guitar
|
|
6
|
+
# This class represents a group of guitar notes, strummed at the same time
|
|
7
|
+
class Chord
|
|
8
|
+
include Comparable
|
|
9
|
+
attr_reader :guitar_notes, :guitar, :free_fingers, :target_chord, :barre
|
|
10
|
+
|
|
11
|
+
MAX_FRET_SPAN = 3
|
|
12
|
+
|
|
13
|
+
def self.find(chord, guitar:)
|
|
14
|
+
new(chord, guitar: guitar)
|
|
15
|
+
.fetch_descendant_chords
|
|
16
|
+
.sort
|
|
17
|
+
.reverse
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize(target_chord,
|
|
21
|
+
guitar_notes: [],
|
|
22
|
+
free_fingers: 4,
|
|
23
|
+
barre: nil,
|
|
24
|
+
guitar:)
|
|
25
|
+
|
|
26
|
+
@target_chord = target_chord
|
|
27
|
+
@guitar_notes = guitar_notes
|
|
28
|
+
@free_fingers = free_fingers
|
|
29
|
+
@guitar = guitar
|
|
30
|
+
@barre = barre
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def max_fret_span
|
|
34
|
+
MAX_FRET_SPAN
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def <=>(other)
|
|
38
|
+
rank <=> other.rank
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def rank
|
|
42
|
+
+completeness * 10_000 +
|
|
43
|
+
+fullness * 1000 +
|
|
44
|
+
-spreadness * 100 +
|
|
45
|
+
+easyness * 1
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def analysis
|
|
49
|
+
{
|
|
50
|
+
completeness: completeness,
|
|
51
|
+
fullness: fullness,
|
|
52
|
+
easyness: easyness,
|
|
53
|
+
spreadness: spreadness
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def spreadness
|
|
58
|
+
fret_range.size.to_f / MAX_FRET_SPAN
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def completeness
|
|
62
|
+
(target_chord.notes.size.to_f - notes_left.size) / target_chord.notes.size
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def easyness
|
|
66
|
+
frets.count(0).to_f / guitar_notes.size
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def fullness
|
|
70
|
+
(guitar.strings.size.to_f - frets.count(nil)) / guitar.strings.size
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def barre?
|
|
74
|
+
!@barre.nil?
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def fetch_descendant_chords
|
|
78
|
+
return [self] if guitar_notes.size >= guitar.strings.size
|
|
79
|
+
possible_new_notes(notes_available.positive?).reduce([]) do |memo, n|
|
|
80
|
+
barre = n.fret if guitar_notes.last == n.fret
|
|
81
|
+
fingers_change = n.fret == barre || n.fret.zero? ? 0 : 1
|
|
82
|
+
next memo if (free_fingers - fingers_change).negative?
|
|
83
|
+
self.class.new(target_chord,
|
|
84
|
+
guitar_notes: guitar_notes + [n],
|
|
85
|
+
free_fingers: free_fingers - fingers_change,
|
|
86
|
+
guitar: guitar,
|
|
87
|
+
barre: barre
|
|
88
|
+
).fetch_descendant_chords + memo
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def notes_available
|
|
93
|
+
strings_available - notes_left.size
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def strings_available
|
|
97
|
+
guitar.strings.size - guitar_notes.size
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def notes_left
|
|
101
|
+
@notes_left ||= begin
|
|
102
|
+
target_chord.notes - Theory::NoteSet[
|
|
103
|
+
*guitar_notes.map do |n|
|
|
104
|
+
next if n.pitch.nil?
|
|
105
|
+
n.pitch.pitch_class
|
|
106
|
+
end
|
|
107
|
+
]
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def target_notes
|
|
112
|
+
notes_left.any? ? notes_left : target_chord.notes
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def notes
|
|
116
|
+
guitar_notes.map(&:pitch)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def frets
|
|
120
|
+
@frets ||= guitar_notes.map(&:fret)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def non_zero_frets
|
|
124
|
+
frets.reject { |f| f.nil? || f.zero? }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def lowest_fret
|
|
128
|
+
non_zero_frets.any? ? non_zero_frets.min : 0
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def highest_fret
|
|
132
|
+
non_zero_frets.max || 0
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def fret_range
|
|
136
|
+
(lowest_fret..highest_fret)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def lowest_possible_fret
|
|
140
|
+
lowest_fret.zero? ? 0 : [(lowest_fret - possible_span), 0].max
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def highest_possible_fret
|
|
144
|
+
[(possible_span + (highest_fret == 0 ? guitar.frets : highest_fret)), guitar.frets].min
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def possible_span
|
|
148
|
+
MAX_FRET_SPAN - fret_range.size
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def fret_expansion_range
|
|
152
|
+
(lowest_possible_fret..highest_possible_fret).to_a +
|
|
153
|
+
[(0 unless barre?)].compact
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def to_s
|
|
157
|
+
guitar_notes.map { |n| n.fret.nil? ? 'x' : n.fret }.join('-')
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def voicing
|
|
161
|
+
Coltrane::Voicing.new(pitches: guitar_notes.map(&:pitch).compact)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
private
|
|
165
|
+
|
|
166
|
+
attr_writer :barre
|
|
167
|
+
|
|
168
|
+
def next_string
|
|
169
|
+
guitar.strings[guitar_notes.size]
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def possible_new_notes(include_mute_note = false)
|
|
173
|
+
target_notes.notes.map do |note|
|
|
174
|
+
next_string.find(note, possible_frets: fret_expansion_range)
|
|
175
|
+
end.flatten + [(Guitar::Note.new(next_string, nil) if include_mute_note)].compact
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coltrane
|
|
4
|
+
module Representation
|
|
5
|
+
class Guitar
|
|
6
|
+
class Note
|
|
7
|
+
attr_reader :string, :fret
|
|
8
|
+
|
|
9
|
+
def initialize(string, fret = nil)
|
|
10
|
+
@string = string
|
|
11
|
+
@fret = fret
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def pitch
|
|
15
|
+
string + fret unless fret.nil?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def pitch_class
|
|
19
|
+
pitch.pitch_class unless fret.nil?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
alias note pitch_class
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coltrane
|
|
4
|
+
module Representation
|
|
5
|
+
class Guitar
|
|
6
|
+
class NoteSet
|
|
7
|
+
extend Forwardable
|
|
8
|
+
include Enumerable
|
|
9
|
+
|
|
10
|
+
attr_reader :notes, :guitar
|
|
11
|
+
def_delegators :notes, :each, :root
|
|
12
|
+
|
|
13
|
+
def initialize(note_set, guitar:)
|
|
14
|
+
@notes = note_set
|
|
15
|
+
@guitar = guitar
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
instance_eval { alias [] new }
|
|
19
|
+
|
|
20
|
+
def results
|
|
21
|
+
@strings ||= begin
|
|
22
|
+
guitar.strings.map do |string|
|
|
23
|
+
{
|
|
24
|
+
pitch: string.pitch,
|
|
25
|
+
notes: notes.map { |note| string.find(note) }
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
alias strings results
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coltrane
|
|
4
|
+
module Representation
|
|
5
|
+
class Guitar
|
|
6
|
+
class String
|
|
7
|
+
attr_reader :pitch, :guitar
|
|
8
|
+
|
|
9
|
+
def initialize(pitch, guitar:)
|
|
10
|
+
@guitar = guitar
|
|
11
|
+
@pitch = pitch
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def find(pitch_class, possible_frets: (0..guitar.frets).to_a)
|
|
15
|
+
output = []
|
|
16
|
+
n = 0
|
|
17
|
+
loop do
|
|
18
|
+
f = (pitch_class.integer - pitch.integer) % 12 + 12 * n
|
|
19
|
+
possible_frets.include?(f) ? output << Note.new(self, f) : break
|
|
20
|
+
n += 1
|
|
21
|
+
end
|
|
22
|
+
output
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def +(fret)
|
|
26
|
+
pitch + fret
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'coltrane/representation/guitar'
|
|
4
|
+
|
|
5
|
+
module Coltrane
|
|
6
|
+
module Representation
|
|
7
|
+
class Ukulele < Guitar
|
|
8
|
+
def initialize(tuning: %w[G3 C4 E4 A4],
|
|
9
|
+
frets: 12,
|
|
10
|
+
special_frets: [5, 7, 9, 12])
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class Bass < Guitar
|
|
16
|
+
def initialize(tuning: %w[E1 A1 D2 G2])
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'coltrane/representation/piano/note_set'
|
|
2
|
+
|
|
3
|
+
module Coltrane
|
|
4
|
+
module Representation
|
|
5
|
+
class Piano
|
|
6
|
+
attr_reader :octaves
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
|
|
10
|
+
def find_notes(notes)
|
|
11
|
+
Piano::NoteSet.new(notes, piano: new)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def chord(chord)
|
|
15
|
+
find_notes(
|
|
16
|
+
chord.is_a?(Chord) ? chord.notes : Chord.new(name: chord).notes
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def black_notes
|
|
21
|
+
Theory::Scale.pentatonic_major('C#', 4).notes
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def white_notes
|
|
25
|
+
Theory::Scale.major.notes
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def initialize
|
|
31
|
+
@octaves
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coltrane
|
|
4
|
+
module Representation
|
|
5
|
+
class Piano
|
|
6
|
+
class NoteSet
|
|
7
|
+
extend Forwardable
|
|
8
|
+
include Enumerable
|
|
9
|
+
|
|
10
|
+
attr_reader :notes, :piano
|
|
11
|
+
def_delegators :notes, :each, :root
|
|
12
|
+
|
|
13
|
+
def initialize(note_set, piano:)
|
|
14
|
+
@notes = note_set
|
|
15
|
+
@piano = piano
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
instance_eval { alias [] new }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coltrane
|
|
4
|
+
# The main module for working with Music Theory
|
|
5
|
+
module Theory
|
|
6
|
+
require 'coltrane/theory/errors'
|
|
7
|
+
autoload :Frequency, 'coltrane/theory/frequency'
|
|
8
|
+
|
|
9
|
+
BASE_OCTAVE = 4
|
|
10
|
+
BASE_PITCH_INTEGER = 9
|
|
11
|
+
|
|
12
|
+
def self.tuning=(f)
|
|
13
|
+
@base_tuning = Frequency[f].octave(-4)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.base_tuning
|
|
17
|
+
@base_tuning
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
@base_tuning = Frequency[440].octave(-4)
|
|
21
|
+
|
|
22
|
+
autoload :Pitch, 'coltrane/theory/pitch'
|
|
23
|
+
autoload :Voicing, 'coltrane/theory/voicing'
|
|
24
|
+
|
|
25
|
+
autoload :PitchClass, 'coltrane/theory/pitch_class'
|
|
26
|
+
autoload :Note, 'coltrane/theory/note'
|
|
27
|
+
autoload :NoteSet, 'coltrane/theory/note_set'
|
|
28
|
+
|
|
29
|
+
autoload :FrequencyInterval, 'coltrane/theory/frequency_interval'
|
|
30
|
+
autoload :IntervalClass, 'coltrane/theory/interval_class'
|
|
31
|
+
autoload :Interval, 'coltrane/theory/interval'
|
|
32
|
+
autoload :UnorderedIntervalClass, 'coltrane/theory/unordered_interval_class'
|
|
33
|
+
autoload :IntervalSequence, 'coltrane/theory/interval_sequence'
|
|
34
|
+
autoload :Qualities, 'coltrane/theory/qualities'
|
|
35
|
+
autoload :ChordQuality, 'coltrane/theory/chord_quality'
|
|
36
|
+
autoload :Chord, 'coltrane/theory/chord'
|
|
37
|
+
autoload :ChordSubstitutions, 'coltrane/theory/chord_substitutions'
|
|
38
|
+
autoload :RomanChord, 'coltrane/theory/roman_chord'
|
|
39
|
+
|
|
40
|
+
autoload :ClassicScales, 'coltrane/theory/classic_scales'
|
|
41
|
+
autoload :Scale, 'coltrane/theory/scale'
|
|
42
|
+
autoload :ScaleSet, 'coltrane/theory/scale_set'
|
|
43
|
+
autoload :CircleOfFifths, 'coltrane/theory/circle_of_fifths'
|
|
44
|
+
autoload :DiatonicScale, 'coltrane/theory/diatonic_scale'
|
|
45
|
+
autoload :Key, 'coltrane/theory/key'
|
|
46
|
+
|
|
47
|
+
autoload :NotableProgressions, 'coltrane/theory/notable_progressions'
|
|
48
|
+
autoload :Changes, 'coltrane/theory/changes'
|
|
49
|
+
autoload :Cadence, 'coltrane/theory/cadence'
|
|
50
|
+
autoload :ProgressionSet, 'coltrane/theory/progression_set'
|
|
51
|
+
autoload :Progression, 'coltrane/theory/progression'
|
|
52
|
+
autoload :Mode, 'coltrane/theory/mode'
|
|
53
|
+
end
|
|
54
|
+
end
|