tonal-tools 7.7.0 → 8.3.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.
data/lib/tonal/ratio.rb CHANGED
@@ -12,7 +12,7 @@ class Tonal::Ratio
12
12
 
13
13
  # @return [Tonal::Ratio]
14
14
  # @example
15
- # Tonal::Ratio.new(3,2) => (3/2)
15
+ # Tonal::Ratio.new(3,2) => 3/2
16
16
  # @param antecedent [Numeric, Tonal::Ratio]
17
17
  # @param consequent [Numeric, Tonal::Ratio]
18
18
  #
@@ -28,7 +28,7 @@ class Tonal::Ratio
28
28
 
29
29
  # @return [Tonal::Ratio] ratio who's numerator and denominator are seperated by a difference of 1
30
30
  # @example
31
- # Tonal::Ratio.superparticular(100) = (101/100)
31
+ # Tonal::Ratio.superparticular(100) = 101/100
32
32
  # @param n [Integer] number from which the superior part is calculated
33
33
  # @param factor [Rational] multiplied into the resulting ratio, default 1/1
34
34
  # @param superpart [Symbol] assigning the superior part to the antecedent or consequent
@@ -39,7 +39,7 @@ class Tonal::Ratio
39
39
 
40
40
  # @return [Tonal::Ratio] ratio who's numerator and denominator are separated by a summand difference
41
41
  # @example
42
- # Tonal::Ratio.superpartient(23, summand: 3) => (26/23)
42
+ # Tonal::Ratio.superpartient(23, summand: 3) => 26/23
43
43
  # @param n [Integer] number from which the superior part is calculated
44
44
  # @param summand [Integer] term added to the superior part
45
45
  # @param factor [Rational] multiplied into the resulting ratio, default 1/1
@@ -56,11 +56,12 @@ class Tonal::Ratio
56
56
 
57
57
  # @return [Tonal::Ratio] a randomly generated ratio
58
58
  # @example
59
- # Tonal::Ratio.random_ratio => (169/1)
60
- # @param number_of_factors
61
- # @param within
59
+ # Tonal::Ratio.random_ratio => 169/1
60
+ # @param number_of_factors the number of prime factors to include in the ratio
61
+ # @param within the upper limit for prime factors
62
+ # @param reduced boolean determining whether to use Tonal::ReducedRatio or Tonal::Ratio
62
63
  #
63
- def self.random_ratio(number_of_factors = 2, within: 100, reduced: false)
64
+ def self.random_ratio(number_of_factors = 2, within: 100, reduced: (self == Tonal::ReducedRatio) ? true : false)
64
65
  primes = Prime.each(within).to_a
65
66
  nums = []
66
67
  dens = []
@@ -73,13 +74,12 @@ class Tonal::Ratio
73
74
 
74
75
  # @return [Tonal::Ratio] the ratio of step in the modulo
75
76
  # @example
76
- # Tonal::Ratio.ed(12, 7)
77
- # => (4771397596969315/4503599627370496)
78
- # @param modulo
79
- # @param step
80
- # @param equave
77
+ # Tonal::Ratio.ed(12, 7) => 1.5
78
+ # @param modulo the number of steps in the equal division
79
+ # @param step the step number in the equal division of the equave
80
+ # @param equave the interval of equivalence, default 2/1
81
81
  #
82
- def self.ed(modulo, step, equave: 2/1r)
82
+ def self.ed(step, modulo, equave: 2/1r)
83
83
  self.new(2**(step.to_f/modulo), equave: equave)
84
84
  end
85
85
 
@@ -108,7 +108,7 @@ class Tonal::Ratio
108
108
  end
109
109
 
110
110
  # ==================================
111
- # Conversions
111
+ # Conversions, mappings and measurements
112
112
  # ==================================
113
113
 
114
114
  # @return [Array] antecedent and consequent as elements of Array
@@ -143,6 +143,7 @@ class Tonal::Ratio
143
143
  def to_f
144
144
  antecedent.to_f / consequent.to_f
145
145
  end
146
+ alias :number :to_f
146
147
 
147
148
  # @return [Tonal::Log] Math.log of self in given base
148
149
  # @example
@@ -177,7 +178,7 @@ class Tonal::Ratio
177
178
  # Tonal::ReducedRatio.new(3,2).step(12) => 7\12
178
179
  #
179
180
  def step(modulo=12)
180
- Tonal::Step.new(ratio: to_r, modulo: modulo)
181
+ Tonal::Scale::Step.new(ratio: to_r, modulo: modulo)
181
182
  end
182
183
 
183
184
  # @return [Float] degrees
@@ -200,7 +201,7 @@ class Tonal::Ratio
200
201
 
201
202
  # @return [Tonal::Ratio] copy of self rationally reduced
202
203
  # @example
203
- # Tonal::Ratio.new(16,14).fraction_reduce => (8/7)
204
+ # Tonal::Ratio.new(16,14).fraction_reduce => 8/7
204
205
  # @see to_r
205
206
  #
206
207
  def fraction_reduce
@@ -209,7 +210,7 @@ class Tonal::Ratio
209
210
 
210
211
  # @return [Tonal::Ratio] copy of self reduced to the given equave
211
212
  # @example
212
- # Tonal::Ratio.new(48,14).equave_reduce(3) => (8/7)
213
+ # Tonal::Ratio.new(48,14).equave_reduce(3) => 8/7
213
214
  # @param equave Numeric
214
215
  #
215
216
  def equave_reduce(equave=2/1r)
@@ -220,7 +221,7 @@ class Tonal::Ratio
220
221
 
221
222
  # @return [Tonal::Ratio] self reduced to the given equave
222
223
  # @example
223
- # Tonal::Ratio.new(48,14).equave_reduce!(3) => (8/7)
224
+ # Tonal::Ratio.new(48,14).equave_reduce!(3) => 8/7
224
225
  # @param equave Numeric
225
226
  #
226
227
  def equave_reduce!(equave=2/1r)
@@ -232,7 +233,7 @@ class Tonal::Ratio
232
233
 
233
234
  # @return [Tonal::ReducedRatio] of self
234
235
  # @example
235
- # Tonal::Ratio.new(1,9).to_reduced_ratio => (16/9)
236
+ # Tonal::Ratio.new(1,9).to_reduced_ratio => 16/9
236
237
  #
237
238
  def to_reduced_ratio
238
239
  Tonal::ReducedRatio.new(reduced_antecedent, reduced_consequent, equave: equave)
@@ -241,7 +242,7 @@ class Tonal::Ratio
241
242
 
242
243
  # @return [Tonal::Ratio] copy of self with the antecedent and precedent switched
243
244
  # @example
244
- # Tonal::Ratio.new(3,2).invert => (2/3)
245
+ # Tonal::Ratio.new(3,2).invert => 2/3
245
246
  #
246
247
  def invert
247
248
  self.class.new(consequent, antecedent)
@@ -251,7 +252,7 @@ class Tonal::Ratio
251
252
 
252
253
  # @return [Tonal::Ratio] with antecedent and precedent switched
253
254
  # @example
254
- # Tonal::Ratio.new(3,2).invert! => (2/3)
255
+ # Tonal::Ratio.new(3,2).invert! => 2/3
255
256
  #
256
257
  def invert!
257
258
  _initialize(consequent, antecedent, label: label, equave: equave)
@@ -260,7 +261,7 @@ class Tonal::Ratio
260
261
 
261
262
  # @return [Tonal::Ratio] the mirror of self along the axis (default 1/1)
262
263
  # @example
263
- # Tonal::ReducedRatio.new(4,3).mirror => (3/2)
264
+ # Tonal::ReducedRatio.new(4,3).mirror => 3/2
264
265
  # @param axis
265
266
  #
266
267
  def mirror(axis=1/1r)
@@ -269,7 +270,7 @@ class Tonal::Ratio
269
270
 
270
271
  # @return [Tonal::ReducedRatio] the Ernst Levy negative of self
271
272
  # @example
272
- # Tonal::ReducedRatio.new(7/4r).negative => (12/7)
273
+ # Tonal::ReducedRatio.new(7/4r).negative => 12/7
273
274
  #
274
275
  def negative
275
276
  self.class.new(3/2r) / self
@@ -281,10 +282,9 @@ class Tonal::Ratio
281
282
  # denominator mapped on y-axis
282
283
  # ==================================
283
284
  #
284
-
285
285
  # @return [Tonal::Ratio] with the antecedent and consequent translated by x and y
286
286
  # @example
287
- # Tonal::Ratio.new(3,2).translate(3,3) => (6/5)
287
+ # Tonal::Ratio.new(3,2).translate(3,3) => 6/5
288
288
  # @param x [Numeric]
289
289
  # @param y [Numeric]
290
290
  #
@@ -295,7 +295,7 @@ class Tonal::Ratio
295
295
 
296
296
  # @return [Tonal::Ratio] self scaled by given arguments
297
297
  # @example
298
- # Tonal::Ratio.new(3,2).scale(2**5) => (96/64)
298
+ # Tonal::Ratio.new(3,2).scale(2**5) => 96/64
299
299
  # @param a [Numeric]
300
300
  # @param b [Numeric]
301
301
  #
@@ -306,7 +306,7 @@ class Tonal::Ratio
306
306
 
307
307
  # @return [Tonal::Ratio] self sheared by given arguments
308
308
  # @example
309
- # Tonal::Ratio.new(3,2).shear(1, 3) => (14/11)
309
+ # Tonal::Ratio.new(3,2).shear(1, 3) => 14/11
310
310
  # @param a [Numeric]
311
311
  # @param b [Numeric]
312
312
  #
@@ -377,15 +377,10 @@ class Tonal::Ratio
377
377
  prime_divisions.flatten(1).map(&:first).min
378
378
  end
379
379
 
380
- # @return [Boolean] whether self's max prime is within the given number
381
- # @example
382
- # Tonal::Ratio.new(31/30r).max_prime_within?(7) => false
383
- # @param number to compare max prime against
380
+ # =================================
381
+ # Measures of complexity
382
+ # ==================================
384
383
  #
385
- def max_prime_within?(number)
386
- max_prime.nil? ? false : max_prime <= number
387
- end
388
-
389
384
  # @return [Integer] the product complexity of self
390
385
  # @example
391
386
  # Tonal::ReducedRatio.new(3/2r).benedetti_height => 6
@@ -471,6 +466,86 @@ class Tonal::Ratio
471
466
  cents - other_ratio.ratio.cents
472
467
  end
473
468
 
469
+ # @return [Integer] the least common multiple with self's denominator and the given number's denominator
470
+ # @example
471
+ # Tonal::Ratio.new(3/2r).lcm(5/4r) => 4
472
+ # @param lhs [Numeric, Tonal::Ratio] the number with which the lcm with self is computed
473
+ #
474
+ def lcm(lhs)
475
+ [self.denominator, lhs.denominator].lcm
476
+ end
477
+
478
+ # @return [Tonal::Interval] between self and another ratio
479
+ # @example
480
+ # Tonal::ReducedRatio.new(3,2).interval_with(4/3r)
481
+ # => 9/8 (3/2 / 4/3)
482
+ # @example
483
+ # Tonal::ReducedRatio.new(3,2).interval_with(4/3r, is_lower: false)
484
+ # => 16/9 (4/3 / 3/2)
485
+ # @param other_ratio [Tonal::ReducedRatio, Numeric] the ratio to form the interval with
486
+ # @param is_lower [Boolean] whether other_ratio is the lower ratio of the interval
487
+ #
488
+ def interval_with(other_ratio, is_lower: true)
489
+ other_ratio = self.class.new(other_ratio)
490
+ args = is_lower ? [self, other_ratio] : [other_ratio, self]
491
+ Tonal::Interval.new(*args)
492
+ end
493
+
494
+ # @return [Tonal::Interval] between 1/1 and self
495
+ # @example
496
+ # Tonal::ReducedRatio.new(3,2).to_interval
497
+ # => (3/2) ((3/2) / (1/1))
498
+ #
499
+ def to_interval
500
+ interval_with(1/1r)
501
+ end
502
+
503
+ # @return [Tonal::Cents] difference between ratio (upper) and self (lower)
504
+ # @example
505
+ # Tonal::ReducedRatio.new(3,2).cents_difference_with(4/3r) => 203.91
506
+ # @example
507
+ # Tonal::ReducedRatio.new(3,2).cents_difference_with(4/3r, is_lower: false) => 996.09
508
+ # @param other_ratio [Tonal::ReducedRatio, Numeric] the ratio to compare cents difference with
509
+ #
510
+ def cents_difference_with(other_ratio, is_lower: true)
511
+ interval_with(other_ratio, is_lower:).to_cents
512
+ end
513
+
514
+ # @return [Integer] the difference between antecedent and consequent
515
+ # @example
516
+ # Tonal::ReducedRatio.new(3,2).difference => 1
517
+ #
518
+ def difference
519
+ antecedent - consequent
520
+ end
521
+ alias :diff :difference
522
+
523
+ # @return [Integer] the sum of antecedent and consequent
524
+ # @example
525
+ # Tonal::ReducedRatio.new(3,2).combination => 5
526
+ #
527
+ def combination
528
+ antecedent + consequent
529
+ end
530
+ alias :comb :combination
531
+
532
+ # @return [Tonal::Ratio] self raised to the given power and root
533
+ # @example
534
+ # Tonal::ReducedRatio.new(3,2).power(2) => 9/8
535
+ # @param power [Numeric]
536
+ # @param root [Numeric, nil]
537
+ # @param approximant [Integer] the index of the approximant to use
538
+ # @param by_method [Symbol] the method used to calculate approximation of the root intervalic ratio
539
+ # @param from [Symbol] whether to calculate the root interval from the lower or upper ratio of the interval
540
+ #
541
+ def power(power, root=nil, approximant: 0, by_method: :continued_fraction, from: :lower_ratio)
542
+ to_interval.root_interval(power:, root:, approximant:, by_method:, from:).intervalic_ratio
543
+ end
544
+
545
+ # ==================================
546
+ # Display
547
+ # ==================================
548
+
474
549
  # @return [String] symbolic representation of Tonal::Ratio
475
550
  #
476
551
  def label
@@ -480,7 +555,7 @@ class Tonal::Ratio
480
555
 
481
556
  # @return [String] the string representation of Tonal::Ratio
482
557
  # @example
483
- # Tonal::Ratio.new(3, 2).inspect => "(3/2)"
558
+ # Tonal::Ratio.new(3, 2).inspect => "3/2"
484
559
  #
485
560
  def inspect
486
561
  # Return the "antecedent/consequent", if antecedent is less than 7 digits long; or
@@ -489,22 +564,51 @@ class Tonal::Ratio
489
564
  end
490
565
  alias :to_s :inspect
491
566
 
567
+ # ==================================
568
+ # Arithmetic operations
569
+ # ==================================
570
+
571
+ # @return [Tonal::Ratio] result of adding self and rhs
572
+ # @example
573
+ # Tonal::Ratio.new(3,2) + Tonal::Ratio.new(4,3) => (17/12)
574
+ # @param rhs [Numeric, Tonal::Ratio]
575
+ #
492
576
  def +(rhs)
493
577
  operate(rhs, :+)
494
578
  end
495
579
 
580
+ # @return [Tonal::Ratio] result of subtracting rhs from self
581
+ # @example
582
+ # Tonal::Ratio.new(3,2) - Tonal::Ratio.new(4,3) => (1/6)
583
+ # @param rhs [Numeric, Tonal::Ratio]
584
+ #
496
585
  def -(rhs)
497
586
  operate(rhs, :-)
498
587
  end
499
588
 
589
+ # @return [Tonal::Ratio] result of multiplying self and rhs
590
+ # @example
591
+ # Tonal::Ratio.new(3,2) * Tonal::Ratio.new(4,3) => (2/1)
592
+ # @param rhs [Numeric, Tonal::Ratio]
593
+ #
500
594
  def *(rhs)
501
595
  operate(rhs, :*)
502
596
  end
503
597
 
598
+ # @return [Tonal::Ratio] result of dividing self by rhs
599
+ # @example
600
+ # Tonal::Ratio.new(3,2) / Tonal::Ratio.new(4,3) => (9/8)
601
+ # @param rhs [Numeric, Tonal::Ratio]
602
+ #
504
603
  def /(rhs)
505
604
  operate(rhs, :/)
506
605
  end
507
606
 
607
+ # @return [Tonal::Ratio] result of raising self to the rhs power
608
+ # @example
609
+ # Tonal::Ratio.new(3,2) ** 2 => (9/4)
610
+ # @param rhs [Numeric, Tonal::Ratio]
611
+ #
508
612
  def **(rhs)
509
613
  operate(rhs, :**)
510
614
  end
@@ -520,64 +624,27 @@ class Tonal::Ratio
520
624
  alias :mediant :mediant_sum
521
625
  alias :farey_sum :mediant_sum
522
626
 
523
- # ==================================
524
- # Measurements
525
- # ==================================
526
-
527
- # @return [Integer] the least common multiple with self's denominator and the given number's denominator
528
- # @example
529
- # Tonal::Ratio.new(3/2r).lcm(5/4r) => 4
530
- # @param lhs [Numeric, Tonal::Ratio] the number with which the lcm with self is computed
531
- #
532
- def lcm(lhs)
533
- [self.denominator, lhs.denominator].lcm
534
- end
535
-
536
- # @return [Tonal::Interval] between ratio (upper) and self (lower)
537
- # @example
538
- # Tonal::ReducedRatio.new(133).interval_with(3/2r)
539
- # => (192/133) ((3/2) / (133/128))
540
- # @param upper ratio
541
- # @param lower ratio
542
- #
543
- def interval_with(upper, lower=nil)
544
- r = self.class.new(upper, lower)
545
- Tonal::Interval.new(self, r)
546
- end
547
-
548
- # @return [Tonal::Cents] difference between ratio (upper) and self (lower)
549
- # @example
550
- # Tonal::ReducedRatio.new(133).cents_difference_with(3/2r)
551
- # => 635.62
552
- # @param upper ratio
553
- # @param lower ratio
554
- #
555
- def cents_difference_with(upper, lower=nil)
556
- interval_with(upper, lower).to_cents
557
- end
558
-
559
- # @return [Integer] the difference between antecedent and consequent
627
+ # @return [Integer] comparison of self to rhs
560
628
  # @example
561
- # Tonal::ReducedRatio.new(3,2).difference => 1
629
+ # Tonal::Ratio.new(3,2) <=> Tonal::Ratio.new(4,3) => 1
630
+ # @param rhs [Tonal::Ratio]
562
631
  #
563
- def difference
564
- antecedent - consequent
632
+ def <=>(rhs)
633
+ left = consequent == 0 ? Float::INFINITY : Rational(antecedent, consequent)
634
+ right = rhs.denominator == 0 ? Float::INFINITY : Rational(rhs.numerator, rhs.denominator)
635
+ left <=> right
565
636
  end
566
- alias :diff :difference
567
637
 
568
- # @return [Integer] the sum of antecedent and consequent
569
- # @example
570
- # Tonal::ReducedRatio.new(3,2).combination => 5
638
+ # Set uses Hash as storage and equality of elements is determined according to Object#eql? and Object#hash.
571
639
  #
572
- def combination
573
- antecedent + consequent
640
+ def eql?(other)
641
+ other.instance_of?(self.class) && to_r == other.to_r
574
642
  end
575
- alias :comb :combination
576
643
 
577
- def <=>(rhs)
578
- left = consequent == 0 ? Float::INFINITY : Rational(antecedent, consequent)
579
- right = rhs.denominator == 0 ? Float::INFINITY : Rational(rhs.numerator, rhs.denominator)
580
- left <=> right
644
+ def hash
645
+ p, q = 17, 37
646
+ p = q * @id.hash
647
+ p = q * @name.hash
581
648
  end
582
649
 
583
650
  private
@@ -638,9 +705,3 @@ class Tonal::Ratio
638
705
  end
639
706
  end
640
707
  end
641
-
642
- module Ratio
643
- def self.[](u, l=nil)
644
- Tonal::Ratio.new(u, l)
645
- end
646
- end
@@ -3,7 +3,7 @@ class Tonal::ReducedRatio < Tonal::Ratio
3
3
 
4
4
  # @return [Tonal::ReducedRatio]
5
5
  # @example
6
- # Tonal::ReducedRatio.new(12,2) => (3/2)
6
+ # Tonal::ReducedRatio.new(12,2) => 3/2
7
7
  # @param antecedent [Numeric, Tonal::Ratio]
8
8
  # @param consequent [Numeric, Tonal::Ratio]
9
9
  # @param equave the interval of equivalence, default 2/1
@@ -35,9 +35,3 @@ class Tonal::ReducedRatio < Tonal::Ratio
35
35
  self
36
36
  end
37
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
@@ -1,112 +1,114 @@
1
- class Tonal::Step
2
- extend Forwardable
3
- include Comparable
1
+ class Tonal::Scale
2
+ class Step
3
+ extend Forwardable
4
+ include Comparable
4
5
 
5
- def_delegators :@log, :logarithmand
6
+ def_delegators :@log, :logarithmand
6
7
 
7
- attr_reader :modulo, :log, :step, :ratio, :tempered
8
+ attr_reader :modulo, :log, :step, :ratio, :tempered
8
9
 
9
- def initialize(modulo: nil, log: nil, step: nil, ratio: nil)
10
- raise ArgumentError, "modulo: required" unless modulo
11
- raise ArgumentError, "One of log:, step: or ratio: must be provided" unless [log, step, ratio].compact.count == 1
12
- @modulo = modulo.round
10
+ def initialize(modulo: nil, log: nil, step: nil, ratio: nil)
11
+ raise ArgumentError, "modulo: required" unless modulo
12
+ raise ArgumentError, "One of log:, step: or ratio: must be provided" unless [log, step, ratio].compact.count == 1
13
+ @modulo = modulo.round
13
14
 
14
- if ratio
15
- @ratio, @log = derive_ratio_and_log(ratio: ratio)
16
- elsif step
17
- @ratio, @log = derive_ratio_and_log(step: step)
18
- elsif log
19
- @ratio, @log = derive_ratio_and_log(log: log)
20
- end
15
+ if ratio
16
+ @ratio, @log = derive_ratio_and_log(ratio: ratio)
17
+ elsif step
18
+ @ratio, @log = derive_ratio_and_log(step: step)
19
+ elsif log
20
+ @ratio, @log = derive_ratio_and_log(log: log)
21
+ end
21
22
 
22
- @step = (modulo * @log).round
23
- @tempered = 2**(@step.to_f/@modulo)
24
- end
23
+ @step = (modulo * @log).round
24
+ @tempered = 2**(@step.to_f/@modulo)
25
+ end
25
26
 
26
- def inspect
27
- "#{step}\\#{modulo}"
28
- end
29
- alias :to_s :inspect
27
+ def inspect
28
+ "#{step}\\#{modulo}"
29
+ end
30
+ alias :to_s :inspect
30
31
 
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
- #
36
- def convert(new_modulo)
37
- self.class.new(log: log, modulo: new_modulo)
38
- end
32
+ # @return [Tonal::Scale::Step] new step with the ratio mapped to the new modulo
33
+ # @example
34
+ # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).convert(12)
35
+ # => 7\12
36
+ #
37
+ def convert(new_modulo)
38
+ self.class.new(log: log, modulo: new_modulo)
39
+ end
39
40
 
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
41
+ # @return [Rational] of the step
42
+ # @example
43
+ # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).step_to_r
44
+ # => (6735213777669305/4503599627370496)
45
+ #
46
+ def step_to_r
47
+ tempered.to_r
48
+ end
49
+ alias :to_r :step_to_r
49
50
 
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
56
- ratio.to_r
57
- end
51
+ # @return [Rational] of the ratio
52
+ # @example
53
+ # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).ratio_to_r
54
+ # => (3/2)
55
+ #
56
+ def ratio_to_r
57
+ ratio.to_r
58
+ end
58
59
 
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
60
+ # @return [Tonal::Cents] measure of step in cents
61
+ # @example
62
+ # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).step_to_cents
63
+ # => 696.77
64
+ #
65
+ def step_to_cents
66
+ tempered.to_cents
67
+ end
68
+ alias :to_cents :step_to_cents
68
69
 
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
75
- ratio.to_cents
76
- end
70
+ # @return [Tonal::Cents] measure of ratio in cents
71
+ # @example
72
+ # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).ratio_to_cents
73
+ # => 701.96
74
+ #
75
+ def ratio_to_cents
76
+ ratio.to_cents
77
+ end
77
78
 
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
- # We want the efficiency from the step (self).
85
- ratio_to_cents - step_to_cents
86
- end
79
+ # @return [Tonal::Cents] the difference between the step and the ratio
80
+ # @example
81
+ # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).efficiency
82
+ # => 5.19
83
+ #
84
+ def efficiency
85
+ # We want the efficiency from the step (self).
86
+ ratio_to_cents - step_to_cents
87
+ end
87
88
 
88
- def +(rhs)
89
- self.class.new(step: (rhs % modulo), modulo: modulo)
90
- end
91
- alias :% :+
89
+ def +(rhs)
90
+ self.class.new(step: (rhs % modulo), modulo: modulo)
91
+ end
92
+ alias :% :+
92
93
 
93
- def <=>(rhs)
94
- rhs.kind_of?(self.class) && modulo <=> rhs.modulo && log <=> rhs.log && step <=> rhs.step
95
- end
94
+ def <=>(rhs)
95
+ rhs.kind_of?(self.class) && modulo <=> rhs.modulo && log <=> rhs.log && step <=> rhs.step
96
+ end
96
97
 
97
- private
98
- def derive_ratio_and_log(ratio: nil, log: nil, step: nil)
99
- if ratio
100
- [Tonal::ReducedRatio.new(ratio), Tonal::Log2.new(logarithmand: ratio)]
101
- elsif log
102
- if log.kind_of?(Tonal::Log)
103
- [log.logarithmand, log]
104
- else
105
- lg = Tonal::Log2.new(logarithm: log)
106
- [Tonal::ReducedRatio.new(lg.logarithmand), lg]
98
+ private
99
+ def derive_ratio_and_log(ratio: nil, log: nil, step: nil)
100
+ if ratio
101
+ [Tonal::ReducedRatio.new(ratio), Tonal::Log2.new(logarithmand: ratio)]
102
+ elsif log
103
+ if log.kind_of?(Tonal::Log)
104
+ [log.logarithmand, log]
105
+ else
106
+ lg = Tonal::Log2.new(logarithm: log)
107
+ [Tonal::ReducedRatio.new(lg.logarithmand), lg]
108
+ end
109
+ elsif step
110
+ [Tonal::ReducedRatio.new(2.0**(step.to_f/@modulo)), Tonal::Log2.new(logarithmand: (2.0 ** (step.to_f/@modulo)))]
107
111
  end
108
- elsif step
109
- [Tonal::ReducedRatio.new(2.0**(step.to_f/@modulo)), Tonal::Log2.new(logarithmand: (2.0 ** (step.to_f/@modulo)))]
110
112
  end
111
113
  end
112
114
  end