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
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.
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.
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
Public: Returns the MIDI note number of the sample, which normally should be between 0 and 127.
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.
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.
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.
Public: Returns the SMPTE format (0, 24, 25, 29 or 30)
Public: Returns a SMPTETimecode
representing the SMPTE time offset.
Public Class Methods
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
# File lib/wavefile/sampler_info.rb, line 118 def required(keyword) raise ArgumentError.new("missing keyword: #{keyword}") end
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
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
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
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
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