class WahWah::Mp3::MpegFrameHeader

mpeg frame header structure:

Position Length Meaning 0 11 Frame sync to find the header (all bits are always set)

11 2 Audio version ID

00 - MPEG Version 2.5 (unofficial extension of MPEG 2)
01 - reserved
10 - MPEG Version 2 (ISO/IEC 13818-3)
11 - MPEG Version 1 (ISO/IEC 11172-3)

13 2 Layer index

00 - reserved
01 - Layer III
10 - Layer II
11 - Layer I

15 1 Protection bit

16 4 Bitrate index, see FRAME_BITRATE_INDEX constant

20 2 Sampling rate index, see SAMPLE_RATE_INDEX constant

22 1 Padding bit

23 1 Private bit

24 2 Channel mode

00 - Stereo
01 - Joint Stereo (Stereo)
10 - Dual channel (Two mono channels)
11 - Single channel (Mono)

26 2 Mode extension (Only used in Joint Stereo)

28 1 Copyright bit (only informative)

29 1 Original bit (only informative)

30 2 Emphasis

Constants

CHANNEL_MODE_INDEX
FRAME_BITRATE_INDEX
HEADER_SIZE
LAYER_INDEX
SAMPLES_PER_FRAME_INDEX
SAMPLE_RATE_INDEX
VERSIONS_INDEX

Attributes

channel_mode[R]
frame_bitrate[R]
layer[R]
sample_rate[R]
version[R]

Public Class Methods

new(file_io, offset = 0) click to toggle source
# File lib/wahwah/mp3/mpeg_frame_header.rb, line 88
def initialize(file_io, offset = 0)
  # mpeg frame header start with '11111111111' sync bits,
  # So look through file until find it.
  loop do
    file_io.rewind
    file_io.seek(offset)

    break if file_io.eof?

    header = file_io.read(HEADER_SIZE)
    sync_bits = header.unpack('B11').first

    if sync_bits == "#{'1' * 11}".b
      @header = header.unpack('B*').first
      @position = offset

      parse; break
    end

    offset += 1
  end
end

Public Instance Methods

kind() click to toggle source
# File lib/wahwah/mp3/mpeg_frame_header.rb, line 120
def kind
  return if @version.nil? && @layer.nil?
  "#{@version} #{@layer}"
end
position() click to toggle source
# File lib/wahwah/mp3/mpeg_frame_header.rb, line 115
def position
  return 0 unless valid?
  @position
end
samples_per_frame() click to toggle source
# File lib/wahwah/mp3/mpeg_frame_header.rb, line 125
def samples_per_frame
  SAMPLES_PER_FRAME_INDEX[kind]
end
valid?() click to toggle source
# File lib/wahwah/mp3/mpeg_frame_header.rb, line 111
def valid?
  !@header.nil?
end

Private Instance Methods

parse() click to toggle source
# File lib/wahwah/mp3/mpeg_frame_header.rb, line 130
def parse
  return unless valid?

  @version = VERSIONS_INDEX[@header[11..12].to_i(2)]
  @layer = LAYER_INDEX[@header[13..14].to_i(2)]
  @frame_bitrate = FRAME_BITRATE_INDEX[kind]&.fetch(@header[16..19].to_i(2))
  @channel_mode = CHANNEL_MODE_INDEX[@header[24..25].to_i(2)]
  @sample_rate = SAMPLE_RATE_INDEX[@version]&.fetch(@header[20..21].to_i(2))
end