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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 340dc7220c5ab24c65486eefc2ebb457d76c7c1ac64fd91a428b94a4fd84cd7d
4
- data.tar.gz: 5721937407c18951a5b72eb075ffdbbfe8765abb3ae98695fc2af40e55277c3a
3
+ metadata.gz: ed09e5cd360980028547160d80bf374eacc14df7596e7cdfa0034bc295de771a
4
+ data.tar.gz: 3f17b4accf20c651fb3f7e172d9e4e5c094eb62a1a5705274ef36b16577f8f4f
5
5
  SHA512:
6
- metadata.gz: def0ab4830c3f5b3e82b919fcf8242899539a32e554acd2b260d3f37f87df6dbd7899cb8a6f9c045c98805bba69a10efc1f974d88e7f3107f641033c862acdc8
7
- data.tar.gz: 72601d465253ab599188b0f15a241b30e9824754c076bf260f69d4fa5b92309ac85dbb677a1e9e03bff0c29b42302a064b8d73a14ac92e0c0f5f7c9c8c84af8c
6
+ metadata.gz: 22aef50e39cbc83f269fa1a326da40e1d8068b1ff965ffbbaeda8c82919aadce2d1ef11b6988f4c78f87321ddfa010fd07def250b597015bacb3dbf09accd94d
7
+ data.tar.gz: 186a12f240251e6a6f1a2f0142cfe3f800151f182827fa06f7f6c999d0e652277a4cbc473a3e0ae6838ff6d1786a7f4c5ce80a9de35a2fb5572d246b3d43e884
@@ -1,4 +1,4 @@
1
1
  module Tonal
2
2
  TOOLS_PRODUCER = "mTonal"
3
- TOOLS_VERSION = "2.0.1"
3
+ TOOLS_VERSION = "3.0.1"
4
4
  end
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
  #
@@ -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.ratio.prime_divisions
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 [Array], self decomposed into its prime factors
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
- # (31/30r).max_prime => 31
175
+ # (7/4r).negative => (12/7)
196
176
  #
197
- def max_prime = self.ratio.max_prime
177
+ def negative = self.ratio.negative
198
178
 
199
- # @return [Integer] the minimum prime factor of self
179
+ # @return [Tonal::ReducedRatio], the ratio rotated on the given axis, default 1/1
200
180
  # @example
201
- # (31/30r).min_prime => 2
181
+ # (3/2r).mirror => (4/3)
202
182
  #
203
- def min_prime = self.ratio.min_prime
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
- if consequent
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
- to_log2.step(modulo)
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 [self] with antecedent and precedent switched
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
- tmp = antecedent
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 [Float] the cents difference between self and its step in the given modulo
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
- ((Tonal::Cents::CENT_SCALE * step(modulo).step / modulo.to_f) - to_cents).round(Tonal::Cents::PRECISION)
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
@@ -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
- def to_r
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
- def to_cents
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: 2.0.1
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-02-13 00:00:00.000000000 Z
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.5
195
+ rubygems_version: 3.5.6
196
196
  signing_key:
197
197
  specification_version: 4
198
198
  summary: Tonal tools