wtf_chord 0.2.1 → 0.3
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/lib/wtf_chord/chord.rb +6 -46
- data/lib/wtf_chord/cli.rb +1 -1
- data/lib/wtf_chord/complexity_counter.rb +15 -5
- data/lib/wtf_chord/fingering.rb +2 -1
- data/lib/wtf_chord/fingerings_generator.rb +85 -0
- data/lib/wtf_chord/note.rb +3 -2
- data/lib/wtf_chord/rules.rb +3 -1
- data/lib/wtf_chord/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ffe99b5205f9a4cbde1ebdd815a41dc9f8f0836
|
4
|
+
data.tar.gz: d08a21cf109465b729d171e88e7a3f3631ca95df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e250bfa2ee065d20208dfca8831b33c216b2a4c2c450fecae75bef2a9b8c69189c2d6fd244dff31c25c00c38f9549d579f42b7ba6fca557509fb5a88460a2290
|
7
|
+
data.tar.gz: 25a18c48cecc08247ccfa78c6c396d2edd9c4481b0c86f39cf23636fb1b7bf51ba038d15b5e2fd0db8cd89c904aaf5d939cacb1a78233dcd0e7108495e1fd4cc
|
data/lib/wtf_chord/chord.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
require 'wtf_chord/fingering'
|
2
|
+
require 'wtf_chord/fingerings_generator'
|
2
3
|
|
3
4
|
module WTFChord
|
4
5
|
class Chord
|
5
|
-
MAX_DIST = 5
|
6
|
-
MAX_FRET = 7
|
7
|
-
|
8
6
|
attr_reader :pitch, :steps, :notes, :name
|
9
7
|
|
10
8
|
def initialize(note, name)
|
@@ -18,51 +16,13 @@ module WTFChord
|
|
18
16
|
"#{name} (#{@notes.map(&:key) * ' - '})"
|
19
17
|
end
|
20
18
|
|
21
|
-
def fingerings(limit =
|
22
|
-
|
23
|
-
|
24
|
-
(0..MAX_FRET).each do |from_fret|
|
25
|
-
f = get_fingering(from_fret)
|
26
|
-
next if list.include?(f)
|
27
|
-
list << f if all_notes?(f.used_strings)
|
28
|
-
end
|
29
|
-
|
30
|
-
sort_fingerings(list, limit)
|
31
|
-
end
|
32
|
-
|
33
|
-
def get_fingering(from_fret = 0)
|
34
|
-
to_fret = from_fret + MAX_DIST
|
35
|
-
Fingering.new(GUITAR) do |f|
|
36
|
-
f.strings.each do |s|
|
37
|
-
fret = (from_fret..to_fret).detect { |dist| @notes.include?((s.original + dist).note) }
|
38
|
-
fret ? s.hold_on(fret) : s.dead
|
39
|
-
end
|
40
|
-
|
41
|
-
adjust_fingering(f.used_strings[0], to_fret, 0) while should_adjust?(f.used_strings[0], 0)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def all_notes?(strings)
|
46
|
-
snotes = strings.map(&:note).tap(&:uniq!)
|
47
|
-
@notes.all? { |n| snotes.include?(n) }
|
48
|
-
end
|
49
|
-
|
50
|
-
def adjust_fingering(string, to_fret, i = 0)
|
51
|
-
while string.fret < to_fret.pred
|
52
|
-
string.hold_on(string.fret + 1)
|
53
|
-
break if @notes.include?(string.note)
|
54
|
-
end
|
55
|
-
|
56
|
-
string.dead if !string.dead? && string.note != @notes[i]
|
57
|
-
end
|
58
|
-
|
59
|
-
def should_adjust?(string, i = 0)
|
60
|
-
string && string.note != @notes[i]
|
19
|
+
def fingerings(limit = nil)
|
20
|
+
limit ||= 5
|
21
|
+
FingeringsGenerator.new(self).call[0, limit]
|
61
22
|
end
|
62
23
|
|
63
|
-
def
|
64
|
-
|
65
|
-
list[0...limit].sort_by!(&:min_fret)
|
24
|
+
def third_tone
|
25
|
+
@third_tone ||= @notes[@steps.index(7) || -1]
|
66
26
|
end
|
67
27
|
end
|
68
28
|
end
|
data/lib/wtf_chord/cli.rb
CHANGED
@@ -6,17 +6,27 @@ module WTFChord
|
|
6
6
|
|
7
7
|
def rate
|
8
8
|
frets = @fingering.holded_strings.map(&:fret)
|
9
|
-
barre = frets.uniq.keep_if { |o| frets.count(o) >= 2 }
|
10
|
-
barre_strings = barre ? frets.count(barre).pred : 0
|
9
|
+
barre = frets.uniq.keep_if { |o| frets.count(o) >= 2 }
|
10
|
+
barre_strings = barre.min ? frets.count(barre.min).pred : 0
|
11
11
|
|
12
12
|
base_rate = begin
|
13
|
-
Rational(holded_strings - barre_strings,
|
14
|
-
Rational(finger_dist(
|
13
|
+
Rational(holded_strings - barre_strings, 4).to_f +
|
14
|
+
Rational(finger_dist(@fingering.used_strings.map(&:fret)), 4).to_f
|
15
15
|
end
|
16
16
|
|
17
|
+
base_rate += 0.5 if (holded_strings - barre_strings) > 4
|
18
|
+
|
17
19
|
# p [@fingering, holded_strings, barre_strings]
|
18
20
|
|
19
|
-
|
21
|
+
if holded_strings > 4
|
22
|
+
uniq_frets = frets.uniq.size
|
23
|
+
|
24
|
+
if barre.size > 1 && uniq_frets == 3 && frets.count(barre.max) > barre_strings.next
|
25
|
+
base_rate += 1 if complex_barre?(barre.max, frets)
|
26
|
+
elsif barre_strings.next >= 2 || uniq_frets.size > 3
|
27
|
+
base_rate += 1 if complex_barre?(barre.min, frets)
|
28
|
+
end
|
29
|
+
end
|
20
30
|
|
21
31
|
base_rate
|
22
32
|
end
|
data/lib/wtf_chord/fingering.rb
CHANGED
@@ -4,9 +4,10 @@ require 'wtf_chord/formatter'
|
|
4
4
|
|
5
5
|
module WTFChord
|
6
6
|
class Fingering < Fretboard
|
7
|
-
def initialize(guitar)
|
7
|
+
def initialize(guitar, fingers = nil)
|
8
8
|
@capo = guitar.capo
|
9
9
|
@strings = guitar.strings.map(&:dup)
|
10
|
+
set_fingers(fingers) if fingers.is_a?(Array)
|
10
11
|
yield(self) if block_given?
|
11
12
|
end
|
12
13
|
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module WTFChord
|
2
|
+
class Chord
|
3
|
+
end
|
4
|
+
|
5
|
+
class FingeringsGenerator < DelegateClass(Chord)
|
6
|
+
MAX_DIST = 5
|
7
|
+
MAX_FRET = 7
|
8
|
+
|
9
|
+
def fingerings
|
10
|
+
@fingerings ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
fingerings.clear
|
15
|
+
|
16
|
+
(0...MAX_FRET).each do |from|
|
17
|
+
to = from + MAX_DIST
|
18
|
+
generate(from...to) do |variant|
|
19
|
+
fingerings << variant if filter_variant(variant)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
fingerings.sort_by!(&:complexity)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def generate(fret_range)
|
29
|
+
combinations = GUITAR.strings.map.with_index do |s, index|
|
30
|
+
fret_range.select do |dist|
|
31
|
+
pitch = s.original + dist
|
32
|
+
has_note?(pitch)
|
33
|
+
end.tap do |frets|
|
34
|
+
frets << nil if frets.size == 0
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
combinations.inject(&:product).each do |fingers|
|
39
|
+
fingers.flatten!
|
40
|
+
Fingering.new(GUITAR, fingers) do |variant|
|
41
|
+
adjust(variant)
|
42
|
+
yield(variant)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def filter_variant(variant)
|
48
|
+
used_strings = variant.used_strings
|
49
|
+
used_notes = used_strings.map(&:note)
|
50
|
+
tones_count = notes.map { |n| used_notes.count(n) }
|
51
|
+
|
52
|
+
!fingerings.include?(variant) &&
|
53
|
+
basetone?(used_strings[0]) &&
|
54
|
+
(third?(used_strings[1]) || third?(used_strings[2])) &&
|
55
|
+
all_notes?(used_notes) &&
|
56
|
+
used_notes.each_cons(2).none? { |(l, r)| l == r } &&
|
57
|
+
tones_count.all? { |n| tones_count[0] >= n || tones_count[notes.index(third_tone)] >= n } &&
|
58
|
+
variant.complexity <= 2.25
|
59
|
+
end
|
60
|
+
|
61
|
+
def adjust(fingering)
|
62
|
+
while (string = fingering.used_strings[0]) && !basetone?(string)
|
63
|
+
string.dead if !string.dead?
|
64
|
+
break if fingering.used_strings.size == 4
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def all_notes?(used_notes)
|
69
|
+
notes.all? { |n| used_notes.include?(n) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def has_note?(value)
|
73
|
+
value = value.note if !value.is_a?(Note) && value.respond_to?(:note)
|
74
|
+
notes.include?(value)
|
75
|
+
end
|
76
|
+
|
77
|
+
def basetone?(string)
|
78
|
+
string && string.note == notes[0]
|
79
|
+
end
|
80
|
+
|
81
|
+
def third?(string)
|
82
|
+
string && (string.note == third_tone)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/wtf_chord/note.rb
CHANGED
@@ -25,8 +25,9 @@ module WTFChord
|
|
25
25
|
|
26
26
|
def == other
|
27
27
|
case other
|
28
|
-
when String
|
29
|
-
when Integer
|
28
|
+
when String then other.casecmp(@key).zero?
|
29
|
+
when Integer then other == @position
|
30
|
+
when Note then other.position == @position
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
data/lib/wtf_chord/rules.rb
CHANGED
@@ -23,7 +23,9 @@ module WTFChord
|
|
23
23
|
name.match(pattern) do |m|
|
24
24
|
base = chords[m[:name]] || chords["M"]
|
25
25
|
steps.concat(base)
|
26
|
-
|
26
|
+
|
27
|
+
ext = extra[m[:ext]] if m[:ext]
|
28
|
+
steps.concat(ext) if ext
|
27
29
|
end
|
28
30
|
|
29
31
|
steps.tap(&:uniq!)
|
data/lib/wtf_chord/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wtf_chord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton
|
@@ -107,6 +107,7 @@ files:
|
|
107
107
|
- lib/wtf_chord/cli.rb
|
108
108
|
- lib/wtf_chord/complexity_counter.rb
|
109
109
|
- lib/wtf_chord/fingering.rb
|
110
|
+
- lib/wtf_chord/fingerings_generator.rb
|
110
111
|
- lib/wtf_chord/formatter.rb
|
111
112
|
- lib/wtf_chord/formatters/base.rb
|
112
113
|
- lib/wtf_chord/formatters/default.rb
|