Skip to content

Commit

Permalink
More improvements on WAV parser
Browse files Browse the repository at this point in the history
  • Loading branch information
linkyndy committed Jul 10, 2024
1 parent b71b6f6 commit f7ec5ad
Showing 1 changed file with 8 additions and 11 deletions.
19 changes: 8 additions & 11 deletions lib/parsers/wav_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,27 @@ def call(io)
# The specification does not require the Format chunk to be the first chunk
# after the RIFF header.
# https://www.mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
fmt_processed = false
data_processed = false
fmt_data = {}
data_size = 0
total_sample_frames = nil
loop do
chunk_type, chunk_size = safe_read(io, 8).unpack('a4l')
case chunk_type
when 'fmt ' # watch out: the chunk ID of the format chunk ends with a space
fmt_data = unpack_fmt_chunk(io, chunk_size)
fmt_processed = true
when 'data'
data_size = chunk_size
when 'fact'
total_sample_frames = safe_read(io, 4).unpack('l').first
safe_skip(io, chunk_size - 4)
data_processed = true
else
# Skip this chunk until a known chunk is encountered
safe_skip(io, chunk_size)
end
rescue FormatParser::IOUtils::InvalidRead
# We've reached EOF, so it's time to make the most out of the metadata we
# managed to parse
break
break if fmt_processed && data_processed
end

file_info(fmt_data, data_size, total_sample_frames)
file_info(fmt_data, data_size)
end

def unpack_fmt_chunk(io, chunk_size)
Expand All @@ -70,9 +67,9 @@ def unpack_fmt_chunk(io, chunk_size)
}
end

def file_info(fmt_data, data_size, sample_frames)
def file_info(fmt_data, data_size)
# NOTE: Each sample includes information for each channel
sample_frames ||= data_size / (fmt_data[:channels] * fmt_data[:bits_per_sample] / 8) if fmt_data[:channels] > 0 && fmt_data[:bits_per_sample] > 0
sample_frames = data_size / (fmt_data[:channels] * fmt_data[:bits_per_sample] / 8) if fmt_data[:channels] > 0 && fmt_data[:bits_per_sample] > 0
duration_in_seconds = sample_frames / fmt_data[:sample_rate].to_f if fmt_data[:sample_rate] > 0
FormatParser::Audio.new(
format: :wav,
Expand Down

0 comments on commit f7ec5ad

Please sign in to comment.