Class: Wavify::Core::Duration
- Inherits:
-
Object
- Object
- Wavify::Core::Duration
- Includes:
- Comparable, Comparable[Duration]
- Defined in:
- lib/wavify/core/duration.rb,
sig/core.rbs
Overview
Immutable duration value object used across codecs and sequencer APIs.
Instance Attribute Summary collapse
-
#total_seconds ⇒ Float
readonly
Returns the value of attribute total_seconds.
Class Method Summary collapse
-
.from_samples(sample_frames, sample_rate) ⇒ Duration
Builds a duration from a frame count and sample rate.
-
.parse(value) ⇒ Duration
Parses
SS.sss,MM:SS.sss, orHH:MM:SS.ssstext.
Instance Method Summary collapse
- #+(other) ⇒ Duration
- #-(other) ⇒ Duration
-
#<=>(other) ⇒ -1, ...
Compares two durations.
- #eql?(other) ⇒ Boolean
- #hash ⇒ Integer
-
#hours ⇒ Integer
Hours component for #to_s.
-
#initialize(total_seconds) ⇒ Duration
constructor
A new instance of Duration.
-
#milliseconds ⇒ Integer
Milliseconds component for #to_s.
-
#minutes ⇒ Integer
Minutes component for #to_s.
-
#seconds ⇒ Integer
Seconds component for #to_s.
-
#to_s ⇒ String
Returns a clock-style string (
HH:MM:SS.mmm).
Constructor Details
#initialize(total_seconds) ⇒ Duration
Returns a new instance of Duration.
51 52 53 54 55 56 57 58 |
# File 'lib/wavify/core/duration.rb', line 51 def initialize(total_seconds) unless total_seconds.is_a?(Numeric) && total_seconds.respond_to?(:finite?) && total_seconds.finite? && total_seconds >= 0 raise InvalidParameterError, "total_seconds must be a non-negative finite Numeric: #{total_seconds.inspect}" end @total_seconds = total_seconds.to_f freeze end |
Instance Attribute Details
#total_seconds ⇒ Float (readonly)
Returns the value of attribute total_seconds.
9 10 11 |
# File 'lib/wavify/core/duration.rb', line 9 def total_seconds @total_seconds end |
Class Method Details
.from_samples(sample_frames, sample_rate) ⇒ Duration
Builds a duration from a frame count and sample rate.
16 17 18 19 20 21 22 23 24 25 |
# File 'lib/wavify/core/duration.rb', line 16 def self.from_samples(sample_frames, sample_rate) unless sample_frames.is_a?(Integer) && sample_frames >= 0 raise InvalidParameterError, "sample_frames must be a non-negative Integer: #{sample_frames.inspect}" end unless sample_rate.is_a?(Integer) && sample_rate.positive? raise InvalidParameterError, "sample_rate must be a positive Integer: #{sample_rate.inspect}" end new(sample_frames.to_f / sample_rate) end |
.parse(value) ⇒ Duration
Parses SS.sss, MM:SS.sss, or HH:MM:SS.sss text.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/wavify/core/duration.rb', line 31 def self.parse(value) raise InvalidParameterError, "duration must be a String" unless value.is_a?(String) parts = value.strip.split(":") component_count = parts.length raise InvalidParameterError, "invalid duration: #{value.inspect}" unless component_count.between?(1, 3) seconds = parse_seconds(parts.pop) minutes = parts.empty? ? 0.0 : parse_component(parts.pop, :minutes) hours = parts.empty? ? 0.0 : parse_component(parts.pop, :hours) raise InvalidParameterError, "invalid duration: #{value.inspect}" unless parts.empty? raise InvalidParameterError, "minutes must be less than 60" if component_count == 3 && minutes >= 60.0 raise InvalidParameterError, "seconds must be less than 60" if component_count >= 2 && seconds >= 60.0 new((hours * 3600.0) + (minutes * 60.0) + seconds) rescue ArgumentError raise InvalidParameterError, "invalid duration: #{value.inspect}" end |
Instance Method Details
#+(other) ⇒ Duration
78 79 80 81 82 |
# File 'lib/wavify/core/duration.rb', line 78 def +(other) raise InvalidParameterError, "expected Duration: #{other.inspect}" unless other.is_a?(Duration) self.class.new(@total_seconds + other.total_seconds) end |
#-(other) ⇒ Duration
84 85 86 87 88 89 90 91 |
# File 'lib/wavify/core/duration.rb', line 84 def -(other) raise InvalidParameterError, "expected Duration: #{other.inspect}" unless other.is_a?(Duration) value = @total_seconds - other.total_seconds raise InvalidParameterError, "resulting duration cannot be negative: #{value}" if value.negative? self.class.new(value) end |
#<=>(other) ⇒ -1, ...
Compares two durations.
64 65 66 67 68 |
# File 'lib/wavify/core/duration.rb', line 64 def <=>(other) return nil unless other.is_a?(Duration) @total_seconds <=> other.total_seconds end |
#eql?(other) ⇒ Boolean
70 71 72 |
# File 'lib/wavify/core/duration.rb', line 70 def eql?(other) other.is_a?(Duration) && @total_seconds.eql?(other.total_seconds) end |
#hash ⇒ Integer
74 75 76 |
# File 'lib/wavify/core/duration.rb', line 74 def hash @total_seconds.hash end |
#hours ⇒ Integer
Returns hours component for #to_s.
94 95 96 |
# File 'lib/wavify/core/duration.rb', line 94 def hours (total_milliseconds / 3_600_000).floor end |
#milliseconds ⇒ Integer
Returns milliseconds component for #to_s.
109 110 111 |
# File 'lib/wavify/core/duration.rb', line 109 def milliseconds (total_milliseconds % 1000).floor end |
#minutes ⇒ Integer
Returns minutes component for #to_s.
99 100 101 |
# File 'lib/wavify/core/duration.rb', line 99 def minutes ((total_milliseconds % 3_600_000) / 60_000).floor end |
#seconds ⇒ Integer
Returns seconds component for #to_s.
104 105 106 |
# File 'lib/wavify/core/duration.rb', line 104 def seconds ((total_milliseconds % 60_000) / 1000).floor end |
#to_s ⇒ String
Returns a clock-style string (HH:MM:SS.mmm).
116 117 118 119 120 121 122 |
# File 'lib/wavify/core/duration.rb', line 116 def to_s format("%<hours>02d:%<minutes>02d:%<seconds>02d.%<milliseconds>03d", hours: hours, minutes: minutes, seconds: seconds, milliseconds: milliseconds) end |