class Music::Transcription::Pitch
@author James Tunnell
@!attribute [r] octave
@return [Fixnum] The pitch octave.
@!attribute [r] semitone
@return [Fixnum] 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/music-transcription/model/pitch.rb, line 143 def self.from_freq freq from_ratio(freq / BASE_FREQ) end
# File lib/music-transcription/model/pitch.rb, line 137 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/music-transcription/model/pitch.rb, line 104 def self.from_semitones semitones Pitch.new(cent: (semitones * CENTS_PER_SEMITONE).round) end
# File lib/music-transcription/model/pitch.rb, line 34 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
Public Instance Methods
Compare pitches. A higher ratio or total semitone is considered larger. @param [Pitch] other The pitch object to compare.
# File lib/music-transcription/model/pitch.rb, line 78 def <=> (other) @total_cents <=> other.total_cents end
Compare pitch equality using total semitone
# File lib/music-transcription/model/pitch.rb, line 67 def ==(other) return (self.class == other.class && @total_cents == other.total_cents) end
# File lib/music-transcription/model/pitch.rb, line 108 def clone Pitch.new(cent: @total_cents) end
diff in (rounded) semitones
# File lib/music-transcription/model/pitch.rb, line 92 def diff other Rational(@total_cents - other.total_cents, CENTS_PER_SEMITONE) end
# File lib/music-transcription/model/pitch.rb, line 72 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/music-transcription/model/pitch.rb, line 50 def freq return self.ratio() * BASE_FREQ end
Override default hash method.
# File lib/music-transcription/model/pitch.rb, line 62 def hash return @total_cents 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/music-transcription/model/pitch.rb, line 57 def ratio 2.0**(@total_cents.to_f / CENTS_PER_OCTAVE) end
rounds to the nearest semitone
# File lib/music-transcription/model/pitch.rb, line 83 def round if @cent == 0 self.clone else Pitch.new(semitone: (@total_cents / CENTS_PER_SEMITONE.to_f).round) end end
# File lib/music-transcription/model/pitch.rb, line 112 def to_s(sharpit = false) letter = 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 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/music-transcription/model/pitch.rb, line 100 def total_semitones Rational(@total_cents, CENTS_PER_SEMITONE) end
# File lib/music-transcription/model/pitch.rb, line 96 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/music-transcription/model/pitch.rb, line 150 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