class WaveFile::SamplerLoop

Public: Provides a way to indicate the data about sampler loop points

in a file's "smpl" chunk. That is, information about how a sampler
could loop between a sample range while playing this *.wav as a note.
If a *.wav file contains a "smpl" chunk, then Reader.sampler_info.loops
will return an array of SamplerLoop objects with the relevant info.

Attributes

end_sample_frame[R]

Public: Returns the last sample frame of the loop.

fraction[R]

Public: A value >= 0.0 and < 1.0 which specifies a fraction of a sample at which to loop.

This allows a loop to be fine tuned at a resolution finer than one sample.
id[R]

Public: Returns a numeric ID which identifies the specific loop

play_count[R]

Public: Returns the number of times to loop. Will be an Integer 1 or greater, or Float::INFINITY.

start_sample_frame[R]

Public: Returns the first sample frame of the loop.

type[R]

Public: Returns a symbol indicating which direction the loop should run. The possible values

are :forward, :alternating, :backward, or a positive Integer. Integer values 3 or greater
are allowed by the *.wav file spec, but don't necessarily have a defined meaning.

Public Class Methods

new(id: required("id"), type: required("type"), start_sample_frame: required("start_sample_frame"), end_sample_frame: required("end_sample_frame"), fraction: required("fraction"), play_count: required("play_count")) click to toggle source

Public: Constructs a new SamplerLoop instance.

id - A numeric ID which identifies the specific loop. Should be an Integer 0 or greater. type - Indicates which direction the loop should run. Should either be one of the symbols

+:forward+, +:alternating+, +:backward+, or a positive Integer. If an Integer, then 0 will
be normalized to +:forward+, 1 to +:alternating+, 2 to +:backward+. Integer values 3 or
greater are allowed by the *.wav file spec, but don't necessarily have a defined meaning.

start_sample_frame - The first sample frame in the loop. end_sample_frame - The last sample frame in the loop. fraction - A Float >= 0.0 and < 1.0 which specifies a fraction of a sample at which to start

the loop. This allows a loop start to be fine tuned at a resolution finer than one sample.

play_count - The number of times to loop. Can be an Integer 0 or greater, or Float::INFINITY.

A value of 0 will be normalized to Float::INFINITY, because in the file format a
value of 0 means to repeat the loop indefinitely.

Raises InvalidSamplerLoopError if the given arguments can't be written to a *.wav file.

# File lib/wavefile/sampler_loop.rb, line 40
def initialize(id: required("id"),
              type: required("type"),
              start_sample_frame: required("start_sample_frame"),
              end_sample_frame: required("end_sample_frame"),
              fraction: required("fraction"),
              play_count: required("play_count"))
  type = normalize_type(type)
  if play_count == 0
    play_count = Float::INFINITY
  end

  validate_32_bit_integer_field(id, "id")
  validate_loop_type(type)
  validate_32_bit_integer_field(start_sample_frame, "start_sample_frame")
  validate_32_bit_integer_field(end_sample_frame, "end_sample_frame")
  validate_fraction(fraction)
  validate_play_count(play_count)

  @id = id
  @type = type
  @start_sample_frame = start_sample_frame
  @end_sample_frame = end_sample_frame
  @fraction = fraction
  @play_count = play_count
end

Private Instance Methods

normalize_type(type) click to toggle source

Internal

# File lib/wavefile/sampler_loop.rb, line 94
def normalize_type(type)
  if !type.is_a?(Integer)
    return type
  end

  if type == 0
    :forward
  elsif type == 1
    :alternating
  elsif type == 2
    :backward
  else
    type
  end
end
required(keyword) click to toggle source
# File lib/wavefile/sampler_loop.rb, line 89
def required(keyword)
  raise ArgumentError.new("missing keyword: #{keyword}")
end
validate_32_bit_integer_field(candidate, field_name) click to toggle source

Internal

# File lib/wavefile/sampler_loop.rb, line 111
def validate_32_bit_integer_field(candidate, field_name)
  unless candidate.is_a?(Integer) && VALID_32_BIT_INTEGER_RANGE === candidate
    raise InvalidSamplerLoopError,
          "Invalid `#{field_name}` value: `#{candidate}`. Must be an Integer between #{VALID_32_BIT_INTEGER_RANGE.min} and #{VALID_32_BIT_INTEGER_RANGE.max}"
  end
end
validate_fraction(candidate) click to toggle source

Internal

# File lib/wavefile/sampler_loop.rb, line 127
def validate_fraction(candidate)
  unless (candidate.is_a?(Integer) || candidate.is_a?(Float)) && candidate >= 0.0 && candidate < 1.0
    raise InvalidSamplerLoopError,
          "Invalid `fraction` value: `#{candidate}`. Must be >= 0.0 and < 1.0"
  end
end
validate_loop_type(candidate) click to toggle source

Internal

# File lib/wavefile/sampler_loop.rb, line 119
def validate_loop_type(candidate)
  unless VALID_LOOP_TYPES.include?(candidate) || (candidate.is_a?(Integer) && VALID_32_BIT_INTEGER_RANGE === candidate)
    raise InvalidSamplerLoopError,
          "Invalid `type` value: `#{candidate}`. Must be an Integer between #{VALID_32_BIT_INTEGER_RANGE.min} and #{VALID_32_BIT_INTEGER_RANGE.max} or one of #{VALID_LOOP_TYPES}"
  end
end
validate_play_count(candidate) click to toggle source

Internal

# File lib/wavefile/sampler_loop.rb, line 135
def validate_play_count(candidate)
  unless candidate == Float::INFINITY || (candidate.is_a?(Integer) && VALID_32_BIT_INTEGER_RANGE === candidate)
    raise InvalidSamplerLoopError,
          "Invalid `type` value: `#{candidate}`. Must be Float::INFINITY or an Integer between #{VALID_32_BIT_INTEGER_RANGE.min} and #{VALID_32_BIT_INTEGER_RANGE.max}"
  end
end