tonal-tools 8.5.2 → 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: 9693004e4d76b2c000404f674643eab88d6f9cfa6096d2c7f47e7f25eabfb8b1
4
- data.tar.gz: cbf08e054d50ba6b677472aeb5d8824c45dd2493425cecbea0852aeb50a50249
3
+ metadata.gz: 25126d841103214bbe0a1fe1dcd861460ff4bf7b108ac3e0854032e037f64ab1
4
+ data.tar.gz: 3f3941c9a097f937d08f5c0b9fc1edec5df331b45d12599b0dcedfaa275ed6b4
5
5
  SHA512:
6
- metadata.gz: d2ba9456c73a6a6c48ef51acc2fd0572f8ffd9be7a0735b77b18c6a1e0a8faf6a352df45b3d5f44b057200c51e936ea9ba21d5ea210fdf607a327c33ebf4282a
7
- data.tar.gz: '02078ab88ddd46711864a22a4b568e2f2c0df14d3c854518e2eb01835b1abaacb4a8d5148988381b2fd3c8553eb21361f8faff725405c242f0a6a6e379e7233b'
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.2"
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,16 @@ class Tonal::Scale
49
49
  Rational(step, modulo)
50
50
  end
51
51
 
52
- # @return [Rational] of the ratio
52
+ # @return the [Tonal::Ratio] representation of the step/modulo of self
53
+ # @example
54
+ # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).step_to_ratio
55
+ # => 18/31
56
+ #
57
+ def step_to_ratio
58
+ Tonal::Ratio.new(step, modulo)
59
+ end
60
+
61
+ # @return the [Rational] representation of the ratio of self
53
62
  # @example
54
63
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).ratio_to_r
55
64
  # => (3/2)
@@ -58,7 +67,7 @@ class Tonal::Scale
58
67
  ratio.to_r
59
68
  end
60
69
 
61
- # @return [Tonal::Cents] measure of tempered in cents
70
+ # @return the [Tonal::Cents] measure of tempered in cents
62
71
  # @example
63
72
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).tempered_to_cents
64
73
  # => 696.77
@@ -67,7 +76,7 @@ class Tonal::Scale
67
76
  tempered.to_cents
68
77
  end
69
78
 
70
- # @return [Tonal::Cents] measure of ratio in cents
79
+ # @return the [Tonal::Cents] measure of ratio in cents
71
80
  # @example
72
81
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).ratio_to_cents
73
82
  # => 701.96
@@ -76,7 +85,7 @@ class Tonal::Scale
76
85
  ratio.to_cents
77
86
  end
78
87
 
79
- # @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
80
89
  # @example
81
90
  # Tonal::Scale::Step.new(ratio: 3/2r, modulo: 31).efficiency => 5.19 ¢
82
91
  #
@@ -95,6 +104,10 @@ class Tonal::Scale
95
104
  step.coprime?(modulo)
96
105
  end
97
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
+ #
98
111
  def +(rhs)
99
112
  self.class.new(step: (rhs % modulo), modulo: modulo)
100
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.2
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