wtf_chord 0.2.1 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|