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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 23feadfbf5375e890423135cc86a56d9b70af3e8
4
- data.tar.gz: aaa6a0d46fbeb51e715306da3d127b86816ed293
3
+ metadata.gz: 0ffe99b5205f9a4cbde1ebdd815a41dc9f8f0836
4
+ data.tar.gz: d08a21cf109465b729d171e88e7a3f3631ca95df
5
5
  SHA512:
6
- metadata.gz: 711ef213b9ea7302e812c122fda26aee2bb305960a0a1fc3f687106948ea401dcfe17eaeac3972d9a42f6bdf22f6189d01255be790bf89194dbb5e6479a3d86c
7
- data.tar.gz: 4c081a0a57e196422c13fa0a40f671e55d2b39ad49f96678c8b87da277d5e242d4d38fd19924d7e0d920444cc290af7d5984208e75f8a1cbc4dbeeddd10e7547
6
+ metadata.gz: e250bfa2ee065d20208dfca8831b33c216b2a4c2c450fecae75bef2a9b8c69189c2d6fd244dff31c25c00c38f9549d579f42b7ba6fca557509fb5a88460a2290
7
+ data.tar.gz: 25a18c48cecc08247ccfa78c6c396d2edd9c4481b0c86f39cf23636fb1b7bf51ba038d15b5e2fd0db8cd89c904aaf5d939cacb1a78233dcd0e7108495e1fd4cc
@@ -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 = 3)
22
- list = []
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 sort_fingerings(list, limit)
64
- list.sort_by!(&:complexity)
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
@@ -31,7 +31,7 @@ module WTFChord
31
31
  ##
32
32
  # Options
33
33
  #
34
- options['amount'] = 3
34
+ options['amount'] = 5
35
35
  options['output'] = 'default'
36
36
  options['rates'] = false
37
37
 
@@ -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 }.min
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, 6).to_f +
14
- Rational(finger_dist(frets), 5).to_f
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
- base_rate += 1 if (barre_strings > 2 || frets.uniq.size > 3) && complex_barre?(barre, frets)
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
@@ -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
@@ -25,8 +25,9 @@ module WTFChord
25
25
 
26
26
  def == other
27
27
  case other
28
- when String then other.casecmp(@key).zero?
29
- when Integer, Note then other == @position
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
 
@@ -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
- steps.concat(extra[m[:ext]]) if m[:ext] && m[:ext].length <= (6 - steps.length)
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!)
@@ -1,3 +1,3 @@
1
1
  module WTFChord
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3"
3
3
  end
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.2.1
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