tonal-tools 8.5.3 → 8.6.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: d35ccfb34bc36393de62b66954048131b48eff9a9aa0c3af8c9f5d97d79d8406
4
- data.tar.gz: 16b2e4235caeaf796ddd7ceec8e6b881eb2291b4ec0f7f6389ac2faaca1fe243
3
+ metadata.gz: 25126d841103214bbe0a1fe1dcd861460ff4bf7b108ac3e0854032e037f64ab1
4
+ data.tar.gz: 3f3941c9a097f937d08f5c0b9fc1edec5df331b45d12599b0dcedfaa275ed6b4
5
5
  SHA512:
6
- metadata.gz: 6849510f855a326970cf7a7ad4ee619b05251b15331659192c4a7d1cf17a08eb64cdd55e70232300587f6f263cb906ddde329fba2d7923002b34f303f1ee4bd1
7
- data.tar.gz: ab77a51fb2c82acf98fb1b65b1d33ace5baac0fbfc4c823140fb1a746995468f8cf3621824af17b07f0f099300dd7b4b244da4578711705e8a62f9d22c1976cd
6
+ metadata.gz: 4c8828863ca77987db6837fbbff67a8f74029d8b817418596a3a0ce6959fbd09ffb174a7dc4142a1d67ed8fadc5d85e3694ee87155c1ea064b6760cf73d3baae
7
+ data.tar.gz: 54122f26528a2fa0866abc7e9c2e23ffee7dbb64a8d9ed192c48c205b233b365b9064847d667a7e95cfd90b23f0424bc9799ff098426e27b4be727d45cc6c489
@@ -1,4 +1,4 @@
1
1
  module Tonal
2
2
  TOOLS_PRODUCER = "mTonal"
3
- TOOLS_VERSION = "8.5.3"
3
+ TOOLS_VERSION = "8.6.0"
4
4
  end
data/lib/tonal/hertz.rb CHANGED
@@ -10,7 +10,7 @@ class Tonal::Hertz
10
10
  #
11
11
  def initialize(arg)
12
12
  raise ArgumentError, "Argument is not Numeric or Tonal::Hertz" unless arg.kind_of?(Numeric) || arg.kind_of?(self.class)
13
- @value = arg.kind_of?(self.class) ? arg.inspect : arg
13
+ @value = arg.kind_of?(self.class) ? arg.value : arg
14
14
  end
15
15
 
16
16
  # @return [Tonal::Hertz] 440 Hz
@@ -46,6 +46,16 @@ class Tonal::Hertz
46
46
  Tonal::Cents.new(ratio: to_r / reference.to_r)
47
47
  end
48
48
 
49
+ # @return [Tonal::Midi::Note] the midi representation of self
50
+ # @example
51
+ # Tonal::Hertz.new(440).to_midi => 69.0 MIDI
52
+ # @param reference [Tonal::Hertz, Numeric] the reference frequency to compare to
53
+ #
54
+ def to_midi_note
55
+ Tonal::Midi::Note.new(frequency: to_f)
56
+ end
57
+ alias :to_midi :to_midi_note
58
+
49
59
  # @return [String] the string representation of Tonal::Hertz
50
60
  # @example
51
61
  # Tonal::Hertz(1000.0).inspect => "1000.0 Hz"
data/lib/tonal/midi.rb ADDED
@@ -0,0 +1,38 @@
1
+ module Tonal::Midi
2
+ class Note
3
+ include Comparable
4
+
5
+ REFERENCE_FREQUENCY = 440.0
6
+ A4_MIDI_NUMBER = 69
7
+
8
+ attr_reader :number, :frequency
9
+
10
+ # @return [Tonal::Midi::Note]
11
+ # @example
12
+ # Tonal::Midi::Note.new(number:60) => 60.0 MIDI
13
+ # @param arg [Numeric, Tonal::Midi::Note]
14
+ #
15
+ def initialize(number: A4_MIDI_NUMBER, frequency: nil)
16
+ if frequency
17
+ raise ArgumentError, "Frequency argument is not Numeric or Tonal::Hertz" unless frequency.kind_of?(Numeric) || frequency.kind_of?(Tonal::Hertz)
18
+ @frequency = Tonal::Hertz.new(frequency)
19
+ @number = (A4_MIDI_NUMBER + 12 * Math.log2(frequency.to_f / REFERENCE_FREQUENCY)).round
20
+ else
21
+ raise ArgumentError, "Number argument is not Integer" unless number.kind_of?(Integer)
22
+ @number = number.kind_of?(self.class) ? number.inspect : number
23
+ @frequency = Tonal::Hertz.new(REFERENCE_FREQUENCY * (2 ** ((number - A4_MIDI_NUMBER) / 12.0)))
24
+ end
25
+ end
26
+
27
+ alias :value :number
28
+
29
+ # @return [String] representation of self
30
+ def inspect
31
+ "#{number} MIDI"
32
+ end
33
+
34
+ def <=>(other)
35
+ number <=> other.number
36
+ end
37
+ end
38
+ end
data/lib/tonal/step.rb CHANGED
@@ -29,7 +29,7 @@ class Tonal::Scale
29
29
  end
30
30
  alias :to_s :inspect
31
31
 
32
- # @return [Tonal::Scale::Step] new step with the ratio mapped to the new modulo
32
+ # @return a new [Tonal::Scale::Step] with the ratio mapped to the new modulo
33
33
  # @example
34
34
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).convert(12)
35
35
  # => 7\12
@@ -38,7 +38,7 @@ class Tonal::Scale
38
38
  self.class.new(log: log, modulo: new_modulo)
39
39
  end
40
40
 
41
- # @return [Rational] of the step
41
+ # @return the [Rational] representation of the step/modulo of self
42
42
  # @example
43
43
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).step_to_r
44
44
  # => (18/31)
@@ -49,7 +49,7 @@ class Tonal::Scale
49
49
  Rational(step, modulo)
50
50
  end
51
51
 
52
- # @return [Tonal::Ratio] of the step/modulo
52
+ # @return the [Tonal::Ratio] representation of the step/modulo of self
53
53
  # @example
54
54
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).step_to_ratio
55
55
  # => 18/31
@@ -58,7 +58,7 @@ class Tonal::Scale
58
58
  Tonal::Ratio.new(step, modulo)
59
59
  end
60
60
 
61
- # @return [Rational] of the ratio
61
+ # @return the [Rational] representation of the ratio of self
62
62
  # @example
63
63
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).ratio_to_r
64
64
  # => (3/2)
@@ -67,7 +67,7 @@ class Tonal::Scale
67
67
  ratio.to_r
68
68
  end
69
69
 
70
- # @return [Tonal::Cents] measure of tempered in cents
70
+ # @return the [Tonal::Cents] measure of tempered in cents
71
71
  # @example
72
72
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).tempered_to_cents
73
73
  # => 696.77
@@ -76,7 +76,7 @@ class Tonal::Scale
76
76
  tempered.to_cents
77
77
  end
78
78
 
79
- # @return [Tonal::Cents] measure of ratio in cents
79
+ # @return the [Tonal::Cents] measure of ratio in cents
80
80
  # @example
81
81
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).ratio_to_cents
82
82
  # => 701.96
@@ -85,7 +85,7 @@ class Tonal::Scale
85
85
  ratio.to_cents
86
86
  end
87
87
 
88
- # @return [Tonal::Cents] the difference between the tempered number and the ratio
88
+ # @return the [Tonal::Cents] measure of the difference between the tempered number and the ratio
89
89
  # @example
90
90
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).efficiency => 5.19 ¢
91
91
  #
@@ -104,6 +104,10 @@ class Tonal::Scale
104
104
  step.coprime?(modulo)
105
105
  end
106
106
 
107
+ # @return a new [Tonal::Scale::Step] with the step added to the current step
108
+ # @example
109
+ # Tonal::Scale::Step.new(step: 5, modulo: 12) + Tonal::Scale::Step.new(step: 7, modulo: 12) => 0\12
110
+ #
107
111
  def +(rhs)
108
112
  self.class.new(step: (rhs % modulo), modulo: modulo)
109
113
  end
data/lib/tonal/tools.rb CHANGED
@@ -12,6 +12,7 @@ module Tonal
12
12
  require "tonal/log"
13
13
  require "tonal/log2"
14
14
  require "tonal/approximation"
15
+ require "tonal/midi"
15
16
  require "tonal/ratio"
16
17
  require "tonal/reduced_ratio"
17
18
  require "tonal/extended_ratio"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tonal-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.5.3
4
+ version: 8.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jose Hales-Garcia
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-05-03 00:00:00.000000000 Z
10
+ date: 2026-05-26 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: yaml
@@ -168,6 +168,7 @@ files:
168
168
  - lib/tonal/irb_helpers.rb
169
169
  - lib/tonal/log.rb
170
170
  - lib/tonal/log2.rb
171
+ - lib/tonal/midi.rb
171
172
  - lib/tonal/ratio.rb
172
173
  - lib/tonal/reduced_ratio.rb
173
174
  - lib/tonal/step.rb