class MTK::Core::Duration
A measure of time in musical beats. May be negative to indicate a rest, which uses the absolute value for the effective duration.
@see Lang::Durations
Constants
- NAMES
The names of the base durations. See {MTK::Lang::Durations} for more info.
- VALUES_BY_NAME
Attributes
The number of beats, typically represented as a Rational
Public Class Methods
Return a duration, only constructing a new instance when not already in the flyweight cache
# File lib/mtk/core/duration.rb, line 35 def self.[](length_in_beats) if length_in_beats.is_a? Fixnum value = length_in_beats else value = Rational(length_in_beats) end @flyweight[value] ||= new(value) end
Lookup a duration by name. This method supports appending any combination of ‘.’ and ‘t’ for more fine-grained values. each ‘.’ multiplies by 3/2, and each ‘t’ multiplies by 2/3. You may use the prefix ‘-’ to negate the duration (which turns it into a rest of the same length). You may also prefix (after the ‘-’ if present) the base duration name with an integer, float, or rational number to multiply the base duration value. Rationals are in the form “#!{numerator_integer}/#!{denominator_integer}”. @example lookup value of ‘q.’, which is 1.5 times a quarter note (1.5 beats):
MTK::Core::Duration.from_s('q.')
@example lookup the value of 3/4w, which three-quarters of a whole note (3 beats):
MTK::Core::Duration.from_s('3/4w')
# File lib/mtk/core/duration.rb, line 59 def self.from_s(s) if s =~ /^(-)?(\d+([\.\/]\d+)?)?([whqesrx])((\.|t)*)$/i name = $4.downcase modifier = $5.downcase modifier << $1 if $1 # negation multiplier = $2 else raise ArgumentError.new("Invalid Duration string '#{s}'") end value = VALUES_BY_NAME[name] modifier.each_char do |mod| case mod when '-' then value *= -1 when '.' then value *= Rational(3,2) when 't' then value *= Rational(2,3) end end if multiplier case multiplier when /\./ value *= multiplier.to_f when /\// numerator, denominator = multiplier.split('/') value *= Rational(numerator.to_i, denominator.to_i) else value *= multiplier.to_i end end self[value] end
# File lib/mtk/core/duration.rb, line 30 def initialize( length_in_beats ) @value = length_in_beats end
Public Instance Methods
Multiply this duration with another. @return a new Duration
that has a value of the product of the arguments.
# File lib/mtk/core/duration.rb, line 182 def * duration if duration.is_a? MTK::Core::Duration MTK::Core::Duration[@value * duration.value] else MTK::Core::Duration[@value * duration] end end
Add this duration to another. @return a new Duration
that has a value of the sum of the arguments.
# File lib/mtk/core/duration.rb, line 162 def + duration if duration.is_a? MTK::Core::Duration MTK::Core::Duration[@value + duration.value] else MTK::Core::Duration[@value + duration] end end
Subtract another duration from this one. @return a new Duration
that has a value of the difference of the arguments.
# File lib/mtk/core/duration.rb, line 172 def - duration if duration.is_a? MTK::Core::Duration MTK::Core::Duration[@value - duration.value] else MTK::Core::Duration[@value - duration] end end
Divide this duration with another. @return a new Duration
that has a value of the division of the arguments.
# File lib/mtk/core/duration.rb, line 192 def / duration if duration.is_a? MTK::Core::Duration MTK::Core::Duration[to_f / duration.value] else MTK::Core::Duration[to_f / duration] end end
# File lib/mtk/core/duration.rb, line 152 def <=> other if other.respond_to? :value @value <=> other.value else @value <=> other end end
# File lib/mtk/core/duration.rb, line 144 def ==( other ) if other.is_a? MTK::Core::Duration other.value == @value else other == @value end end
Allow basic math operations with Numeric
objects.
# File lib/mtk/core/duration.rb, line 209 def coerce(other) return MTK::Core::Duration[other], self end
# File lib/mtk/core/duration.rb, line 140 def inspect "#<#{self.class}:#{object_id} @value=#{@value}>" end
The number of beats as a floating point number
# File lib/mtk/core/duration.rb, line 125 def to_f @value.to_f end
The numerical value for the nearest whole number of beats
# File lib/mtk/core/duration.rb, line 130 def to_i @value.round end
# File lib/mtk/core/duration.rb, line 134 def to_s value = @value.to_s value = sprintf '%.2f', @value if value.length > 6 # threshold is 6 for no particular reason... "#{value} #{@value.abs > 1 || @value==0 ? 'beats' : 'beat'}" end