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,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coltrane
4
- module Cli
5
- # Renders notes in a bass guitar scheme
6
- class BassGuitar < Guitar
7
- def initialize(notes, tuning: %w[E A D G])
8
- super
9
- end
10
- end
11
- end
12
- end
data/lib/cli/chord.rb DELETED
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coltrane
4
- module Cli
5
- # Interfaces chord functionality with the lib
6
- class Chord
7
- def initialize(*chords, notes: nil)
8
- Cli.config do |c|
9
- if c.on == :guitar
10
- c.on = :guitar_chords
11
- elsif c.on == :guitar_arm
12
- c.on = :guitar
13
- end
14
- end
15
-
16
- @chords =
17
- if !chords.empty?
18
- if chords[0].is_a?(String)
19
- chords.map { |c| Coltrane::Chord.new(name: c) }
20
- else
21
- chords
22
- end
23
- elsif !notes.nil?
24
- [Coltrane::Chord.new(notes: notes)]
25
- end
26
-
27
- raise BadChordError unless @chords
28
-
29
- @chords.each do |chord|
30
- desc = "#{chord.name} chord:"
31
- Coltrane::Cli::Notes.new chord.notes, desc: desc
32
- # ColtraneSynth::Base.play(chord, 1) if Cli.config.sound
33
- end
34
- end
35
- end
36
- end
37
- end
38
-
39
- # rubocop:enable Metrics/MethodLength
data/lib/cli/config.rb DELETED
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coltrane
4
- module Cli
5
- class Config
6
- DEFAULTS = {
7
- flavor: :notes,
8
- sound: false,
9
- on: :text
10
- }.freeze
11
-
12
- attr_accessor :flavor, :degrees, :sound
13
- attr_reader :on
14
-
15
- def initialize(defaults = DEFAULTS)
16
- defaults.each do |key, val|
17
- instance_variable_set(:"@#{key}", val)
18
- end
19
- end
20
-
21
- def on=(instrument)
22
- @on = case instrument
23
- when :ukelele then :ukulele
24
- when :bass then :bass_guitar
25
- else instrument
26
- end
27
- end
28
- end
29
-
30
- def self.config
31
- @config = Config.new if @config.nil?
32
- block_given? ? yield(@config) : @config
33
- end
34
-
35
- def self.erase_config
36
- @config = nil
37
- end
38
- end
39
- end
data/lib/cli/errors.rb DELETED
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # rubocop:disable Style/Documentation
4
-
5
- module Coltrane
6
- module Cli
7
- class ColtraneCliError < StandardError
8
- def initialize(msg)
9
- super msg
10
- end
11
- end
12
-
13
- class WrongFlavorError < ColtraneCliError
14
- def initialize(msg = nil)
15
- super msg || 'Wrong flavor. Check possible flavors with `coltrane list flavors`.'
16
- end
17
- end
18
-
19
- class BadFindScales < ColtraneCliError
20
- def initialize(msg = nil)
21
- super msg || 'Provide --notes or --chords. Ex: `coltrane find-scale --notes C-E-G`.'
22
- end
23
- end
24
-
25
- class WrongRepresentationTypeError < ColtraneCliError
26
- def initialize(type)
27
- super "The provided representation type (#{type}) "\
28
- 'is not available at the moment.'
29
- end
30
- end
31
-
32
- class BadScaleError < ColtraneCliError
33
- def initialize(msg = nil)
34
- super msg || 'Incorrect scale, please specify scale and root separated by `-`. Ex: `coltrane scale major-C'
35
- end
36
- end
37
-
38
- class BadChordError < ColtraneCliError
39
- def initialize(msg = nil)
40
- super msg || 'Incorrect chord, please specify a set of chords separated by `-`. Ex: coltrane chord CM7'
41
- end
42
- end
43
- end
44
- end
45
-
46
- # rubocop:enable Style/Documentation
data/lib/cli/guitar.rb DELETED
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coltrane
4
- module Cli
5
- # Renders notes in a common most popular ukulele scheme
6
- class Guitar < Representation
7
- SPECIAL_FRETS = [3, 5, 7, 9, 12, 15, 17, 19].freeze
8
-
9
- include Color
10
- def initialize(notes, tuning: %w[E A D G B E], frets: 22)
11
- @notes = notes
12
- @tuning = tuning.reverse
13
- @frets = frets
14
- @ref_note = @notes.first
15
- end
16
-
17
- def render
18
- [render_notes, render_special_frets, hint].join("\n" * 2)
19
- end
20
-
21
- def render_notes
22
- @tuning.each_with_index.map do |string, str_i|
23
- string_note = Note[string]
24
- Array.new(@frets + 2) do |i|
25
- if i.zero?
26
- Paint[string, HSL.new(140 + str_i * 20, 50, 50).html]
27
- else
28
- fret = i - 1
29
- note = string_note + fret
30
- m = (@notes.include?(note) ? place_mark(note) : place_empty(str_i))
31
- fret.zero? ? (m + ' |') : m
32
- end
33
- end.join(' ')
34
- end.join("\n")
35
- end
36
-
37
- def render_special_frets
38
- ' ' +
39
- Array.new(@frets + 2) do |fret|
40
- m = SPECIAL_FRETS.include?(fret) ? fret.to_s.rjust(2, 0.to_s) : ' '
41
- "#{m}#{' ' if fret.zero?}"
42
- end.join(' ')
43
- end
44
-
45
- def place_empty(str_i)
46
- Paint['--', HSL.new(180 + str_i * 3, 50, 30).html]
47
- end
48
-
49
- def place_mark(note)
50
- mark = case Cli.config.flavor
51
- when :notes then note.pretty_name.ljust(2, ' ')
52
- when :intervals then (@ref_note - note).name.ljust(2, '-')
53
- when :degrees then @notes.degree(note).to_s.rjust(2, '0')
54
- when :marks then ' ' # '◼◼'
55
- else raise WrongFlavorError
56
- end
57
-
58
- base_hue = (180 + note.integer * 10) % 360 # + 260
59
- Paint[
60
- mark,
61
- HSL.new(0, 0, 100).html,
62
- HSL.new(base_hue, 100, 30).html
63
- ]
64
- end
65
- end
66
- end
67
- end
@@ -1,122 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coltrane
4
- module Cli
5
- # Renders notes in a common most popular ukulele scheme
6
- class GuitarChords < Representation
7
- include Color
8
-
9
- def initialize(notes, tuning: %w[E2 A2 D3 G3 B3 E4], frets: 23)
10
- @notes = notes
11
- @tuning = tuning.reverse
12
- @frets = frets
13
-
14
- target_chord = Coltrane::Chord.new(notes: @notes)
15
- chords = ColtraneInstruments::Guitar::Base.find_chords(target_chord)
16
- @chords = chords.sort[-6..-1].reverse
17
- # @chords.each { |c| ColtraneSynth::Base.play(c.voicing) } if false
18
- end
19
-
20
- def chord_height
21
- ColtraneInstruments::Guitar::Chord::MAX_FRET_SPAN
22
- end
23
-
24
- def render
25
- render_horizontally
26
- # render_vertically
27
- end
28
-
29
- def render_vertically
30
- @chords.map { |c| render_chord(c) }
31
- end
32
-
33
- def render_horizontally
34
- rchords = @chords.map { |c| render_chord(c).split("\n") }
35
- rchords.max_by(&:size).size.times.reduce('') do |memo1, l|
36
- memo1 +
37
- rchords.reduce('') do |memo2, c|
38
- memo2 +
39
- (c[l].nil? ? ' ' * c.map(&:size).max + ' ' : "#{c[l]} ")
40
- end +
41
- "\n"
42
- end
43
- end
44
-
45
- def render_chord(chord)
46
- render_top(chord) +
47
- (chord.lowest_fret..chord.lowest_fret + chord_height)
48
- .each_with_index.reduce('') do |memo1, (f, y)|
49
- memo1 +
50
- ' ' +
51
- (chord.guitar.strings.size * 2).times.map { |x| base_color border(x, y) }.join('') +
52
- "\n" +
53
- chord.guitar.strings.reduce(base_color(f.to_s.ljust(2, ' '))) do |memo2, s|
54
- memo2 +
55
- ' ' +
56
- render_note(chord.guitar_notes.select do |n|
57
- n.string == s && n.fret == f
58
- end.any?)
59
- end +
60
- " \n"
61
- end + ' ' +
62
- (chord.guitar.strings.size * 2).times.map do |x|
63
- base_color border(x, chord_height + 1)
64
- end.join('')
65
- end
66
-
67
- def border(x, y)
68
- edge = [@tuning.size * 2 - 2, chord_height + 1]
69
- x_on_start = x == 0
70
- y_on_start = y == 0
71
- x_on_edge = x == edge[0]
72
- y_on_edge = y == edge[1]
73
- x_on_middle = (0...edge[0]).cover?(x)
74
- y_on_middle = (0...edge[1]).cover?(y)
75
-
76
- if x_on_start && y_on_start then '┍'
77
- elsif x_on_middle && y_on_start then x.odd? ? '━' : '┯'
78
- elsif x_on_edge && y_on_start then '┑'
79
- elsif x_on_start && y_on_middle then '┝'
80
- elsif x_on_middle && y_on_middle then x.odd? ? '━' : '┿'
81
- elsif x_on_edge && y_on_middle then '┥'
82
- elsif x_on_start && y_on_edge then '┕'
83
- elsif x_on_middle && y_on_edge then x.odd? ? '━' : '┷'
84
- elsif x_on_edge && y_on_edge then '┙'
85
- else ' '
86
- end
87
- # puts edge.inspect
88
- # "#{x},#{y} "
89
- end
90
-
91
- def base_color(str)
92
- Paint[str, '#6A4AC2']
93
- end
94
-
95
- def highlight(str)
96
- Paint[str, '#E67831']
97
- end
98
-
99
- def alt(str)
100
- Paint[str, '#2DD380']
101
- end
102
-
103
- def render_top(chord)
104
- chord.guitar.strings.reduce(' ') do |memo, s|
105
- memo +
106
- if chord.guitar_notes.select { |n|
107
- n.string == s && n.fret == 0 }.any?
108
- highlight '⬤ '
109
- elsif chord.guitar_notes.select { |n| n.string == s && n.fret.nil? }.any?
110
- alt 'x '
111
- else
112
- ' '
113
- end
114
- end + "\n"
115
- end
116
-
117
- def render_note(found)
118
- found ? highlight('⬤') : base_color('│')
119
- end
120
- end
121
- end
122
- end
data/lib/cli/notes.rb DELETED
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coltrane
4
- module Cli
5
- # Interfaces notes outputting functionality with the lib
6
- class Notes
7
- def initialize(notes, desc: nil)
8
- @desc = desc || 'The notes you supplied:'
9
- notes = Coltrane::NoteSet.new(notes)
10
- @representation = Representation.build(notes)
11
- render
12
- # notes.each {|n| ColtraneSynth::Base.play(n, 0.1) } if Cli.config.sound
13
- end
14
-
15
- def render
16
- puts "\n" + [@desc, @representation.render].join("\n" * 2)
17
- end
18
- end
19
- end
20
- end
data/lib/cli/piano.rb DELETED
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coltrane
4
- module Cli
5
- # It allows rendering notes in an ASCII piano
6
- class Piano < Representation
7
- PIANO_TEMPLATE = <<~ASCII
8
- ┌─┬─┬┬─┬─╥─┬─┬┬─┬┬─┬─╥─┬─┬┬─┬─╥─┬─┬┬─┬┬─┬─┐
9
- │ │ ││ │ ║ │ ││ ││ │ ║ │ ││ │ ║ │ ││ ││ │ │
10
- │ │X││X│ ║ │X││X││X│ ║ │X││X│ ║ │X││X││X│ │
11
- │ │X││X│ ║ │X││X││X│ ║ │X││X│ ║ │X││X││X│ │
12
- │ ┕╥┙┕╥┙ ║ ┕╥┙┕╥┙┕╥┙ ║ ┕╥┙┕╥┙ ║ ┕╥┙┕╥┙┕╥┙ │
13
- │ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ │
14
- │XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX│
15
- └──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──┘
16
- ASCII
17
-
18
- def render
19
- PIANO_TEMPLATE.each_line.map.each_with_index do |l, ln|
20
- case ln
21
- when 2, 3 then replace_x(l, black_notes, 1, ln - 2)
22
- when 6 then replace_x(l, white_notes, 2)
23
- else l
24
- end
25
- end.join + "\n#{hint}"
26
- end
27
-
28
- private
29
-
30
- def replace_x(line, notes, size, index = 0)
31
- line.gsub('X' * size).with_index do |_match, i|
32
- note = notes[i % notes.size]
33
- next ' ' * size unless @notes.include?(note)
34
- Paint[replacer(note)[size == 2 ? 0..2 : index], 'red']
35
- end
36
- end
37
-
38
- def replacer(note)
39
- # TODO: Maybe extract this method into its own class/module
40
- case Cli.config.flavor
41
- when :intervals then (@ref_note - note).name
42
- when :marks then '◼ '
43
- when :degrees then @notes.degree(note).to_s.rjust(2, '0')
44
- when :notes then note.pretty_name.to_s.ljust(2, "\u266E")
45
- end
46
- end
47
-
48
- def white_notes
49
- Coltrane::Scale.major.notes
50
- end
51
-
52
- def black_notes
53
- Coltrane::Scale.pentatonic_major('C#', 4).notes
54
- end
55
- end
56
- end
57
- end
data/lib/cli/scale.rb DELETED
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coltrane
4
- module Cli
5
- # Interfaces commands with the scales functionality
6
- class Scale
7
- def self.parse(str)
8
- raise BadScaleError unless str&.include?('-')
9
- *scale_name, tone = str.split('-')
10
- Coltrane::Scale.fetch(scale_name.join('_'), tone)
11
- end
12
-
13
- def self.find(notes: [], chords: [])
14
- if notes.any?
15
- puts "\nSearching for scales containing #{notes.join(', ')}:\n\n"
16
- notes = NoteSet[*notes]
17
- elsif chords.any?
18
- puts "\nSearching for scales containing #{chords.join(', ')}:\n\n"
19
- notes = chords.reduce(NoteSet[]) do |memo, c|
20
- memo + Coltrane::Chord.new(name: c).notes
21
- end
22
- else raise BadFindScales
23
- end
24
- render_search(notes)
25
- puts "\nUnderlined means the scale has all notes"
26
- end
27
-
28
- def self.render_search(searched_notes)
29
- search = Coltrane::Scale.having_notes(searched_notes)
30
- output = []
31
- scale_width = search[:results].keys.map(&:size).max
32
- search[:results].each do |name, scales_by_tone|
33
- output << name.ljust(scale_width + 1, ' ')
34
- scales_by_tone.each do |tone_number, notes|
35
- p = (notes.size.to_f / searched_notes.size) * 100
36
- l = p == 100 ? p : (p + 20) * 0.4
37
- und = p == 100 ? :underline : nil
38
- color = Color::HSL.new(30, p, l / 2).html
39
- output << Paint["#{Note[tone_number].name}(#{notes.size})", color, und]
40
- output << ' '
41
- end
42
- output << "\n"
43
- end
44
- puts output.join
45
- end
46
-
47
- def initialize(scale)
48
- desc = "This is the #{scale.tone.name} #{scale.name} scale:"
49
- Coltrane::Cli::Notes.new(scale.notes)
50
- end
51
- end
52
- end
53
- end