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 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