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.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +16 -1
  3. data/CHANGELOG.md +11 -0
  4. data/Gemfile.lock +25 -2
  5. data/README.md +3 -0
  6. data/bin/console +6 -2
  7. data/coltrane.gemspec +2 -1
  8. data/exe/coltrane +14 -224
  9. data/lib/coltrane.rb +3 -50
  10. data/lib/coltrane/commands.rb +14 -0
  11. data/lib/coltrane/commands/chords.rb +77 -0
  12. data/lib/coltrane/commands/command.rb +45 -0
  13. data/lib/coltrane/commands/common_chords.rb +33 -0
  14. data/lib/coltrane/commands/errors.rb +44 -0
  15. data/lib/coltrane/commands/find_progression.rb +28 -0
  16. data/lib/coltrane/commands/find_scale.rb +39 -0
  17. data/lib/coltrane/commands/notes.rb +44 -0
  18. data/lib/coltrane/commands/progression.rb +27 -0
  19. data/lib/{cli → coltrane/commands}/representation.rb +0 -0
  20. data/lib/coltrane/commands/scale.rb +46 -0
  21. data/lib/coltrane/renderers.rb +6 -0
  22. data/lib/coltrane/renderers/renderer.rb +42 -0
  23. data/lib/coltrane/renderers/text_renderer.rb +23 -0
  24. data/lib/coltrane/renderers/text_renderer/array_drawer.rb +45 -0
  25. data/lib/coltrane/renderers/text_renderer/base_drawer.rb +20 -0
  26. data/lib/coltrane/renderers/text_renderer/hash_drawer.rb +16 -0
  27. data/lib/coltrane/renderers/text_renderer/representation_guitar_chord_drawer.rb +95 -0
  28. data/lib/coltrane/renderers/text_renderer/representation_guitar_note_set_drawer.rb +76 -0
  29. data/lib/coltrane/renderers/text_renderer/representation_piano_note_set_drawer.rb +49 -0
  30. data/lib/coltrane/renderers/text_renderer/theory_chord_drawer.rb +14 -0
  31. data/lib/coltrane/renderers/text_renderer/theory_note_set_drawer.rb +17 -0
  32. data/lib/coltrane/renderers/text_renderer/theory_progression_drawer.rb +13 -0
  33. data/lib/coltrane/renderers/text_renderer/theory_progression_set_drawer.rb +22 -0
  34. data/lib/coltrane/renderers/text_renderer/theory_scale_drawer.rb +13 -0
  35. data/lib/coltrane/renderers/text_renderer/theory_scale_set_drawer.rb +27 -0
  36. data/lib/coltrane/representation.rb +12 -0
  37. data/lib/coltrane/representation/guitar.rb +34 -0
  38. data/lib/coltrane/representation/guitar/chord.rb +180 -0
  39. data/lib/coltrane/representation/guitar/note.rb +26 -0
  40. data/lib/coltrane/representation/guitar/note_set.rb +35 -0
  41. data/lib/coltrane/representation/guitar/string.rb +31 -0
  42. data/lib/coltrane/representation/guitar_like_instruments.rb +21 -0
  43. data/lib/coltrane/representation/piano.rb +36 -0
  44. data/lib/coltrane/representation/piano/note_set.rb +22 -0
  45. data/lib/{coltrane_synth.rb → coltrane/synth.rb.rb} +0 -0
  46. data/lib/{coltrane_synth → coltrane/synth}/base.rb +0 -0
  47. data/lib/{coltrane_synth → coltrane/synth}/synth.rb +0 -0
  48. data/lib/coltrane/theory.rb +54 -0
  49. data/lib/coltrane/theory/cadence.rb +9 -0
  50. data/lib/coltrane/{changes.rb → theory/changes.rb} +0 -0
  51. data/lib/coltrane/theory/chord.rb +101 -0
  52. data/lib/coltrane/theory/chord_quality.rb +113 -0
  53. data/lib/coltrane/theory/chord_substitutions.rb +11 -0
  54. data/lib/coltrane/theory/circle_of_fifths.rb +33 -0
  55. data/lib/coltrane/theory/classic_scales.rb +113 -0
  56. data/lib/coltrane/theory/diatonic_scale.rb +38 -0
  57. data/lib/coltrane/theory/errors.rb +97 -0
  58. data/lib/coltrane/theory/frequency.rb +52 -0
  59. data/lib/coltrane/theory/frequency_interval.rb +83 -0
  60. data/lib/coltrane/theory/interval.rb +209 -0
  61. data/lib/coltrane/theory/interval_class.rb +212 -0
  62. data/lib/coltrane/theory/interval_sequence.rb +157 -0
  63. data/lib/coltrane/theory/key.rb +18 -0
  64. data/lib/coltrane/{mode.rb → theory/mode.rb} +0 -0
  65. data/lib/coltrane/theory/notable_progressions.rb +30 -0
  66. data/lib/coltrane/theory/note.rb +104 -0
  67. data/lib/coltrane/theory/note_set.rb +101 -0
  68. data/lib/coltrane/theory/pitch.rb +94 -0
  69. data/lib/coltrane/theory/pitch_class.rb +154 -0
  70. data/lib/coltrane/theory/progression.rb +81 -0
  71. data/lib/coltrane/theory/progression_set.rb +18 -0
  72. data/lib/coltrane/{qualities.rb → theory/qualities.rb} +0 -0
  73. data/lib/coltrane/theory/roman_chord.rb +114 -0
  74. data/lib/coltrane/theory/scale.rb +161 -0
  75. data/lib/coltrane/theory/scale_search_result.rb +6 -0
  76. data/lib/coltrane/theory/scale_set.rb +40 -0
  77. data/lib/coltrane/theory/voicing.rb +41 -0
  78. data/lib/coltrane/version.rb +1 -1
  79. metadata +88 -63
  80. data/bin/rails +0 -17
  81. data/data/qualities.yml +0 -83
  82. data/db/cache.sqlite3 +0 -0
  83. data/db/cache_test.sqlite3 +0 -0
  84. data/db/config.yml +0 -11
  85. data/lib/cli.rb +0 -24
  86. data/lib/cli/bass_guitar.rb +0 -12
  87. data/lib/cli/chord.rb +0 -39
  88. data/lib/cli/config.rb +0 -39
  89. data/lib/cli/errors.rb +0 -46
  90. data/lib/cli/guitar.rb +0 -67
  91. data/lib/cli/guitar_chords.rb +0 -122
  92. data/lib/cli/notes.rb +0 -20
  93. data/lib/cli/piano.rb +0 -57
  94. data/lib/cli/scale.rb +0 -53
  95. data/lib/cli/text.rb +0 -16
  96. data/lib/cli/ukulele.rb +0 -14
  97. data/lib/coltrane/cache.rb +0 -43
  98. data/lib/coltrane/cadence.rb +0 -7
  99. data/lib/coltrane/chord.rb +0 -89
  100. data/lib/coltrane/chord_quality.rb +0 -111
  101. data/lib/coltrane/chord_substitutions.rb +0 -9
  102. data/lib/coltrane/circle_of_fifths.rb +0 -31
  103. data/lib/coltrane/classic_scales.rb +0 -94
  104. data/lib/coltrane/diatonic_scale.rb +0 -36
  105. data/lib/coltrane/errors.rb +0 -95
  106. data/lib/coltrane/frequency.rb +0 -50
  107. data/lib/coltrane/frequency_interval.rb +0 -81
  108. data/lib/coltrane/interval.rb +0 -208
  109. data/lib/coltrane/interval_class.rb +0 -210
  110. data/lib/coltrane/interval_sequence.rb +0 -155
  111. data/lib/coltrane/key.rb +0 -16
  112. data/lib/coltrane/notable_progressions.rb +0 -28
  113. data/lib/coltrane/note.rb +0 -98
  114. data/lib/coltrane/note_set.rb +0 -89
  115. data/lib/coltrane/pitch.rb +0 -92
  116. data/lib/coltrane/pitch_class.rb +0 -148
  117. data/lib/coltrane/progression.rb +0 -74
  118. data/lib/coltrane/roman_chord.rb +0 -112
  119. data/lib/coltrane/scale.rb +0 -154
  120. data/lib/coltrane/unordered_interval_class.rb +0 -7
  121. data/lib/coltrane/voicing.rb +0 -39
  122. data/lib/coltrane_game/question.rb +0 -7
  123. data/lib/coltrane_instruments.rb +0 -7
  124. data/lib/coltrane_instruments/guitar.rb +0 -10
  125. data/lib/coltrane_instruments/guitar/base.rb +0 -29
  126. data/lib/coltrane_instruments/guitar/chord.rb +0 -170
  127. data/lib/coltrane_instruments/guitar/note.rb +0 -24
  128. data/lib/coltrane_instruments/guitar/string.rb +0 -29
  129. data/lib/os.rb +0 -21
@@ -1,7 +0,0 @@
1
-
2
- # frozen_string_literal: true
3
-
4
- module Coltrane
5
- class UnorderedIntervalClass
6
- end
7
- end
@@ -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
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ColtraneGame
4
- class Question
5
- def generate; end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'coltrane'
4
-
5
- module ColtraneInstruments
6
- autoload :Guitar, 'coltrane_instruments/guitar'
7
- end
@@ -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