class WahWah::RiffTag

Constants

CHANNEL_MODE_INDEX
INFO_ID_MAPPING

see exiftool.org/TagNames/RIFF.html#Info for more info

Public Instance Methods

channel_mode() click to toggle source
# File lib/wahwah/riff_tag.rb, line 37
def channel_mode
  CHANNEL_MODE_INDEX[@channel - 1]
end

Private Instance Methods

parse() click to toggle source
# File lib/wahwah/riff_tag.rb, line 42
def parse
  top_chunk = Riff::Chunk.new(@file_io)
  return unless top_chunk.valid?

  total_chunk_size = top_chunk.size + Riff::Chunk::HEADER_SIZE

  # The top "RIFF" chunks include an additional field in the first four bytes of the data field.
  # This additional field provides the form type of the field.
  # For wav file, the value of the type field is 'WAVE'
  return unless top_chunk.id == 'RIFF' && top_chunk.type == 'WAVE'

  until total_chunk_size <= @file_io.pos || @file_io.eof? do
    sub_chunk = Riff::Chunk.new(@file_io)
    parse_sub_chunk(sub_chunk)
  end
end
parse_data_chunk(chunk) click to toggle source
# File lib/wahwah/riff_tag.rb, line 99
def parse_data_chunk(chunk)
  @duration = chunk.size * 8 / (@bitrate * 1000)
  chunk.skip
end
parse_fmt_chunk(chunk) click to toggle source

The fmt chunk data structure: Length Meaning Description

2(little endian) AudioFormat PCM = 1 (i.e. Linear quantization)

Values other than 1 indicate some
form of compression.

2(little endian) NumChannels Mono = 1, Stereo = 2, etc.

4(little endian) SampleRate 8000, 44100, etc.

4(little endian) ByteRate == SampleRate * NumChannels * BitsPerSample/8

2(little endian) BlockAlign == NumChannels * BitsPerSample/8

The number of bytes for one sample including
all channels.

2(little endian) BitsPerSample 8 bits = 8, 16 bits = 16, etc.

# File lib/wahwah/riff_tag.rb, line 94
def parse_fmt_chunk(chunk)
  _, @channel, @sample_rate, _, _, @bit_depth = chunk.data.unpack('vvVVvv')
  @bitrate = @sample_rate * @channel * @bit_depth / 1000
end
parse_id3_chunk(chunk) click to toggle source
# File lib/wahwah/riff_tag.rb, line 124
def parse_id3_chunk(chunk)
  @id3_tag = ID3::V2.new(StringIO.new(chunk.data))
end
parse_list_chunk(chunk) click to toggle source
# File lib/wahwah/riff_tag.rb, line 104
def parse_list_chunk(chunk)
  list_chunk_end_position = @file_io.pos + chunk.size

  # RIFF can be tagged with metadata in the INFO chunk.
  # And INFO chunk as a subchunk for LIST chunk.
  if chunk.type != 'INFO'
    chunk.skip
  else
    until list_chunk_end_position <= @file_io.pos do
      info_chunk = Riff::Chunk.new(@file_io)

      unless INFO_ID_MAPPING.keys.include? info_chunk.id.to_sym
        info_chunk.skip; next
      end

      update_attribute(info_chunk)
    end
  end
end
parse_sub_chunk(sub_chunk) click to toggle source
# File lib/wahwah/riff_tag.rb, line 59
def parse_sub_chunk(sub_chunk)
  return unless sub_chunk.valid?

  case sub_chunk.id
  when 'fmt'
    parse_fmt_chunk(sub_chunk)
  when 'data'
    parse_data_chunk(sub_chunk)
  when 'LIST'
    parse_list_chunk(sub_chunk)
  when 'id3', 'ID3'
    parse_id3_chunk(sub_chunk)
  else
    sub_chunk.skip
  end
end
update_attribute(chunk) click to toggle source
# File lib/wahwah/riff_tag.rb, line 128
def update_attribute(chunk)
  attr_name = INFO_ID_MAPPING[chunk.id.to_sym]
  chunk_data = Helper.encode_to_utf8(chunk.data)

  case attr_name
  when :comment
    @comments.push(chunk_data)
  else
    instance_variable_set("@#{attr_name}", chunk_data)
  end
end