class WaveFile::Reader
Provides the ability to read sample data out of a wave file, as well as query a wave file about its metadata (e.g. number of channels, sample rate, etc).
When constructing a Reader
a block can be given. All data should be read inside this block, and when the block exits the Reader
will automatically be closed.
Reader.new("my_file.wav") do |reader| # Read sample data here end
Alternately, if a block isn’t given you should make sure to call close when finished reading.
reader = Reader.new("my_file.wav") # Read sample data here reader.close
Public
↑ topPublic Class Methods
Constructs a Reader
object that is ready to start reading the specified file’s sample data.
- io_or_file_name
-
The name of the wave file to read from, or an open IO object to read from.
- format
-
The format that read sample data should be returned in (default: the wave file’s internal format).
Returns¶ ↑
Returns a Reader
object that is ready to start reading the specified file’s sample data.
Raises Errno::ENOENT
if the specified file can’t be found.
Raises InvalidFormatError
if the specified file isn’t a valid wave file.
# File lib/wavefile/reader.rb, line 34 def initialize(io_or_file_name, format=nil) if io_or_file_name.is_a?(String) @io = File.open(io_or_file_name, "rb") @io_source = :file_name else @io = io_or_file_name @io_source = :io end @closed = false riff_reader = ChunkReaders::RiffReader.new(@io, format) @data_chunk_reader = riff_reader.data_chunk_reader @sample_chunk = riff_reader.sample_chunk if block_given? begin yield(self) ensure close end end end
Public Instance Methods
Closes the Reader
. If the Reader
is already closed, does nothing. After a Reader
is closed, no more sample data can be read from it. Note: If the Reader
is constructed from an open IO instance (as opposed to a file name), the IO instance will not be closed. You’ll have to manually close it yourself. This is intentional, because Reader
can’t know what you may/may not want to do with the IO instance in the future.
Returns¶ ↑
Returns nothing.
# File lib/wavefile/reader.rb, line 153 def close return if @closed if @io_source == :file_name @io.close end @closed = true end
Returns¶ ↑
Returns the index of the sample frame which is “cued up” for reading. I.e., the index of the next sample frame that will be read. A sample frame contains a single sample for each channel. So if there are 1,000 sample frames in a stereo file, this means there are 1,000 left-channel samples and 1,000 right-channel samples.
# File lib/wavefile/reader.rb, line 196 def current_sample_frame @data_chunk_reader.current_sample_frame end
Starting from the current reading position, reads sample frames into successive Buffers of the specified size, until there are no more sample frames to be read. When the final sample frame has been read the Reader
is automatically closed. Each Buffer
is passed to the given block.
If the Reader
is constructed from an open IO, the IO is NOT closed after all sample data is read. However, the Reader
will be closed and any attempt to continue to read from it will result in an error.
Note that sample_frame_count indicates the number of sample frames to read, not number of samples. A sample frame include one sample for each channel. For example, if sample_frame_count is 1024, then for a stereo file 1024 samples will be read from the left channel, and 1024 samples will be read from the right channel.
- sample_frame_count
-
The number of sample frames to read into each
Buffer
from each channel. The number of sample frames read into the finalBuffer
could be less than this size, if there are not enough remaining.
Examples¶ ↑
# sample_frame_count not given, so default buffer size Reader.new("my_file.wav").each_buffer do |buffer| puts "#{buffer.samples.length} sample frames read" end # Specific sample_frame_count given for each buffer Reader.new("my_file.wav").each_buffer(1024) do |buffer| puts "#{buffer.samples.length} sample frames read" end # Reading each buffer from an externally created IO file = File.open("my_file.wav", "rb") Reader.new(file).each_buffer do |buffer| puts "#{buffer.samples.length} sample frames read" end # Although Reader is closed, file still needs to be manually closed file.close reader = Reader.new("my_file.wav") reader.read(100) # Reading using `each_buffer` will start at the 101st sample frame: reader.each_buffer do |buffer| puts "#{buffer.samples.length} sample frames read" end # At this point, the Reader is now closed (even without # a call to `close()`)
Returns¶ ↑
Returns nothing. Has side effect of closing the Reader
.
# File lib/wavefile/reader.rb, line 106 def each_buffer(sample_frame_count=4096) begin while true do yield(read(sample_frame_count)) end rescue EOFError close end end
Returns¶ ↑
Returns an object describing how sample data is being read from the Wave file. I.e., number of channels, bits per sample, sample format, etc. If readable_format?
is true, then this will be a Format
object. The format the samples are read out as might be different from how the samples are actually stored in the file. Therefore, format
might not match native_format
. If readable_format?
is false, then this will return the same value as native_format
.
# File lib/wavefile/reader.rb, line 188 def format @data_chunk_reader.format end
Returns¶ ↑
Returns an object describing the sample format of the Wave file being read. This returns the data contained in the “fmt ” chunk of the Wave file. It will not necessarily match the format that the samples are read out as (for that, see format
).
# File lib/wavefile/reader.rb, line 171 def native_format @data_chunk_reader.raw_native_format end
Reads the specified number of sample frames from the wave file into a Buffer
. Note that the Buffer
will have at most sample_frame_count sample frames, but could have less if the file doesn’t have enough remaining.
- sample_frame_count
-
The number of sample frames to read. Note that each sample frame includes a sample for each channel.
Returns¶ ↑
Returns a Buffer
containing sample_frame_count sample frames.
Raises UnsupportedFormatError
if file is in a format that can’t be read by this gem.
Raises ReaderClosedError
if the Reader
has been closed.
Raises EOFError if no samples could be read due to reaching the end of the file.
# File lib/wavefile/reader.rb, line 131 def read(sample_frame_count) if @closed raise ReaderClosedError end @data_chunk_reader.read(sample_frame_count) end
Returns¶ ↑
Returns true if this is a valid Wave file and contains sample data that is in a format that this class can read, and returns false if this is a valid Wave file but does not contain a sample format that this gem knows how to read.
# File lib/wavefile/reader.rb, line 178 def readable_format? @data_chunk_reader.readable_format end
Returns¶ ↑
Returns a SamplerInfo
object if the file contains “smpl” chunk, or nil if it doesn’t. If present, this will contain information about how the file can be use by a sampler, such as corresponding MIDI note, or loop points.
# File lib/wavefile/reader.rb, line 210 def sampler_info @sample_chunk end
Returns¶ ↑
Returns the total number of sample frames in the file. A sample frame contains a single sample for each channel. So if there are 1,000 sample frames in a stereo file, this means there are 1,000 left-channel samples and 1,000 right-channel samples.
# File lib/wavefile/reader.rb, line 203 def total_sample_frames @data_chunk_reader.total_sample_frames end