def parse_wave_header(file)
format_tag = nil
channels = nil
samples_per_sec = nil
avg_bytes_per_sec = nil
block_align = nil
bits_per_sample = nil
is_wav = false
data_length = 0
file_length = file.read(4).unpack('N').first
raise "Corrupt wave" if file.read(4).unpack('N').first != WAV_ID_WAVE
20.times {
type = file.read(4).unpack('N').first
case type
when WAV_ID_FMT
sub_size = file.read(4).unpack('V').first
raise "Corrupt wave" if sub_size < 16
( format_tag,
channels,
samples_per_sec,
avg_bytes_per_sec,
block_align, bits_per_sample) = *(file.read(16).unpack('vvVVvv'))
sub_size -= 16
file.read(sub_size) if sub_size > 0
when WAV_ID_DATA
sub_size = file.read(4).unpack('V').first
data_length = sub_size
is_wav = true
break;
else
sub_size = file.read(4).unpack('V').first
file.read(sub_size)
end
}
raise "Unsupported format" unless format_tag == 1
raise unless is_wav
{
:num_channels => channels,
:in_samplerate => samples_per_sec,
:bytes_in_seconds => data_length,
:milliseconds => (data_length/2)/(samples_per_sec/1000)/2,
:num_samples => data_length / (channels*((bits_per_sample+7)/8)),
:bit_width => bits_per_sample,
}
end