tonal-tools 2.0.1 → 3.0.1
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/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
|