class Musicality::Pitch
@author James Tunnell
@!attribute [r] octave
@return [Integer] The pitch octave.
@!attribute [r] semitone
@return [Integer] The pitch semitone.
Constants
- BASE_FREQ
The base ferquency is C0
- CENTS_PER_OCTAVE
- CENTS_PER_SEMITONE
- CONVERSION_METHOD
- PARSER
- SEMITONES_PER_OCTAVE
The default number of semitones per octave is 12, corresponding to
the twelve-tone equal temperment tuning system.
Attributes
Public Class Methods
# File lib/musicality/notation/model/pitch.rb, line 159 def self.from_freq freq from_ratio(freq / BASE_FREQ) end
# File lib/musicality/notation/model/pitch.rb, line 153 def self.from_ratio ratio raise NonPositiveError, "ratio #{ratio} is not > 0" unless ratio > 0 x = Math.log2 ratio new(cent: (x * CENTS_PER_OCTAVE).round) end
# File lib/musicality/notation/model/pitch.rb, line 113 def self.from_semitones semitones Pitch.new(cent: (semitones * CENTS_PER_SEMITONE).round) end
# File lib/musicality/notation/model/pitch.rb, line 35 def initialize octave:0, semitone:0, cent: 0 raise NonIntegerError, "octave #{octave} is not an integer" unless octave.is_a?(Integer) raise NonIntegerError, "semitone #{semitone} is not an integer" unless semitone.is_a?(Integer) raise NonIntegerError, "cent #{cent} is not an integer" unless cent.is_a?(Integer) @octave = octave @semitone = semitone @cent = cent @total_cents = (@octave*SEMITONES_PER_OCTAVE + @semitone)*CENTS_PER_SEMITONE + @cent balance! end
# File lib/musicality/notation/model/pitch.rb, line 125 def self.pc_str semitone, sharpit case semitone when 0 then "C" when 1 then sharpit ? "C#" : "Db" when 2 then "D" when 3 then sharpit ? "D#" : "Eb" when 4 then "E" when 5 then "F" when 6 then sharpit ? "F#" : "Gb" when 7 then "G" when 8 then sharpit ? "G#" : "Ab" when 9 then "A" when 10 then sharpit ? "A#" : "Bb" when 11 then "B" end end
Public Instance Methods
# File lib/musicality/notation/model/pitch.rb, line 101 def + semitones transpose(semitones) end
# File lib/musicality/notation/model/pitch.rb, line 105 def - semitones transpose(-semitones) end
Compare pitches. A higher ratio or total semitone is considered larger. @param [Pitch] other The pitch object to compare.
# File lib/musicality/notation/model/pitch.rb, line 79 def <=> (other) @total_cents <=> other.total_cents end
Compare pitch equality using total semitone
# File lib/musicality/notation/model/pitch.rb, line 68 def ==(other) return (self.class == other.class && @total_cents == other.total_cents) end
# File lib/musicality/notation/model/pitch.rb, line 117 def clone Pitch.new(cent: @total_cents) end
diff in (rounded) semitones
# File lib/musicality/notation/model/pitch.rb, line 93 def diff other Rational(@total_cents - other.total_cents, CENTS_PER_SEMITONE) end
# File lib/musicality/notation/model/pitch.rb, line 73 def eql?(other) self == other end
Return the pitch's frequency, which is determined by multiplying the base frequency and the pitch ratio. Base frequency defaults to DEFAULT_BASE_FREQ, but can be set during initialization to something else by specifying the :base_freq key.
# File lib/musicality/notation/model/pitch.rb, line 51 def freq return self.ratio() * BASE_FREQ end
Override default hash method.
# File lib/musicality/notation/model/pitch.rb, line 63 def hash return @total_cents end
# File lib/musicality/notation/model/pitch.rb, line 121 def natural? [0,2,4,5,7,9,11].include?(semitone) end
Calculate the pitch ratio. Raises 2 to the power of the total cent count divided by cents-per-octave. @return [Float] ratio
# File lib/musicality/notation/model/pitch.rb, line 58 def ratio 2.0**(@total_cents.to_f / CENTS_PER_OCTAVE) end
rounds to the nearest semitone
# File lib/musicality/notation/model/pitch.rb, line 84 def round if @cent == 0 self.clone else Pitch.new(semitone: (@total_cents / CENTS_PER_SEMITONE.to_f).round) end end
# File lib/musicality/printing/lilypond/pitch_engraving.rb, line 4 def to_lilypond sharpit = false output = PitchClass.to_lilypond(semitone, sharpit) if octave > 3 output += "'"*(octave - 3) elsif octave < 3 output += ","*(3 - octave) end return output end
# File lib/musicality/pitch_class.rb, line 16 def to_pc PitchClass.from_i semitone end
# File lib/musicality/notation/model/pitch.rb, line 142 def to_s(sharpit = false) letter = Pitch.pc_str(semitone, sharpit) if @cent == 0 return letter + octave.to_s elsif @cent > 0 return letter + octave.to_s + "+" + @cent.to_s else return letter + octave.to_s + @cent.to_s end end
# File lib/musicality/notation/model/pitch.rb, line 109 def total_semitones Rational(@total_cents, CENTS_PER_SEMITONE) end
# File lib/musicality/notation/model/pitch.rb, line 97 def transpose semitones Pitch.new(cent: (@total_cents + semitones * CENTS_PER_SEMITONE).round) end
Private Instance Methods
Balance out the octave and semitone count.
# File lib/musicality/notation/model/pitch.rb, line 166 def balance! centsTotal = @total_cents @octave = centsTotal / CENTS_PER_OCTAVE centsTotal -= @octave * CENTS_PER_OCTAVE @semitone = centsTotal / CENTS_PER_SEMITONE centsTotal -= @semitone * CENTS_PER_SEMITONE @cent = centsTotal return self end