Closed arjunmenon closed 6 years ago
Thanks for the question - after looking at the gist, I think I might see the problem.
It seems like the gist relies on having the sample data for the entire file in the sample_data
array. Older versions of the WaveFile gem read the entire file into memory, which meant that the sample_data
field would contain the file's entire sample data. However, more recent versions instead allow reading a *.wav file in a buffered way. Calling each_buffer
will normally only return a portion of the file's sample data at a time.
If you want to read the entire file with the current version of the WaveFile gem, you could do:
all_samples_in_file = reader.read(reader.total_sample_frames)
Or:
reader.each_buffer(reader.total_sample_frames) do |buffer|
# `buffer` will contain all samples in the file
end
Hope this helps!
Ok, so if I omit reader.total_sample_frames
does that mean we can use it for continuous stream, like from a mic or from a streaming source?
In theory I think it should be possible to read sample data from a .wav file in a streaming way, using Reader.read
, if you construct it with the relevant IO
instance. However, this will only work if the sample data being read from the IO
instance is wrapped in a `.wav` file. If the stream only contains raw sample data, then the WaveFile gem won't know how to read it.
Raw sample data coming from a microphone will probably not be wrapped inside a *.wav file.
If you're trying to get sample data in real time from a microphone or other sound source, you might want to look into something like a PortAudio wrapper gem for Ruby, such as https://rubygems.org/gems/ffi-portaudio or https://rubygems.org/gems/easy_audio. I haven't used these myself, but I found them from searching on rubygems.org.
Here's an example of how to read a *.wav file from a stream using the WaveFile gem, adapted from the example at http://wavefilegem.com/examples.html:
SAMPLES_PER_BUFFER = 4096
streaming_io = <construct IO instance here>
reader = Reader.new(streaming_io)
begin
while true do
buffer = reader.read(SAMPLES_PER_BUFFER)
puts "Read #{buffer.samples.length} samples."
end
rescue EOFError
reader.close
end
Hope this helps!
Closing this issue, hope this helped!
Hey I found a small gist to get fft values of sound files. It used these methods,
samples = w.sample_data[0, [w.sample_rate * 10, w.sample_data.size].min]
Now, the
sample_data
was available in the very first release of this gem.What is the equivalent newer version to these methods.
Simple generating
returns different result