tonal-tools 4.0.1 → 5.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/tonal/approximation.rb +30 -21
- data/lib/tonal/attributions.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71f085a27fce9f25e0dab185ae58880802186931c3946a39d41e9e975d2fb138
|
4
|
+
data.tar.gz: f4bb5d1c1778aa14b8dd35080be434f409f711a6bd515893276209c338cb4c60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28328c475862c7a51e34d6ea9cfeabe3ede92f7716515bf7ca514c4cff2a1e07fba240fd76a0ad98fc96c0c07b2fc15c047df31b957b032956805da3cbf862d0
|
7
|
+
data.tar.gz: 25b3b997fd617897c43f1d543424581a36f4d26f06c05fbc28ae7b7a6d1b1d53e13c97761380da36f9e8a9160b1124edf85d81aeb4a2aec527646c096ecb1b46
|
data/lib/tonal/approximation.rb
CHANGED
@@ -20,7 +20,7 @@ class Tonal::Ratio
|
|
20
20
|
# @return [Tonal::Ratio::Approximation::Set] of ratios within cent tolerance of self found using continued fraction approximation
|
21
21
|
# @example
|
22
22
|
# Tonal::Ratio.ed(12,1).approximate.by_continued_fraction
|
23
|
-
# => (4771397596969315/4503599627370496): [(
|
23
|
+
# => (4771397596969315/4503599627370496): [(17/16), (18/17), (89/84), (196/185), (1461/1379), (1657/1564), (3118/2943), (7893/7450), (18904/17843)]
|
24
24
|
# @param cents_tolerance the cents tolerance used to scope the collection
|
25
25
|
# @param depth the maximum number of ratios in the collection
|
26
26
|
# @param max_prime the maximum prime number to allow in the collection
|
@@ -29,11 +29,11 @@ class Tonal::Ratio
|
|
29
29
|
def by_continued_fraction(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME, conv_limit: CONVERGENT_LIMIT)
|
30
30
|
self_in_cents = to_cents
|
31
31
|
within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
|
32
|
-
Set.new(ratio: ratio)
|
32
|
+
Set.new(ratio: ratio) do |ratios|
|
33
33
|
ContinuedFraction.new(antecedent.to_f/consequent, conv_limit).convergents.each do |convergent|
|
34
34
|
ratio2 = ratio.class.new(convergent.numerator,convergent.denominator)
|
35
|
-
|
36
|
-
break if
|
35
|
+
ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
|
36
|
+
break if ratios.length >= depth
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -41,7 +41,7 @@ class Tonal::Ratio
|
|
41
41
|
# @return [Tonal::Ratio::Approximation::Set] of ratios within cent tolerance of self found using a quotient walk on the fraction tree
|
42
42
|
# @example
|
43
43
|
# Tonal::Ratio.ed(12,1).approximate.by_quotient_walk(max_prime: 89)
|
44
|
-
# => (4771397596969315/4503599627370496): [(
|
44
|
+
# => (4771397596969315/4503599627370496): [(17/16), (18/17), (35/33), (53/50), (71/67), (89/84), (196/185)]
|
45
45
|
# @param cents_tolerance the cents tolerance used to scope the collection
|
46
46
|
# @param depth the maximum number of ratios in the collection
|
47
47
|
# @param max_prime the maximum prime number to allow in the collection
|
@@ -51,11 +51,11 @@ class Tonal::Ratio
|
|
51
51
|
self_in_cents = to_cents
|
52
52
|
within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
|
53
53
|
|
54
|
-
Set.new(ratio: ratio)
|
54
|
+
Set.new(ratio: ratio) do |ratios|
|
55
55
|
FractionTree.quotient_walk(to_f, limit: conv_limit).each do |node|
|
56
56
|
ratio2 = ratio.class.new(node.weight)
|
57
|
-
|
58
|
-
break if
|
57
|
+
ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
|
58
|
+
break if ratios.length >= depth
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -63,7 +63,7 @@ class Tonal::Ratio
|
|
63
63
|
# @return [Tonal::Ratio::Approximation::Set] of fraction tree ratios within cent tolerance of self
|
64
64
|
# @example
|
65
65
|
# Tonal::Ratio.ed(12,1).approximate.by_tree_path(max_prime: 17)
|
66
|
-
# => (4771397596969315/4503599627370496): [(
|
66
|
+
# => (4771397596969315/4503599627370496): [(17/16), (18/17), (35/33)]
|
67
67
|
# @param cents_tolerance the cents tolerance used to scope the collection
|
68
68
|
# @param depth the maximum number of ratios in the collection
|
69
69
|
# @param max_prime the maximum prime number to allow in the collection
|
@@ -71,11 +71,11 @@ class Tonal::Ratio
|
|
71
71
|
def by_tree_path(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME)
|
72
72
|
self_in_cents = to_cents
|
73
73
|
within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
|
74
|
-
Set.new(ratio: ratio)
|
74
|
+
Set.new(ratio: ratio) do |ratios|
|
75
75
|
FractionTree.path_to(to_f).each do |node|
|
76
76
|
ratio2 = ratio.class.new(node.weight)
|
77
|
-
|
78
|
-
break if
|
77
|
+
ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
|
78
|
+
break if ratios.length >= depth
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
@@ -83,7 +83,7 @@ class Tonal::Ratio
|
|
83
83
|
# @return [Tonal::Ratio::Approximation::Set] of superparticular approximations within cent tolerance of self
|
84
84
|
# @example
|
85
85
|
# Tonal::Ratio.new(3/2r).approximate.by_superparticular
|
86
|
-
# => (3/2): [(
|
86
|
+
# => (3/2): [(1041/692), (1044/694), (1047/696), (1050/698), (1053/700), (1056/702), (1059/704), (1062/706), (1065/708), (1068/710), (1071/712), (1074/714), (1077/716), (1080/718), (1083/720), (1086/722), (1089/724), (1092/726), (1095/728), (1098/730)]
|
87
87
|
# @param cents_tolerance the cents tolerance used to scope the collection
|
88
88
|
# @param depth the maximum number of ratios in the collection
|
89
89
|
# @param max_prime the maximum prime number to allow in the collection
|
@@ -92,12 +92,12 @@ class Tonal::Ratio
|
|
92
92
|
def by_superparticular(cents_tolerance: Tonal::Cents::TOLERANCE, depth: 20, max_prime: DEFAULT_MAX_PRIME, superpart: :upper)
|
93
93
|
self_in_cents = to_cents
|
94
94
|
within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
|
95
|
-
Set.new(ratio: ratio)
|
95
|
+
Set.new(ratio: ratio) do |ratios|
|
96
96
|
n = 1
|
97
97
|
while true do
|
98
98
|
ratio2 = ratio.class.superparticular(n, factor: ratio.to_r, superpart:)
|
99
|
-
|
100
|
-
break if
|
99
|
+
ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime) && ratio2 != ratio
|
100
|
+
break if ratios.length >= depth
|
101
101
|
n += 1
|
102
102
|
end
|
103
103
|
end
|
@@ -116,15 +116,15 @@ class Tonal::Ratio
|
|
116
116
|
def by_neighborhood(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME, max_boundary: DEFAULT_MAX_GRID_BOUNDARY, max_scale: DEFAULT_MAX_GRID_SCALE)
|
117
117
|
self_in_cents = to_cents
|
118
118
|
within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
|
119
|
-
Set.new(ratio: ratio)
|
119
|
+
Set.new(ratio: ratio) do |ratios|
|
120
120
|
scale = 1
|
121
121
|
boundary = 1
|
122
122
|
|
123
|
-
while
|
123
|
+
while ratios.length <= depth && scale <= max_scale do
|
124
124
|
while boundary <= max_boundary
|
125
125
|
vacinity = ratio.respond_to?(:to_basic_ratio) ? to_basic_ratio.scale(scale) : ratio.scale(scale)
|
126
126
|
self.class.neighbors(away: boundary, vacinity: vacinity).each do |neighbor|
|
127
|
-
|
127
|
+
ratios << neighbor if ratio.class.within_cents?(self_in_cents, neighbor.to_cents, within) && neighbor.within_prime?(max_prime) && neighbor != ratio
|
128
128
|
end
|
129
129
|
boundary += 1
|
130
130
|
end
|
@@ -171,19 +171,28 @@ class Tonal::Ratio
|
|
171
171
|
|
172
172
|
class Set
|
173
173
|
extend Forwardable
|
174
|
-
def_delegators :@ratios, :count, :length, :min, :max, :entries, :all?, :any?, :reject, :map
|
174
|
+
def_delegators :@ratios, :count, :length, :min, :max, :entries, :all?, :any?, :reject, :map, :find_index
|
175
175
|
|
176
176
|
attr_reader :ratios, :ratio
|
177
177
|
|
178
178
|
def initialize(ratio:)
|
179
179
|
@ratio = ratio
|
180
|
-
@ratios =
|
180
|
+
@ratios = ::Set.new
|
181
|
+
yield @ratios if block_given?
|
181
182
|
end
|
182
183
|
alias :approximations :entries
|
183
184
|
|
184
185
|
def inspect
|
185
186
|
"#{ratio}: #{entries}"
|
186
187
|
end
|
188
|
+
|
189
|
+
def sort_by(&)
|
190
|
+
self.class.new(ratio: ratio) do |ratios|
|
191
|
+
entries.sort_by(&).each do |ratio|
|
192
|
+
ratios << ratio
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
187
196
|
end
|
188
197
|
end
|
189
198
|
end
|
data/lib/tonal/attributions.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tonal-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jose Hales-Garcia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-03-
|
11
|
+
date: 2024-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yaml
|