class WaveFile::SamplerInfo

Public: Provides a way to indicate the data contained in a “smpl” chunk.

That is, information about how the *.wav file could be used by a
sampler, such as the file's MIDI note or loop points. If a *.wav
file contains a "smpl" chunk, then Reader.sampler_info will
return an instance of this object with the relevant info.

Attributes

fine_tuning_cents[R]

Public: Returns the number of cents >= 0.0 and < 100.0 the note should be tuned up from the midi_note

field. 100 cents is equal to one semitone. For example, if this value is 50, and midi_note is
60, then the sample is tuned half-way between MIDI note 60 and 61. If the value is 0, then the
sample has no fine tuning.
loops[R]

Public: Returns an Array of 0 or more SamplerLoop objects containing loop point info. Loop point info

can indicate that (for example) the sampler should loop between a given sample range as long
as the sample is played.
manufacturer_id[R]

Public: Returns the ID of the manufacturer that this sample is intended for. If it's not

intended for a sampler from a particular manufacturer, this should be 0.
See the list at https://www.midi.org/specifications-old/item/manufacturer-id-numbers
midi_note[R]

Public: Returns the MIDI note number of the sample, which normally should be between 0 and 127.

product_id[R]

Public: Returns the ID of the product made by the manufacturer this sample is intended for.

If not intended for a particular product, this should be 0.
sample_nanoseconds[R]

Public: Returns the length of each sample in nanoseconds, which is typically determined by

converting <code>1 / sample rate</code> (in seconds) into nanoseconds. For example,
with a sample rate of 44100 this would be 22675 nanoseconds. However, this can be set
to an arbitrary value to allow for fine tuning.
sampler_specific_data[R]

Public: Returns a String of data specific to the intended target sampler, or nil if there is no sampler

specific data. This is returned as a raw String because the structure of this data depends on
the specific sampler. If you want to use it, you'll need to unpack the String yourself.
smpte_format[R]

Public: Returns the SMPTE format (0, 24, 25, 29 or 30)

smpte_offset[R]

Public: Returns a SMPTETimecode representing the SMPTE time offset.

Public Class Methods

new(manufacturer_id: required("manufacturer_id"), product_id: required("product_id"), sample_nanoseconds: required("sample_nanoseconds"), midi_note: required("midi_note"), fine_tuning_cents: required("fine_tuning_cents"), smpte_format: required("smpte_format"), smpte_offset: required("smpte_offset"), loops: required("loops"), sampler_specific_data: required("sampler_specific_data")) click to toggle source

Public: Constructs a new SamplerInfo instance.

manufacturer_id - the ID of the manufacturer that this sample is intended for. If it's not

intended for a sampler from a particular manufacturer, this should be 0.
See the list at https://www.midi.org/specifications-old/item/manufacturer-id-numbers

product_id - the ID of the product made by the manufacturer this sample is intended for.

If not intended for a particular product, this should be 0.

sample_nanoseconds - the length of each sample in nanoseconds, which is typically determined by

converting <code>1 / sample rate</code> (in seconds) into nanoseconds.
For example, with a sample rate of 44100 this would be 22675 nanoseconds. However,
this can be set to an arbitrary value to allow for fine tuning.

midi_note - the MIDI note number of the sample. Should be between 0 and 127. fine_tuning_cents - the number of cents >= 0.0 and < 100.0 the note should be tuned up from the midi_note

field. 100 cents is equal to one semitone. For example, if this value is 50.0, and
midi_note is 60, then the sample is tuned half-way between MIDI note 60 and 61. If the
value is 0, then the sample has no fine tuning.

smpte_format - the SMPTE format. Should be 0, 24, 25, 29 or 30. smpte_offset - a SMPTETimecode representing the SMPTE time offset. loops - an Array of 0 or more SamplerLoop objects containing loop point info. Loop point info

can indicate that (for example) the sampler should loop between a given sample range as long
as the sample is played.

sampler_specific_data - a String of data specific to the intended target sampler, or nil if there is no sampler

specific data.

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

# File lib/wavefile/sampler_info.rb, line 46
def initialize(manufacturer_id: required("manufacturer_id"),
               product_id: required("product_id"),
               sample_nanoseconds: required("sample_nanoseconds"),
               midi_note: required("midi_note"),
               fine_tuning_cents: required("fine_tuning_cents"),
               smpte_format: required("smpte_format"),
               smpte_offset: required("smpte_offset"),
               loops: required("loops"),
               sampler_specific_data: required("sampler_specific_data"))
  validate_32_bit_integer_field(manufacturer_id, "manufacturer_id")
  validate_32_bit_integer_field(product_id, "product_id")
  validate_32_bit_integer_field(sample_nanoseconds, "sample_nanoseconds")
  validate_32_bit_integer_field(midi_note, "midi_note")
  validate_fine_tuning_cents(fine_tuning_cents)
  validate_32_bit_integer_field(smpte_format, "smpte_format")
  validate_smpte_offset(smpte_offset)
  validate_loops(loops)
  validate_sampler_specific_data(sampler_specific_data)

  @manufacturer_id = manufacturer_id
  @product_id = product_id
  @sample_nanoseconds = sample_nanoseconds
  @midi_note = midi_note
  @fine_tuning_cents = fine_tuning_cents
  @smpte_format = smpte_format
  @smpte_offset = smpte_offset
  @loops = loops
  @sampler_specific_data = sampler_specific_data
end

Private Instance Methods

required(keyword) click to toggle source
# File lib/wavefile/sampler_info.rb, line 118
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_info.rb, line 123
def validate_32_bit_integer_field(candidate, field_name)
  unless candidate.is_a?(Integer) && VALID_32_BIT_INTEGER_RANGE === candidate
    raise InvalidSamplerInfoError,
          "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_fine_tuning_cents(candidate) click to toggle source

Internal

# File lib/wavefile/sampler_info.rb, line 131
def validate_fine_tuning_cents(candidate)
  unless (candidate.is_a?(Integer) || candidate.is_a?(Float)) && candidate >= 0.0 && candidate < 100.0
    raise InvalidSamplerInfoError,
          "Invalid `fine_tuning_cents` value: `#{candidate}`. Must be a number >= 0.0 and < 100.0"
  end
end
validate_loops(candidate) click to toggle source

Internal

# File lib/wavefile/sampler_info.rb, line 147
def validate_loops(candidate)
  unless candidate.is_a?(Array) && candidate.select {|loop| !loop.is_a?(SamplerLoop) }.empty?
    raise InvalidSamplerInfoError,
          "Invalid `loops` value: `#{candidate}`. Must be an Array of SampleLoop objects"
  end
end
validate_sampler_specific_data(candidate) click to toggle source

Internal

# File lib/wavefile/sampler_info.rb, line 155
def validate_sampler_specific_data(candidate)
  unless candidate.is_a?(String)
    raise InvalidSamplerInfoError,
          "Invalid `sampler_specific_data` value: `#{candidate}`. Must be a String"
  end
end
validate_smpte_offset(candidate) click to toggle source

Internal

# File lib/wavefile/sampler_info.rb, line 139
def validate_smpte_offset(candidate)
  unless candidate.is_a?(SMPTETimecode)
    raise InvalidSamplerInfoError,
          "Invalid `smpte_offset` value: `#{candidate}`. Must be an instance of SMPTETimecode"
  end
end