class SMPTE::SMPTE

Attributes

df[R]
frame_count[R]
frames[R]
has_frames[R]
has_subframes[R]
hours[R]
minutes[R]
seconds[R]
subframes[R]

Public Class Methods

new(string, df=nil) click to toggle source

This can be initialized in one of four ways:

smpte string - with or without frame count integer frame count floating point frame count another smpte object

# File lib/smpte/base.rb, line 87
def initialize(string, df=nil)
  if string.kind_of?(String) && string.to_s =~ /(\d\d):(\d\d):(\d\d)(?:([:;])(\d\d)(\.\d+)?)?/
    @hours, @minutes, @seconds, sep, @frames, @subframes = $1.to_i, $2.to_i, $3.to_i, $4, $5, $6
    @has_frames = !@frames.nil?
    @frames = 0 unless @frames
    @frames = @frames.to_i
    @has_subframes = !@subframes.nil?
    @subframes = @subframes.to_f   # note that nil.to_f == 0.0
    @frame_count = (((@hours * 60) + @minutes) * 60 + @seconds) * 30 + @frames
    if df.to_s == 'df' || df.to_s == 'drop frame' || sep == ';'
      @df = 'df'
    else
      @df = 'ndf'
    end
    if @df == 'df'
      # Every hour, we drop 108 frame #'s.  Every minute, we drop 2 frame
      # #'s, except for the even 10 minutes (00, 10, 20, 30, 40, & 50).
      # The numbers that are dropped are frames 00 and 01, meaning that we
      # have to subtract two for each minute > 0.
      #
      # Consider, 00:02:59:29, next frame is 00:03:00:02, so 00 and 01 were
      # skipped.  This is going to make to_s fun fun fun...
      @frame_count -= (@hours * 108)
      @frame_count -= ((@minutes/10).floor * 18)
      # In reality, this is a sanity check.  03:01:00:01 isn't a valid
      # drop-frame smpte code.
      # But if it shows up, I'm not going to subtract two frames for it.
      if @minutes%10 >= 1
        if @frames >=2 || @seconds > 0
          @frame_count -= (@minutes%10)*2
        else
          @frame_count -= ((@minutes%10)-1)*2
        end
      end
    end
  elsif string.kind_of?(SMPTE)
    @frame_count = string.to_i
    @has_frames = string.has_frames
    @has_subframes = string.has_subframes
    @df = df.nil? ? string.df : ((df.to_s=='df' || df.to_s=='drop frame') ? 'df' : 'ndf')
    @hours = string.hours
    @minutes = string.minutes
    @seconds = string.seconds
    @frames = string.frames
    @subframes = string.subframes
  elsif string.kind_of?(Integer)
    @frame_count = string.to_i
    @has_frames = true
    @has_subframes = false
    @df = (df.to_s=='df' || df.to_s=='drop frame') ? 'df' : 'ndf'
    compute_times
  elsif string.kind_of?(Float)
    @frame_count = string.floor
    @subframes = string - @frame_count.to_f
    @has_frames = true
    @has_subframes = true
    @df = (df.to_s=='df' || df.to_s=='drop frame') ? 'df' : 'ndf'
    compute_times
  else
    raise InvalidParameterError
  end
  if @has_subframes
    @frame_count = @frame_count.to_f + @subframes
  end
end
valid?(string) click to toggle source
# File lib/smpte/base.rb, line 77
def self.valid?(string)
  string.to_s.match(/(\d\d):(\d\d):(\d\d)(?:[:;](\d\d)(\.\d+)?)?/)
end

Public Instance Methods

+(more_frames) click to toggle source

Adds a number of frames to a SMPTE

# File lib/smpte/base.rb, line 170
def +(more_frames)
  if @has_subframes
    self.class.new(@frame_count.to_f + @subframe_count + more_frames.to_f, @df)
  else
    self.class.new(@frame_count + more_frames.to_i, @df)
  end
end
-(other) click to toggle source

Returns difference between two SMPTEs as a SMPTE - use to_i to get a frame count.

# File lib/smpte/base.rb, line 165
def -(other)
  self.class.new(@frame_count - other.frame_count, @df)
end
<=>(other) click to toggle source

Comparision operator to make Comparable work

# File lib/smpte/base.rb, line 159
def <=>(other)
  @frame_count - other.frame_count
end
eql?(other) click to toggle source

Check equality (equal frame counts)

# File lib/smpte/base.rb, line 154
def eql?(other)
  @frame_count == other.frame_count
end
to_df() click to toggle source

Returns a SMPTE with same frame count but forced to drop frame format.

# File lib/smpte/base.rb, line 179
def to_df
  if @df=='df'
    self.dup
  else
    self.class.new(@frame_count,'df')
  end
end
to_f() click to toggle source

Returns frame count as float - with subframe count where applicable

# File lib/smpte/base.rb, line 271
def to_f
  @frame_count.to_f
end
to_i() click to toggle source

Return the frame count

# File lib/smpte/base.rb, line 257
def to_i
  if @has_subframes
    @frame_count.round
  else
    @frame_count
  end
end
to_int() click to toggle source

Alias for to_i

# File lib/smpte/base.rb, line 266
def to_int
  to_i
end
to_ndf() click to toggle source

Returns a SMPTE with same frame count but forced to non-drop frame format.

# File lib/smpte/base.rb, line 188
def to_ndf
  if @df=='ndf'
    self.dup
  else
    self.class.new(@frame_count,'ndf')
  end
end
to_s() click to toggle source

Converts to string format

# File lib/smpte/base.rb, line 241
def to_s
  if @has_subframes
    sprintf("%02d:%02d:%02d%s%02d.%02d", @hours, @minutes, @seconds, (@df=='df' ? ';' : ':'), @frames, (@subframes * 100).floor)
  elsif @has_frames
    sprintf("%02d:%02d:%02d%s%02d", @hours, @minutes, @seconds, (@df=='df' ? ';' : ':'), @frames)
  else
    sprintf("%02d:%02d:%02d", @hours, @minutes, @seconds)
  end
end
to_str() click to toggle source

Alias for to_s

# File lib/smpte/base.rb, line 252
def to_str
  to_s
end

Private Instance Methods

compute_times() click to toggle source

Internal private method to compute various time pieces for this SMPTE.

# File lib/smpte/base.rb, line 197
def compute_times
  total_frames = @frame_count
  @hours = @ten_minute_periods = @minutes = @seconds = @frames = 0
  if @df == 'df'
    # One hour of NTSC video has 107,892 instead of 108,000 frames.
    # Ten @minutes of NTSC video has 17,982 @frames instead of 18,000.
    @hours = (total_frames/107892).floor
    total_frames = total_frames % 107892
    ten_minute_periods = (total_frames/17982).floor
    total_frames = total_frames % 17982
    if total_frames >= 1800
      total_frames -= 1800
      # The first minute is a given
      @minutes = (total_frames/1798).floor + 1
      total_frames %= 1798
      if total_frames >= 28
        total_frames -= 28
        # The first second is a given
        @seconds = (total_frames/30).floor + 1
        @frames = total_frames % 30
      else
        @seconds = 0
        @frames = total_frames+2
      end
    else
      @minutes = 0
      @seconds = (total_frames/30).floor
      @frames = total_frames % 30
    end
    @minutes += ten_minute_periods * 10
  else
    @frames = total_frames % 30
    total_frames = (total_frames/30).floor
    @seconds = total_frames % 60
    total_frames = (total_frames/60).floor
    @minutes = total_frames % 60
    total_frames = (total_frames/60).floor
    @hours = total_frames
  end
end