tonal-tools 8.7.0 → 8.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65ae90958bc67835b5792e9d248eebf51ef5625f5bf3e1fa2da75064f76865d9
4
- data.tar.gz: b9620ff46f3ded909da90d12af35326fa85387000f1432b768d8377b205f78c4
3
+ metadata.gz: 6a2b3699a8ff06f96c208824d04c62c5ea28db3915bcabf73d0ff0860fbf677f
4
+ data.tar.gz: e5fb5120820a4bf96d4489cdf0034a43de897d7dab7a040d6cfc94698ec6bb7e
5
5
  SHA512:
6
- metadata.gz: d73630cb8dec599a68d9f85731f676c3193d0f4f038f5757ace29a77ae8af65b5c74a5808f808605baa0e7392137b3200a4241b22f73870a788de4afb6c4f11a
7
- data.tar.gz: 18977208ddb36b81b446e5559acf7e1618baf360fdf49f75b567e0c6407727077840846b0ce0ada874a428e1c2ae3d281abe484d4f0d27c115c905cc76c1b191
6
+ metadata.gz: d85688a692e9cdf24bc776d2da3faf817015c9b72d31f2c5a4000f05a29db97bf3c13b78307c92496bd9fac1a3a1da9d34a02f250792af25aaf890a5f646d723
7
+ data.tar.gz: 0a21eff54af842f1a640d4fe6b6081a4679359c72f4e03fb06c782724c573b1ec2b1bcc78fbc8538413a464a8ad35ae18c0d5c72669b74d2a6fb7e86ec3ec566
@@ -1,4 +1,4 @@
1
1
  module Tonal
2
2
  TOOLS_PRODUCER = "mTonal"
3
- TOOLS_VERSION = "8.7.0"
3
+ TOOLS_VERSION = "8.8.1"
4
4
  end
data/lib/tonal/hertz.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  class Tonal::Hertz
2
2
  include Comparable
3
3
 
4
+ REFERENCE_FREQUENCY = 440.0
5
+
4
6
  attr_reader :value
5
7
 
6
8
  # @return [Tonal::Hertz]
@@ -18,7 +20,7 @@ class Tonal::Hertz
18
20
  # Tonal::Hertz.reference => 440.0 Hz
19
21
  #
20
22
  def self.reference
21
- self.new(440.0)
23
+ self.new(REFERENCE_FREQUENCY)
22
24
  end
23
25
 
24
26
  # @return [Rational] self as a rational
@@ -49,10 +51,12 @@ class Tonal::Hertz
49
51
  # @return [Tonal::Midi::Note] the midi representation of self
50
52
  # @example
51
53
  # Tonal::Hertz.new(440).to_midi => 69.0 MIDI
52
- # @param reference [Tonal::Hertz, Numeric] the reference frequency to compare to
54
+ # @param modulo [Integer] the modulo to use for the MIDI note calculation
55
+ # @param reference_number [Integer] the MIDI note number that anchors the conversion
56
+ # @param reference_frequency [Numeric] the frequency (Hz) that anchors the conversion
53
57
  #
54
- def to_midi_note
55
- Tonal::Midi::Note.new(frequency: to_f)
58
+ def to_midi_note(modulo: Tonal::Midi::Note::DEFAULT_MODULO, reference_number: Tonal::Midi::Note::A4_MIDI_NUMBER, reference_frequency: Tonal::Hertz::REFERENCE_FREQUENCY)
59
+ Tonal::Midi::Note.new(frequency: to_f, modulo: modulo, reference_number: reference_number, reference_frequency: reference_frequency)
56
60
  end
57
61
  alias :to_midi :to_midi_note
58
62
 
data/lib/tonal/midi.rb CHANGED
@@ -2,31 +2,51 @@ module Tonal::Midi
2
2
  class Note
3
3
  include Comparable
4
4
 
5
- REFERENCE_FREQUENCY = 440.0
6
5
  A4_MIDI_NUMBER = 69
7
6
  C4_MIDI_NUMBER = 60
7
+ DEFAULT_MODULO = 12
8
8
 
9
- attr_reader :number, :frequency
9
+ attr_reader :number, :modulo, :reference_number, :reference_frequency
10
10
 
11
11
  # @return [Tonal::Midi::Note]
12
12
  # @example
13
- # Tonal::Midi::Note.new(number:60) => 60.0 MIDI
14
- # @param arg [Numeric, Tonal::Midi::Note]
13
+ # Tonal::Midi::Note.new(number: 60) => 60 MIDI
14
+ # Tonal::Midi::Note.new(frequency: 261.63) => 60 MIDI
15
+ # @param number [Integer, nil] the MIDI note number. Mutually exclusive with frequency:
16
+ # @param frequency [Numeric, Tonal::Hertz, nil] the frequency in Hz. Mutually exclusive with number:
17
+ # @param modulo [Integer] the number of steps per octave
18
+ # @param reference_number [Integer] the MIDI note number that anchors the number/frequency conversion
19
+ # @param reference_frequency [Numeric] the frequency (Hz) that anchors the number/frequency conversion
15
20
  #
16
- def initialize(number: A4_MIDI_NUMBER, frequency: nil)
21
+ def initialize(number: nil, frequency: nil, modulo: DEFAULT_MODULO, reference_number: A4_MIDI_NUMBER, reference_frequency: Tonal::Hertz::REFERENCE_FREQUENCY)
22
+ raise ArgumentError, "Provide either number: or frequency:, not both" if number && frequency
23
+
24
+ @modulo = modulo
25
+ @reference_number = reference_number
26
+ @reference_frequency = reference_frequency.to_f
17
27
  if frequency
18
28
  raise ArgumentError, "Frequency argument is not Numeric or Tonal::Hertz" unless frequency.kind_of?(Numeric) || frequency.kind_of?(Tonal::Hertz)
19
29
  @frequency = Tonal::Hertz.new(frequency)
20
- @number = (A4_MIDI_NUMBER + 12 * Math.log2(frequency.to_f / REFERENCE_FREQUENCY)).round
30
+ @number = (@reference_number + modulo * Math.log2(frequency.to_f / @reference_frequency)).round
21
31
  else
32
+ number = @reference_number if number.nil?
22
33
  raise ArgumentError, "Number argument is not Integer" unless number.kind_of?(Integer)
23
- @number = number.kind_of?(self.class) ? number.inspect : number
24
- @frequency = Tonal::Hertz.new(REFERENCE_FREQUENCY * (2 ** ((number - A4_MIDI_NUMBER) / 12.0)))
34
+ @number = number
35
+ @frequency = Tonal::Hertz.new(@reference_frequency * (2 ** ((number - @reference_number) / modulo.to_f)))
25
36
  end
26
37
  end
27
38
 
28
39
  alias :value :number
29
40
 
41
+ # @return [Float] the frequency corresponding to the MIDI note number
42
+ # @example
43
+ # Tonal::Midi::Note.new(number:60).frequency => 261.6255653005986
44
+ # @param round [Integer, nil] the number of decimal places to round the frequency to, or nil for no rounding
45
+ #
46
+ def frequency(round: nil)
47
+ round ? @frequency.to_f.round(round) : @frequency.to_f
48
+ end
49
+
30
50
  # @return [String] representation of self
31
51
  def inspect
32
52
  "#{number} MIDI"
data/lib/tonal/ratio.rb CHANGED
@@ -174,6 +174,28 @@ class Tonal::Ratio
174
174
  end
175
175
  alias :cents :to_cents
176
176
 
177
+ # @return [Tonal::Hertz] the hertz of self with respect to a reference frequency
178
+ # @example
179
+ # Tonal::Ratio.new(3,2).to_hertz => 660.0
180
+ # @param reference [Numeric] the reference frequency
181
+ #
182
+ def to_hertz(reference: Tonal::Hertz.reference)
183
+ Tonal::Hertz.new(reference.to_f * to_f)
184
+ end
185
+
186
+ # @return [Tonal::Midi::Note] the midi representation of self with respect to a reference frequency
187
+ # @example
188
+ # Tonal::Ratio.new(3,2).to_midi => 76 MIDI
189
+ # @param reference [Numeric] the reference frequency
190
+ # @param modulo [Integer] the number of steps per octave used to scale self's offset from reference. The
191
+ # reference frequency's own MIDI note number is always computed independently of modulo.
192
+ #
193
+ def to_midi(reference: Tonal::Hertz.reference, modulo: Tonal::Midi::Note::DEFAULT_MODULO)
194
+ reference_hertz = Tonal::Hertz.new(reference)
195
+ reference_number = reference_hertz.to_midi_note.number
196
+ to_hertz(reference: reference_hertz).to_midi_note(modulo: modulo, reference_number: reference_number, reference_frequency: reference_hertz.to_f)
197
+ end
198
+
177
199
  # @return [Integer] the step of self in the given modulo
178
200
  # @example
179
201
  # Tonal::ReducedRatio.new(3,2).step(12) => 7\12
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.7.0
4
+ version: 8.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jose Hales-Garcia
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-06-02 00:00:00.000000000 Z
10
+ date: 2026-07-03 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: yaml
@@ -193,7 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
193
193
  - !ruby/object:Gem::Version
194
194
  version: '3.1'
195
195
  requirements: []
196
- rubygems_version: 4.0.11
196
+ rubygems_version: 4.0.14
197
197
  specification_version: 4
198
198
  summary: Tonal tools
199
199
  test_files: []