tonal-tools 5.3.0 → 6.1.0

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: cf75078baac2ea863202aca76b6c00ab636971096fc676982dcb0114376bca8d
4
- data.tar.gz: 85b5550ccf29103f87416eea33f8a01c865730eecb4396e482e659ead1e5bf9e
3
+ metadata.gz: 398a62afac11715589c7fa92c09f0ac6017ca1edd45758bf6baf90eac7dc3d78
4
+ data.tar.gz: 16922965bddd3191a4cdefe3ae238d0cd654bd10648fc029362c5bf479a6a513
5
5
  SHA512:
6
- metadata.gz: aac11d2e96bda93047dea33f9e79be30f6db228b2fe4c01813544498740e21d82959a3678d0502ec9ee54e055fd96093d9135b244e37e9847de001ccb5a6a7ed
7
- data.tar.gz: 1d71ebff05b9d1e83b0dc90f4968c4ffbc9ebc51f0d931e0627588a2ad4262fcf1c63413a519450367b46eafa9f48b65cb2d38373a43fc23be49b4bbfbb5447d
6
+ metadata.gz: 56595c7e2479252bec13c9c2d41775da6077b2a98396a5916b88541d328cc2d20d72cef8628369dc1646a781b47442707d9828a7d601e83be4028ea66d1280b8
7
+ data.tar.gz: 25c2f3d1ace9a3337140abecfba8e12908274471824c491a099650b96923e820f545c64180850e62838ead9fdf36a8cac6b04bf9386377be9e502c9ddb10554e
@@ -35,7 +35,7 @@ class Tonal::Ratio
35
35
  Set.new(ratio: ratio) do |ratios|
36
36
  ContinuedFraction.new(antecedent.to_f/consequent, conv_limit).convergents.each do |convergent|
37
37
  ratio2 = ratio.class.new(convergent.numerator,convergent.denominator)
38
- ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
38
+ ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.max_prime_within?(max_prime)
39
39
  break if ratios.length >= depth
40
40
  end
41
41
  end
@@ -55,7 +55,7 @@ class Tonal::Ratio
55
55
  Set.new(ratio: ratio) do |ratios|
56
56
  FractionTree.node(to_f).path.each do |node|
57
57
  ratio2 = ratio.class.new(node.number)
58
- ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
58
+ ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.max_prime_within?(max_prime)
59
59
  break if ratios.length >= depth
60
60
  end
61
61
  end
@@ -77,7 +77,7 @@ class Tonal::Ratio
77
77
  n = 1
78
78
  while true do
79
79
  ratio2 = ratio.class.superparticular(n, factor: ratio.to_r, superpart:)
80
- ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime) && ratio2 != ratio
80
+ ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.max_prime_within?(max_prime) && ratio2 != ratio
81
81
  break if ratios.length >= depth
82
82
  n += 1
83
83
  end
@@ -105,7 +105,7 @@ class Tonal::Ratio
105
105
  while boundary <= max_boundary
106
106
  vacinity = ratio.respond_to?(:to_basic_ratio) ? to_basic_ratio.scale(scale) : ratio.scale(scale)
107
107
  self.class.neighbors(away: boundary, vacinity: vacinity).each do |neighbor|
108
- ratios << neighbor if ratio.class.within_cents?(self_in_cents, neighbor.to_cents, within) && neighbor.within_prime?(max_prime) && neighbor != ratio
108
+ ratios << neighbor if ratio.class.within_cents?(self_in_cents, neighbor.to_cents, within) && neighbor.max_prime_within?(max_prime) && neighbor != ratio
109
109
  end
110
110
  boundary += 1
111
111
  end
@@ -1,4 +1,4 @@
1
1
  module Tonal
2
2
  TOOLS_PRODUCER = "mTonal"
3
- TOOLS_VERSION = "5.3.0"
3
+ TOOLS_VERSION = "6.1.0"
4
4
  end
data/lib/tonal/cents.rb CHANGED
@@ -70,7 +70,7 @@ class Tonal::Cents
70
70
  # @return
71
71
  # [Tonal::Cents] nearest hundredth cent difference
72
72
  # @example
73
- # Tonal::Cents.new(701.9550008653874).nearest_hundredth_difference => 1.955000865387433
73
+ # Tonal::Cents.new(cents: 701.9550008653874).nearest_hundredth_difference => 1.96
74
74
  #
75
75
  def nearest_hundredth_difference
76
76
  self.class.new(cents: (value - nearest_hundredth))
@@ -108,7 +108,7 @@ class Tonal::Cents
108
108
  def derive_log(cents: nil, ratio: nil, log: nil)
109
109
  return Tonal::Log2.new(logarithm: cents / CENT_SCALE) if cents
110
110
  return Tonal::Log2.new(logarithmand: ratio) if ratio
111
- log.kind_of?(Tonal::Log2) ? log : Tonal::Log2.new(logarithm: log)
111
+ log.kind_of?(Tonal::Log) ? log : Tonal::Log2.new(logarithm: log)
112
112
  end
113
113
 
114
114
  def derive_ratio(log: nil, ratio: nil)
@@ -9,6 +9,9 @@ class Prime
9
9
  end
10
10
 
11
11
  class Numeric
12
+ alias :antecedent :numerator
13
+ alias :consequent :denominator
14
+
12
15
  # @return [Numeric] translated modularly
13
16
  # @example
14
17
  # Math::PI.modulo_translate(-3, 3) => -2.858407346410207
@@ -102,7 +105,7 @@ class Numeric
102
105
 
103
106
  # @return [Integer] the product complexity of self
104
107
  # @example
105
- # (3/2r).tenney_height => 2.584962500721156
108
+ # (3/2r).tenney_height => 2.58
106
109
  #
107
110
  def tenney_height = self.ratio.tenney_height
108
111
  alias :log_product_complexity :tenney_height
@@ -115,7 +118,7 @@ class Numeric
115
118
 
116
119
  # @return [Tonal::Log2] the log of Weil height
117
120
  # @example
118
- # (3/2r).log_weil_height => 1.5849625007211563
121
+ # (3/2r).log_weil_height => 1.58
119
122
  #
120
123
  def log_weil_height = self.ratio.log_weil_height
121
124
 
@@ -126,10 +129,11 @@ class Numeric
126
129
 
127
130
  # @return [Float] the cents difference between self and its step in the given modulo
128
131
  # @example
129
- # (3/2r).efficiency(12) => -1.955000865387433
132
+ # (3/2r).efficiency(12) => -1.96
130
133
  # @param modulo
131
134
  #
132
- def efficiency(modulo) = (Tonal::Cents::CENT_SCALE * step(modulo).step / modulo.to_f) - to_cents
135
+ # We want the efficiency from the ratio (self)
136
+ def efficiency(modulo) = to_ratio.efficiency(modulo)
133
137
 
134
138
  # @return [Tonal::Interval] beween self (upper) and ratio (lower)
135
139
  # @example
@@ -240,11 +244,11 @@ class Integer
240
244
  alias :totient :phi
241
245
 
242
246
  # @return [Array] of integers that are n-smooth with self
243
- # Adapted from https://rosettacode.org/wiki/N-smooth_numbers#Ruby
244
247
  # @example
245
248
  # 5.nsmooth(25)
246
249
  # => [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, 54]
247
250
  # @param limit
251
+ # @note Adapted from https://rosettacode.org/wiki/N-smooth_numbers#Ruby
248
252
  #
249
253
  def nsmooth(limit=2)
250
254
  ([0] * limit).tap do |ns|
@@ -267,6 +271,11 @@ class Integer
267
271
  end
268
272
 
269
273
  class Array
274
+ alias :numerator :first
275
+ alias :denominator :last
276
+ alias :antecedent :first
277
+ alias :consequent :last
278
+
270
279
  # @return [Array] self replaced by array padded to the right up to n, with value. value default is nil
271
280
  # @example
272
281
  # [3,2].rpad!(3, 12) => [3, 2, 12]
@@ -379,6 +388,12 @@ class Array
379
388
  (value - lower) % range + lower
380
389
  end
381
390
  end
391
+
392
+ # @return [Rational] from first and last element of array. Ideally to be used with tuples.
393
+ # @example
394
+ # [4,3].to_r => (4/3)
395
+ #
396
+ def to_r = Rational(numerator, denominator)
382
397
  end
383
398
 
384
399
  class Vector
@@ -8,9 +8,21 @@ class Tonal::Interval
8
8
 
9
9
  INTERVAL_OF_EQUIVALENCE = 2/1r
10
10
 
11
- def initialize(upper_ratio, lower_ratio)
12
- @lower_ratio = lower_ratio.ratio
13
- @upper_ratio = upper_ratio.ratio
11
+ # @return [Tonal::Interval] the interval of the given ratios
12
+ # @example
13
+ # Tonal::Interval.new(2,3) => (3/2) ((3/2) / (1/1))
14
+ # @param args two arguments representing ratios or four arguments representing two pairs of numerator/denominator
15
+ # @param reduced boolean determining whether to use Tonal::ReducedRatio or Tonal::Ratio
16
+ #
17
+ def initialize(*args, reduced: true)
18
+ klass = reduced ? Tonal::ReducedRatio : Tonal::Ratio
19
+ raise(ArgumentError, "Two or four arguments required. Either two ratios, or two pairs of numerator, denominator", caller[0]) unless [2, 4].include?(args.size)
20
+ @lower_ratio, @upper_ratio = case args.size
21
+ when 2
22
+ [klass.new(args[0].antecedent, args[0].consequent), klass.new(args[1].antecedent, args[1].consequent)]
23
+ when 4
24
+ [klass.new(args[0],args[1]), klass.new(args[2], args[3])]
25
+ end
14
26
  @interval = @upper_ratio / @lower_ratio
15
27
  end
16
28
  alias :ratio :interval
@@ -30,10 +42,16 @@ class Tonal::Interval
30
42
  end
31
43
 
32
44
  def inspect
33
- "#{self.to_r} (#{upper.to_r} / #{lower.to_r})"
45
+ "#{interval} (#{upper} / #{lower})"
34
46
  end
35
47
 
36
48
  def <=>(rhs)
37
49
  interval.to_r <=> rhs.interval.to_r
38
50
  end
39
51
  end
52
+
53
+ module Interval
54
+ def self.[](l, u, reduced=true)
55
+ Tonal::Interval.new(l, u, reduced:)
56
+ end
57
+ end
@@ -0,0 +1,45 @@
1
+ module Tonal
2
+ module IRBHelpers
3
+ # @return [Tonal::Ratio] an unreduced ratio
4
+ # @example
5
+ # r(3,3) => (3/3)
6
+ # @param arg1 the ratio if only argument provided, or the numerator if two argments are provided
7
+ # @param arg2 the denominator when two arguments are provided
8
+ #
9
+ def r(arg1, arg2=nil)
10
+ Tonal::Ratio.new(arg1, arg2)
11
+ end
12
+
13
+ # @return [Tonal::ReducedRatio] a reduced ratio
14
+ # @example
15
+ # r(3,3) => (1/1)
16
+ # @param arg1 the ratio if only argument provided, or the numerator if two argments are provided
17
+ # @param arg2 the denominator when two arguments are provided
18
+ #
19
+ def rr(arg1, arg2=nil)
20
+ Tonal::ReducedRatio.new(arg1, arg2)
21
+ end
22
+
23
+ # @return [Tonal::Interval] the interval between the given args
24
+ # @example
25
+ # i(2,3) => (3/2) ((3/2) / (1/1))
26
+ # @param args two arguments representing ratios or four arguments representing two pairs of numerator/denominator
27
+ # @param reduced boolean determining whether to use Tonal::ReducedRatio or Tonal::Ratio
28
+ #
29
+ def i(*args, reduced: true)
30
+ Tonal::Interval.new(*args, reduced:)
31
+ end
32
+ end
33
+
34
+ # @note
35
+ # Intended for activation from +~/.irbrc+, by placing: +ENV["MTONAL_IRB_HELPERS" ] = "1"+, in the file
36
+ #
37
+ # Invoking this command from the IRB will add the helper methods: +r+, +rr+, +i+ in +main+.
38
+ # These methods represent {Tonal::Ratio}, {Tonal::ReducedRatio} and {Tonal::Interval} respectively.
39
+ #
40
+ # @see Tonal::IRBHelpers
41
+ #
42
+ def self.include_irb_helpers
43
+ Object.include(IRBHelpers)
44
+ end
45
+ end
data/lib/tonal/log.rb CHANGED
@@ -52,7 +52,7 @@ class Tonal::Log
52
52
 
53
53
  # @return [Tonal::Cents] the cents scale logarithm
54
54
  # @example
55
- # Tonal::Log.new(logarithmand: 3/2r, base: 2).to_cents => 701.9550008653874
55
+ # Tonal::Log.new(logarithmand: 3/2r, base: 2).to_cents => 701.96
56
56
  # @see Tonal::Cents
57
57
  #
58
58
  def to_cents(precision: Tonal::Cents::PRECISION)
@@ -61,7 +61,7 @@ class Tonal::Log
61
61
 
62
62
  # @return [Tonal::Step] the nearest step in the given modulo
63
63
  # @example
64
- # Tonal::Log.new(3/2r, base: 2).step(12) => 7\12
64
+ # Tonal::Log.new(logarithmand: 3/2r, base: 2).step(12) => 7\12
65
65
  #
66
66
  def step(modulo)
67
67
  Tonal::Step.new(modulo: modulo, log: self)
@@ -69,10 +69,10 @@ class Tonal::Log
69
69
 
70
70
  # @return [String] the string representation of Tonal::Log
71
71
  # @example
72
- # Tonal::Log.new(3/2r, base: 2).inspect => "0.5849625007211562"
72
+ # Tonal::Log.new(logarithmand: 3/2r, base: 2).inspect => "0.58"
73
73
  #
74
74
  def inspect
75
- "#{logarithm}"
75
+ "#{logarithm.round(2)}"
76
76
  end
77
77
 
78
78
  def <=>(rhs)
data/lib/tonal/ratio.rb CHANGED
@@ -81,7 +81,7 @@ class Tonal::Ratio
81
81
 
82
82
  # @return [Boolean] if pair of ratios are within the given cents limit
83
83
  # @example
84
- # Tonal::Ratio.within_cents?(100, 105, 2) => true
84
+ # Tonal::Ratio.within_cents?(100, 105, 2) => false
85
85
  # @param cents1
86
86
  # @param cents2
87
87
  # @param within
@@ -141,7 +141,7 @@ class Tonal::Ratio
141
141
 
142
142
  # @return [Tonal::Log] Math.log of self in given base
143
143
  # @example
144
- # Tonal::Ratio.new(3,2).log(3) => 0.3690702464285425
144
+ # Tonal::Ratio.new(3,2).log(3) => 0.37
145
145
  # @param base
146
146
  #
147
147
  def to_log(base=2)
@@ -151,7 +151,7 @@ class Tonal::Ratio
151
151
 
152
152
  # @return [Tonal::Log2] Math.log2 of self
153
153
  # @example
154
- # Tonal::ReducedRatio.new(3,2).to_log2 => 0.5849625007211562
154
+ # Tonal::ReducedRatio.new(3,2).to_log2 => 0.58
155
155
  #
156
156
  def to_log2
157
157
  Tonal::Log2.new(logarithmand: to_r)
@@ -169,7 +169,7 @@ class Tonal::Ratio
169
169
 
170
170
  # @return [Integer] the step of self in the given modulo
171
171
  # @example
172
- # Tonal::ReducedRatio.new(3,2).step(12) => 7
172
+ # Tonal::ReducedRatio.new(3,2).step(12) => 7\12
173
173
  #
174
174
  def step(modulo=12)
175
175
  Tonal::Step.new(ratio: to_r, modulo: modulo)
@@ -254,7 +254,7 @@ class Tonal::Ratio
254
254
 
255
255
  # @return [Tonal::Ratio] the mirror of self along the axis (default 1/1)
256
256
  # @example
257
- # Tonal::Ratio.new(4,3).mirror => (3/2)
257
+ # Tonal::ReducedRatio.new(4,3).mirror => (3/2)
258
258
  # @param axis
259
259
  #
260
260
  def mirror(axis=1/1r)
@@ -299,7 +299,7 @@ class Tonal::Ratio
299
299
 
300
300
  # @return [Tonal::Ratio] self sheared by given arguments
301
301
  # @example
302
- # Tonal::Ratio.new(3,2).shear(1, 3) => (9/11)
302
+ # Tonal::Ratio.new(3,2).shear(1, 3) => (14/11)
303
303
  # @param a [Numeric]
304
304
  # @param b [Numeric]
305
305
  #
@@ -368,8 +368,13 @@ class Tonal::Ratio
368
368
  prime_divisions.flatten(1).map(&:first).min
369
369
  end
370
370
 
371
- def within_prime?(prime)
372
- max_prime <= prime
371
+ # @return [Boolean] whether self's max prime is within the given number
372
+ # @example
373
+ # Tonal::Ratio.new(31/30r).max_prime_within?(7) => false
374
+ # @param number to compare max prime against
375
+ #
376
+ def max_prime_within?(number)
377
+ max_prime <= number
373
378
  end
374
379
 
375
380
  # @return [Integer] the product complexity of self
@@ -383,7 +388,7 @@ class Tonal::Ratio
383
388
 
384
389
  # @return [Tonal::Log2] the log product complexity of self
385
390
  # @example
386
- # Tonal::ReducedRatio.new(3/2r).tenney_height => 2.584962500721156
391
+ # Tonal::ReducedRatio.new(3/2r).tenney_height => 2.58
387
392
  #
388
393
  def tenney_height
389
394
  Tonal::Log2.new(logarithmand: benedetti_height)
@@ -402,7 +407,7 @@ class Tonal::Ratio
402
407
 
403
408
  # @return [Tonal::Log2] the log of Weil height
404
409
  # @example
405
- # Tonal::ReducedRatio.new(3/2r).log_weil_height => 1.5849625007211563
410
+ # Tonal::ReducedRatio.new(3/2r).log_weil_height => 1.58
406
411
  #
407
412
  def log_weil_height
408
413
  Tonal::Log2.new(logarithmand: weil_height)
@@ -418,33 +423,33 @@ class Tonal::Ratio
418
423
 
419
424
  # @return [Tonal::Cents] the cents difference between self and its step in the given modulo
420
425
  # @example
421
- # Tonal::ReducedRatio.new(3,2).efficiency(12) => -1.955000865387433
422
- # @param modulo
426
+ # Tonal::ReducedRatio.new(3,2).efficiency(12) => -1.96
427
+ # @param modulo against which the difference of self is compared
423
428
  #
424
429
  def efficiency(modulo)
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.
430
+ # We want the efficiency from the ratio (self).
431
+ # If the step efficiency is X cents, then the ratio efficiency is -X cents.
427
432
  step(modulo).efficiency * -1.0
428
433
  end
429
434
 
430
435
  # @return [Array] the results of ratio dividing and multiplying self
431
436
  # @example
432
437
  # Tonal::ReducedRatio.new(3/2r).div_times(5/4r) => [(6/5), (15/8)]
433
- # @param ratio
438
+ # @param other_ratio to divide and multiple on self
434
439
  #
435
- def div_times(ratio)
436
- ratio = ratio.ratio
437
- [self / ratio, self * ratio]
440
+ def div_times(other_ratio)
441
+ other_ratio = self.class.new(other_ratio)
442
+ [self / other_ratio, self * other_ratio]
438
443
  end
439
444
 
440
445
  # @return [Array] the results of ratio subtracted and added to self
441
446
  # @example
442
447
  # Tonal::ReducedRatio.new(3/2r).plus_minus(5/4r) => [(1/1), (11/8)]
443
- # @param ratio
448
+ # @param other_ratio to add and subtract from self
444
449
  #
445
- def plus_minus(ratio)
446
- ratio = ratio.ratio
447
- [self - ratio, self + ratio]
450
+ def plus_minus(other_ratio)
451
+ other_ratio = self.class.new(other_ratio)
452
+ [self - other_ratio, self + other_ratio]
448
453
  end
449
454
  alias :min_plus :plus_minus
450
455
 
@@ -484,11 +489,11 @@ class Tonal::Ratio
484
489
  end
485
490
 
486
491
  def *(rhs)
487
- self.class.new(antecedent * rhs.antecedent, consequent * rhs.consequent)
492
+ operate(rhs, :*)
488
493
  end
489
494
 
490
495
  def /(rhs)
491
- self.class.new(antecedent * rhs.consequent, consequent * rhs.antecedent)
496
+ operate(rhs, :/)
492
497
  end
493
498
 
494
499
  def **(rhs)
@@ -519,6 +524,18 @@ class Tonal::Ratio
519
524
  [self.denominator, lhs.denominator].lcm
520
525
  end
521
526
 
527
+ # @return [Tonal::Interval] between ratio (upper) and self (lower)
528
+ # @example
529
+ # Tonal::ReducedRatio.new(133).interval_with(3/2r)
530
+ # => (192/133) ((3/2) / (133/128))
531
+ # @param antecedent
532
+ # @param consequent
533
+ #
534
+ def interval_with(antecedent, consequent=nil)
535
+ r = self.class.new(antecedent, consequent)
536
+ Tonal::Interval.new(self, r)
537
+ end
538
+
522
539
  # @return [Integer] the difference between antecedent and consequent
523
540
  # @example
524
541
  # Tonal::ReducedRatio.new(3,2).difference => 1
@@ -579,32 +596,32 @@ class Tonal::Ratio
579
596
  end
580
597
  end
581
598
 
599
+ def coerce(other)
600
+ [self.class.new(other), self]
601
+ end
602
+
582
603
  def operate(rhs, op)
604
+ klass = (rhs.class == Tonal::ReducedRatio || self.class == Tonal::ReducedRatio) ? Tonal::ReducedRatio : Tonal::Ratio
605
+
583
606
  case op
584
- when :+, :-
585
- case rhs
586
- when Tonal::Ratio
587
- self.class.new((antecedent * rhs.consequent).send(op, rhs.antecedent * consequent).abs, consequent * rhs.consequent)
588
- when Rational
589
- self.class.new((antecedent * rhs.denominator).send(op, rhs.numerator * consequent).abs, consequent * rhs.denominator)
590
- when Array
591
- self.class.new((antecedent * rhs[1]).send(op, rhs[0] * consequent), consequent * rhs[1])
592
- else
593
- r = Rational(rhs)
594
- self.class.new((antecedent * r.denominator).send(op, r.numerator * consequent), consequent * r.denominator)
595
- end
596
607
  when :*
597
- case rhs
598
- when Rational
599
- self.class.new(antecedent.send(op, rhs.numerator), consequent.send(op, rhs.denominator))
600
- when Array
601
- self.class.new(antecedent.send(op, rhs[0]), consequent.send(op, rhs[1]))
602
- else
603
- r = Rational(rhs)
604
- self.class.new(antecedent.send(op, r.numerator), consequent.send(op, r.denominator))
605
- end
608
+ klass.new(antecedent * rhs.antecedent, consequent * rhs.consequent)
609
+ when :/
610
+ klass.new(antecedent * rhs.consequent, consequent * rhs.antecedent)
611
+ when :+, :-
612
+ lcm = self.denominator.lcm(rhs.denominator)
613
+ left = (self.to_r * lcm).numerator
614
+ right = (rhs.to_r * lcm).numerator
615
+ klass.new((left).send(op, right).abs, lcm)
606
616
  when :**
607
- self.class.new(antecedent.send(op, rhs), consequent.send(op, rhs))
617
+ klass.new(Rational(antecedent, consequent) ** rhs.to_r)
608
618
  end
609
619
  end
610
620
  end
621
+
622
+ module Ratio
623
+ def self.[](u, l=nil)
624
+ Tonal::Ratio.new(u, l)
625
+ end
626
+ end
627
+
@@ -25,17 +25,6 @@ class Tonal::ReducedRatio < Tonal::Ratio
25
25
  Tonal::Ratio.new(antecedent, consequent)
26
26
  end
27
27
 
28
- # @return [Tonal::Interval] between ratio (upper) and self (lower)
29
- # @example
30
- # Tonal::ReducedRatio.new(133).interval_with(3/2r)
31
- # => 192/133 (3/2 / 133/128)
32
- # @param ratio
33
- #
34
- def interval_with(ratio)
35
- r = ratio.is_a?(self.class) ? ratio : self.class.new(ratio)
36
- Tonal::Interval.new(r, self)
37
- end
38
-
39
28
  # @return [Tonal::ReducedRatio] with antecedent and precedent switched
40
29
  # @example
41
30
  # Tonal::ReducedRatio.new(3,2).invert! => (4/3)
@@ -46,3 +35,9 @@ class Tonal::ReducedRatio < Tonal::Ratio
46
35
  self
47
36
  end
48
37
  end
38
+
39
+ module ReducedRatio
40
+ def self.[](u, l=nil)
41
+ Tonal::ReducedRatio.new(u, l)
42
+ end
43
+ end
data/lib/tonal/step.rb CHANGED
@@ -40,7 +40,7 @@ class Tonal::Step
40
40
  # @return [Rational] of the step
41
41
  # @example
42
42
  # Tonal::Step.new(ratio: 3/2r, modulo: 31).step_to_r
43
- # => 6735213777669305/4503599627370496
43
+ # => (6735213777669305/4503599627370496)
44
44
  #
45
45
  def step_to_r
46
46
  tempered.to_r
@@ -50,7 +50,7 @@ class Tonal::Step
50
50
  # @return [Rational] of the ratio
51
51
  # @example
52
52
  # Tonal::Step.new(ratio: 3/2r, modulo: 31).ratio_to_r
53
- # => 3/2
53
+ # => (3/2)
54
54
  #
55
55
  def ratio_to_r
56
56
  ratio.to_r
@@ -81,6 +81,7 @@ class Tonal::Step
81
81
  # => 5.19
82
82
  #
83
83
  def efficiency
84
+ # We want the efficiency from the step (self).
84
85
  ratio_to_cents - step_to_cents
85
86
  end
86
87
 
@@ -98,7 +99,7 @@ class Tonal::Step
98
99
  if ratio
99
100
  [Tonal::ReducedRatio.new(ratio), Tonal::Log2.new(logarithmand: ratio)]
100
101
  elsif log
101
- if log.kind_of?(Tonal::Log2)
102
+ if log.kind_of?(Tonal::Log)
102
103
  [log.logarithmand, log]
103
104
  else
104
105
  lg = Tonal::Log2.new(logarithm: log)
data/lib/tonal/tools.rb CHANGED
@@ -17,4 +17,10 @@ module Tonal
17
17
  require "tonal/interval"
18
18
  require "tonal/step"
19
19
  require "tonal/extensions"
20
+ require "tonal/irb_helpers"
21
+ end
22
+
23
+ if ENV["MTONAL_IRB_HELPERS"]
24
+ Tonal.include_irb_helpers
25
+ puts 'mTonal IRB helpers have been enabled.'
20
26
  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: 5.3.0
4
+ version: 6.1.0
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-09 00:00:00.000000000 Z
11
+ date: 2024-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yaml
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.2'
19
+ version: '0.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.2'
26
+ version: '0.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.6'
33
+ version: '2.9'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.6'
40
+ version: '2.9'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: prime
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '3.2'
117
+ version: '3'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '3.2'
124
+ version: '3'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: byebug
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -165,6 +165,7 @@ files:
165
165
  - lib/tonal/extensions.rb
166
166
  - lib/tonal/hertz.rb
167
167
  - lib/tonal/interval.rb
168
+ - lib/tonal/irb_helpers.rb
168
169
  - lib/tonal/log.rb
169
170
  - lib/tonal/log2.rb
170
171
  - lib/tonal/ratio.rb