tonal-tools 2.0.1 → 3.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/attributions.rb +1 -1
- data/lib/tonal/cents.rb +4 -4
- data/lib/tonal/extensions.rb +9 -29
- data/lib/tonal/hertz.rb +5 -5
- data/lib/tonal/log.rb +2 -2
- data/lib/tonal/ratio.rb +25 -20
- data/lib/tonal/reduced_ratio.rb +11 -1
- data/lib/tonal/step.rb +46 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed09e5cd360980028547160d80bf374eacc14df7596e7cdfa0034bc295de771a
|
4
|
+
data.tar.gz: 3f17b4accf20c651fb3f7e172d9e4e5c094eb62a1a5705274ef36b16577f8f4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22aef50e39cbc83f269fa1a326da40e1d8068b1ff965ffbbaeda8c82919aadce2d1ef11b6988f4c78f87321ddfa010fd07def250b597015bacb3dbf09accd94d
|
7
|
+
data.tar.gz: 186a12f240251e6a6f1a2f0142cfe3f800151f182827fa06f7f6c999d0e652277a4cbc473a3e0ae6838ff6d1786a7f4c5ce80a9de35a2fb5572d246b3d43e884
|
data/lib/tonal/attributions.rb
CHANGED
data/lib/tonal/cents.rb
CHANGED
@@ -12,7 +12,7 @@ class Tonal::Cents
|
|
12
12
|
|
13
13
|
attr_reader :log, :ratio
|
14
14
|
|
15
|
-
# @return [Cents]
|
15
|
+
# @return [Tonal::Cents]
|
16
16
|
# @example
|
17
17
|
# Tonal::Cents.new(ratio: 2**(2.0/12)) => 200.0
|
18
18
|
# @param cents [Numeric, Tonal::Log2]
|
@@ -40,7 +40,7 @@ class Tonal::Cents
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
# @return [Cents] the default cents tolerance
|
43
|
+
# @return [Tonal::Cents] the default cents tolerance
|
44
44
|
# @example
|
45
45
|
# Tonal::Cents.default_tolerance => 5
|
46
46
|
#
|
@@ -58,7 +58,7 @@ class Tonal::Cents
|
|
58
58
|
alias :cents :value
|
59
59
|
|
60
60
|
# @return
|
61
|
-
# [Cents] nearest hundredth cent value
|
61
|
+
# [Tonal::Cents] nearest hundredth cent value
|
62
62
|
# @example
|
63
63
|
# Tonal::Cents.new(cents: 701.9550008653874).nearest_hundredth => 700.0
|
64
64
|
#
|
@@ -85,7 +85,7 @@ class Tonal::Cents
|
|
85
85
|
end
|
86
86
|
|
87
87
|
# @return
|
88
|
-
# [String] the string representation of Cents
|
88
|
+
# [String] the string representation of Tonal::Cents
|
89
89
|
# @example
|
90
90
|
# Tonal::Cents.new(100.0).inspect => "100.0"
|
91
91
|
#
|
data/lib/tonal/extensions.rb
CHANGED
@@ -86,7 +86,7 @@ class Numeric
|
|
86
86
|
def hz = Tonal::Hertz.new(self)
|
87
87
|
alias :to_hz :hz
|
88
88
|
|
89
|
-
# @return [Step] the step of self in the given modulo
|
89
|
+
# @return [Tonal::Step] the step of self in the given modulo
|
90
90
|
# @example
|
91
91
|
# (5/4r).step(12) => 4\12
|
92
92
|
# @param modulo
|
@@ -131,7 +131,7 @@ class Numeric
|
|
131
131
|
#
|
132
132
|
def efficiency(modulo) = (Tonal::Cents::CENT_SCALE * step(modulo).step / modulo.to_f) - to_cents
|
133
133
|
|
134
|
-
# @return [Interval] beween self (upper) and ratio (lower)
|
134
|
+
# @return [Tonal::Interval] beween self (upper) and ratio (lower)
|
135
135
|
# @example
|
136
136
|
# (133).interval_with(3/2r) => 133/96 (133/128 / 3/2)
|
137
137
|
# @param ratio
|
@@ -149,7 +149,7 @@ class Numeric
|
|
149
149
|
# @example
|
150
150
|
# (31/30r).prime_divisions => [[[31, 1]], [[2, 1], [3, 1], [5, 1]]]
|
151
151
|
#
|
152
|
-
def prime_divisions = self.
|
152
|
+
def prime_divisions = [self.numerator.prime_division, self.denominator.prime_division]
|
153
153
|
|
154
154
|
# @return [Integer] the maximum prime factor of self
|
155
155
|
# @example
|
@@ -163,20 +163,6 @@ class Numeric
|
|
163
163
|
#
|
164
164
|
def min_prime = prime_divisions.flatten(1).map(&:first).min
|
165
165
|
|
166
|
-
# @return [Tonal::ReducedRatio], the Ernst Levy negative of self
|
167
|
-
# @example
|
168
|
-
# (7/4r).negative => (12/7)
|
169
|
-
#
|
170
|
-
def negative = self.ratio.negative
|
171
|
-
|
172
|
-
# @return [Tonal::ReducedRatio], the ratio rotated on the given axis, default 1/1
|
173
|
-
# @example
|
174
|
-
# (3/2r).mirror => (4/3)
|
175
|
-
#
|
176
|
-
def mirror(axis=1/1r) = self.ratio.mirror(axis)
|
177
|
-
end
|
178
|
-
|
179
|
-
class Rational
|
180
166
|
# @return [Vector], self expressed as a Vector
|
181
167
|
# @example
|
182
168
|
# (3/2r).to_vector => Vector[3, 2]
|
@@ -184,23 +170,17 @@ class Rational
|
|
184
170
|
def to_vector = Vector[self.numerator, self.denominator]
|
185
171
|
alias :vector :to_vector
|
186
172
|
|
187
|
-
# @return [
|
188
|
-
# @example
|
189
|
-
# (31/30r).prime_divisions => [[[31, 1]], [[2, 1], [3, 1], [5, 1]]]
|
190
|
-
#
|
191
|
-
def prime_divisions = self.ratio.prime_divisions
|
192
|
-
|
193
|
-
# @return [Integer] the maximum prime factor of self
|
173
|
+
# @return [Tonal::ReducedRatio], the Ernst Levy negative of self
|
194
174
|
# @example
|
195
|
-
#
|
175
|
+
# (7/4r).negative => (12/7)
|
196
176
|
#
|
197
|
-
def
|
177
|
+
def negative = self.ratio.negative
|
198
178
|
|
199
|
-
# @return [
|
179
|
+
# @return [Tonal::ReducedRatio], the ratio rotated on the given axis, default 1/1
|
200
180
|
# @example
|
201
|
-
# (
|
181
|
+
# (3/2r).mirror => (4/3)
|
202
182
|
#
|
203
|
-
def
|
183
|
+
def mirror(axis=1/1r) = self.ratio.mirror(axis)
|
204
184
|
end
|
205
185
|
|
206
186
|
class Integer
|
data/lib/tonal/hertz.rb
CHANGED
@@ -3,9 +3,9 @@ class Tonal::Hertz
|
|
3
3
|
|
4
4
|
attr_reader :value
|
5
5
|
|
6
|
-
# @return [Hertz]
|
6
|
+
# @return [Tonal::Hertz]
|
7
7
|
# @example
|
8
|
-
# Hertz.new(1000.0) => 1000.0
|
8
|
+
# Tonal::Hertz.new(1000.0) => 1000.0
|
9
9
|
# @param arg [Numeric, Tonal::Hertz]
|
10
10
|
#
|
11
11
|
def initialize(arg)
|
@@ -13,7 +13,7 @@ class Tonal::Hertz
|
|
13
13
|
@value = arg.kind_of?(self.class) ? arg.inspect : arg
|
14
14
|
end
|
15
15
|
|
16
|
-
# @return [Hertz] 440 Hz
|
16
|
+
# @return [Tonal::Hertz] 440 Hz
|
17
17
|
# @example
|
18
18
|
# Tonal::Hertz.a440 => 440.0
|
19
19
|
#
|
@@ -38,9 +38,9 @@ class Tonal::Hertz
|
|
38
38
|
value.to_f
|
39
39
|
end
|
40
40
|
|
41
|
-
# @return [String] the string representation of Hertz
|
41
|
+
# @return [String] the string representation of Tonal::Hertz
|
42
42
|
# @example
|
43
|
-
# Hertz(1000.0).inspect => "1000.0"
|
43
|
+
# Tonal::Hertz(1000.0).inspect => "1000.0"
|
44
44
|
#
|
45
45
|
def inspect
|
46
46
|
"#{value}"
|
data/lib/tonal/log.rb
CHANGED
@@ -53,13 +53,13 @@ class Tonal::Log
|
|
53
53
|
# @return [Tonal::Cents] the cents scale logarithm
|
54
54
|
# @example
|
55
55
|
# Tonal::Log.new(logarithmand: 3/2r, base: 2).to_cents => 701.9550008653874
|
56
|
-
# @see Cents
|
56
|
+
# @see Tonal::Cents
|
57
57
|
#
|
58
58
|
def to_cents(precision: Tonal::Cents::PRECISION)
|
59
59
|
Tonal::Cents.new(log: self, precision: precision)
|
60
60
|
end
|
61
61
|
|
62
|
-
# @return [Step] the nearest step in the given modulo
|
62
|
+
# @return [Tonal::Step] the nearest step in the given modulo
|
63
63
|
# @example
|
64
64
|
# Tonal::Log.new(3/2r, base: 2).step(12) => 7\12
|
65
65
|
#
|
data/lib/tonal/ratio.rb
CHANGED
@@ -16,18 +16,7 @@ class Tonal::Ratio
|
|
16
16
|
raise ArgumentError, "Antecedent must be Numeric" unless antecedent.kind_of?(Numeric)
|
17
17
|
raise ArgumentError, "Consequent must be Numeric or nil" unless (consequent.kind_of?(Numeric) || consequent.nil?)
|
18
18
|
|
19
|
-
|
20
|
-
@antecedent = antecedent.abs
|
21
|
-
@consequent = consequent.abs
|
22
|
-
else
|
23
|
-
antecedent = antecedent.abs
|
24
|
-
@antecedent = antecedent.numerator
|
25
|
-
@consequent = antecedent.denominator
|
26
|
-
end
|
27
|
-
@equave = equave
|
28
|
-
@reduced_antecedent, @reduced_consequent = _equave_reduce(equave)
|
29
|
-
@label = label
|
30
|
-
@approximation = Approximation.new(ratio: self)
|
19
|
+
_initialize(antecedent, consequent, label:, equave:)
|
31
20
|
end
|
32
21
|
|
33
22
|
alias :numerator :antecedent
|
@@ -183,7 +172,7 @@ class Tonal::Ratio
|
|
183
172
|
# Tonal::ReducedRatio.new(3,2).step(12) => 7
|
184
173
|
#
|
185
174
|
def step(modulo=12)
|
186
|
-
|
175
|
+
Tonal::Step.new(ratio: to_r, modulo: modulo)
|
187
176
|
end
|
188
177
|
|
189
178
|
# @return [Float] degrees
|
@@ -254,13 +243,12 @@ class Tonal::Ratio
|
|
254
243
|
end
|
255
244
|
alias :reflect :invert
|
256
245
|
|
257
|
-
# @return [
|
246
|
+
# @return [Tonal::Ratio] with antecedent and precedent switched
|
258
247
|
# @example
|
259
248
|
# Tonal::Ratio.new(3,2).invert! => (2/3)
|
260
249
|
#
|
261
250
|
def invert!
|
262
|
-
|
263
|
-
@antecedent, @consequent = consequent, tmp
|
251
|
+
_initialize(consequent, antecedent, label: label, equave: equave)
|
264
252
|
self
|
265
253
|
end
|
266
254
|
|
@@ -273,7 +261,7 @@ class Tonal::Ratio
|
|
273
261
|
(self.class.new(axis) ** 2) / self
|
274
262
|
end
|
275
263
|
|
276
|
-
# @return Tonal::ReducedRatio the Ernst Levy negative of self
|
264
|
+
# @return [Tonal::ReducedRatio] the Ernst Levy negative of self
|
277
265
|
# @example
|
278
266
|
# Tonal::ReducedRatio.new(7/4r).negative => (12/7)
|
279
267
|
#
|
@@ -428,13 +416,15 @@ class Tonal::Ratio
|
|
428
416
|
benedetti_height.prime_division.reject{|p| prime_rejects.include?(p.first) }.sum{|p| p.first * p.last }
|
429
417
|
end
|
430
418
|
|
431
|
-
# @return [
|
419
|
+
# @return [Tonal::Cents] the cents difference between self and its step in the given modulo
|
432
420
|
# @example
|
433
421
|
# Tonal::ReducedRatio.new(3,2).efficiency(12) => -1.955000865387433
|
434
422
|
# @param modulo
|
435
423
|
#
|
436
424
|
def efficiency(modulo)
|
437
|
-
|
425
|
+
# We want the efficiency from the ratio, instead of from the step.
|
426
|
+
# If step efficiency is X cents, then ratio efficiency is -X cents.
|
427
|
+
step(modulo).efficiency * -1.0
|
438
428
|
end
|
439
429
|
|
440
430
|
# @return [Array] the results of ratio dividing and multiplying self
|
@@ -458,7 +448,7 @@ class Tonal::Ratio
|
|
458
448
|
end
|
459
449
|
alias :min_plus :plus_minus
|
460
450
|
|
461
|
-
# @return [Cents] cent difference between self and other ratio
|
451
|
+
# @return [Tonal::Cents] cent difference between self and other ratio
|
462
452
|
# @example
|
463
453
|
# Tonal::ReducedRatio.new(3,2).cent_diff(4/3r) => 203.92
|
464
454
|
# @param other_ratio [Tonal::ReducedRatio, Numeric] from which self's cents is measured
|
@@ -554,6 +544,21 @@ class Tonal::Ratio
|
|
554
544
|
end
|
555
545
|
|
556
546
|
private
|
547
|
+
def _initialize(antecedent, consequent=nil, label: nil, equave: 2/1r)
|
548
|
+
if consequent
|
549
|
+
@antecedent = antecedent.abs
|
550
|
+
@consequent = consequent.abs
|
551
|
+
else
|
552
|
+
antecedent = antecedent.abs
|
553
|
+
@antecedent = antecedent.numerator
|
554
|
+
@consequent = antecedent.denominator
|
555
|
+
end
|
556
|
+
@equave = equave
|
557
|
+
@reduced_antecedent, @reduced_consequent = _equave_reduce(equave)
|
558
|
+
@label = label
|
559
|
+
@approximation = Approximation.new(ratio: self)
|
560
|
+
end
|
561
|
+
|
557
562
|
def raise_if_negative(*args)
|
558
563
|
raise ArgumentError, "Arguments must be greater than zero" if args.any?{|i| i < 0 }
|
559
564
|
end
|
data/lib/tonal/reduced_ratio.rb
CHANGED
@@ -25,7 +25,7 @@ class Tonal::ReducedRatio < Tonal::Ratio
|
|
25
25
|
Tonal::Ratio.new(antecedent, consequent)
|
26
26
|
end
|
27
27
|
|
28
|
-
# @return [Interval] between self (upper) and ratio (lower)
|
28
|
+
# @return [Tonal::Interval] between self (upper) and ratio (lower)
|
29
29
|
# @example
|
30
30
|
# Tonal::ReducedRatio.new(133).interval_with(3/2r) => 133/96 (133/128 / 3/2)
|
31
31
|
# @param ratio
|
@@ -34,4 +34,14 @@ class Tonal::ReducedRatio < Tonal::Ratio
|
|
34
34
|
r = ratio.is_a?(self.class) ? ratio : self.class.new(ratio)
|
35
35
|
Tonal::Interval.new(self, r)
|
36
36
|
end
|
37
|
+
|
38
|
+
# @return [Tonal::ReducedRatio] with antecedent and precedent switched
|
39
|
+
# @example
|
40
|
+
# Tonal::ReducedRatio.new(3,2).invert! => (4/3)
|
41
|
+
#
|
42
|
+
def invert!
|
43
|
+
super
|
44
|
+
@antecedent, @consequent = @reduced_antecedent, @reduced_consequent
|
45
|
+
self
|
46
|
+
end
|
37
47
|
end
|
data/lib/tonal/step.rb
CHANGED
@@ -28,18 +28,62 @@ class Tonal::Step
|
|
28
28
|
end
|
29
29
|
alias :to_s :inspect
|
30
30
|
|
31
|
+
# @return [Tonal::Step] new step with the ratio mapped to the new modulo
|
32
|
+
# @example
|
33
|
+
# Tonal::Step.new(ratio: 3/2r, modulo: 31).convert(12)
|
34
|
+
# => 7\12
|
35
|
+
#
|
31
36
|
def convert(new_modulo)
|
32
37
|
self.class.new(log: log, modulo: new_modulo)
|
33
38
|
end
|
34
39
|
|
35
|
-
|
40
|
+
# @return [Rational] of the step
|
41
|
+
# @example
|
42
|
+
# Tonal::Step.new(ratio: 3/2r, modulo: 31).step_to_r
|
43
|
+
# => 6735213777669305/4503599627370496
|
44
|
+
#
|
45
|
+
def step_to_r
|
46
|
+
tempered.to_r
|
47
|
+
end
|
48
|
+
alias :to_r :step_to_r
|
49
|
+
|
50
|
+
# @return [Rational] of the ratio
|
51
|
+
# @example
|
52
|
+
# Tonal::Step.new(ratio: 3/2r, modulo: 31).ratio_to_r
|
53
|
+
# => 3/2
|
54
|
+
#
|
55
|
+
def ratio_to_r
|
36
56
|
ratio.to_r
|
37
57
|
end
|
38
58
|
|
39
|
-
|
59
|
+
# @return [Tonal::Cents] measure of step in cents
|
60
|
+
# @example
|
61
|
+
# Tonal::Step.new(ratio: 3/2r, modulo: 31).step_to_cents
|
62
|
+
# => 696.77
|
63
|
+
#
|
64
|
+
def step_to_cents
|
65
|
+
tempered.to_cents
|
66
|
+
end
|
67
|
+
alias :to_cents :step_to_cents
|
68
|
+
|
69
|
+
# @return [Tonal::Cents] measure of ratio in cents
|
70
|
+
# @example
|
71
|
+
# Tonal::Step.new(ratio: 3/2r, modulo: 31).ratio_to_cents
|
72
|
+
# => 701.96
|
73
|
+
#
|
74
|
+
def ratio_to_cents
|
40
75
|
ratio.to_cents
|
41
76
|
end
|
42
77
|
|
78
|
+
# @return [Tonal::Cents] the difference between the step and the ratio
|
79
|
+
# @example
|
80
|
+
# Tonal::Step.new(ratio: 3/2r, modulo: 31).efficiency
|
81
|
+
# => 5.19
|
82
|
+
#
|
83
|
+
def efficiency
|
84
|
+
ratio_to_cents - step_to_cents
|
85
|
+
end
|
86
|
+
|
43
87
|
def +(rhs)
|
44
88
|
self.class.new(step: (rhs % modulo), modulo: modulo)
|
45
89
|
end
|
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: 3.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-
|
11
|
+
date: 2024-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yaml
|
@@ -192,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
192
192
|
- !ruby/object:Gem::Version
|
193
193
|
version: '3.1'
|
194
194
|
requirements: []
|
195
|
-
rubygems_version: 3.5.
|
195
|
+
rubygems_version: 3.5.6
|
196
196
|
signing_key:
|
197
197
|
specification_version: 4
|
198
198
|
summary: Tonal tools
|