Class: WahWah::Mp3::MpegFrameHeader

Inherits:
Object
  • Object
show all
Defined in:
lib/wahwah/mp3/mpeg_frame_header.rb

Overview

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

Constant Summary collapse

HEADER_SIZE =
4
FRAME_BITRATE_INDEX =
{
  "MPEG1 layer1" => [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0],
  "MPEG1 layer2" => [0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0],
  "MPEG1 layer3" => [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0],

  "MPEG2 layer1" => [0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0],
  "MPEG2 layer2" => [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0],
  "MPEG2 layer3" => [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0],

  "MPEG2.5 layer1" => [0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0],
  "MPEG2.5 layer2" => [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0],
  "MPEG2.5 layer3" => [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0]
}
VERSIONS_INDEX =
["MPEG2.5", nil, "MPEG2", "MPEG1"]
LAYER_INDEX =
[nil, "layer3", "layer2", "layer1"]
CHANNEL_MODE_INDEX =
["Stereo", "Joint Stereo", "Dual Channel", "Single Channel"]
SAMPLE_RATE_INDEX =
{
  "MPEG1" => [44100, 48000, 32000],
  "MPEG2" => [22050, 24000, 16000],
  "MPEG2.5" => [11025, 12000, 8000]
}
SAMPLES_PER_FRAME_INDEX =
{
  "MPEG1 layer1" => 384,
  "MPEG1 layer2" => 1152,
  "MPEG1 layer3" => 1152,

  "MPEG2 layer1" => 384,
  "MPEG2 layer2" => 1152,
  "MPEG2 layer3" => 576,

  "MPEG2.5 layer1" => 384,
  "MPEG2.5 layer2" => 1152,
  "MPEG2.5 layer3" => 576
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_io, offset = 0) ⇒ MpegFrameHeader

Returns a new instance of MpegFrameHeader.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# 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.unpack1("B11")

    if sync_bits == ("1" * 11).b
      @header = header.unpack1("B*")
      @position = offset

      parse
      break
    end

    offset += 1
  end
end

Instance Attribute Details

#channel_modeObject (readonly)

Returns the value of attribute channel_mode.



86
87
88
# File 'lib/wahwah/mp3/mpeg_frame_header.rb', line 86

def channel_mode
  @channel_mode
end

#frame_bitrateObject (readonly)

Returns the value of attribute frame_bitrate.



86
87
88
# File 'lib/wahwah/mp3/mpeg_frame_header.rb', line 86

def frame_bitrate
  @frame_bitrate
end

#layerObject (readonly)

Returns the value of attribute layer.



86
87
88
# File 'lib/wahwah/mp3/mpeg_frame_header.rb', line 86

def layer
  @layer
end

#sample_rateObject (readonly)

Returns the value of attribute sample_rate.



86
87
88
# File 'lib/wahwah/mp3/mpeg_frame_header.rb', line 86

def sample_rate
  @sample_rate
end

#versionObject (readonly)

Returns the value of attribute version.



86
87
88
# File 'lib/wahwah/mp3/mpeg_frame_header.rb', line 86

def version
  @version
end

Instance Method Details

#kindObject



121
122
123
124
# File 'lib/wahwah/mp3/mpeg_frame_header.rb', line 121

def kind
  return if @version.nil? && @layer.nil?
  "#{@version} #{@layer}"
end

#positionObject



116
117
118
119
# File 'lib/wahwah/mp3/mpeg_frame_header.rb', line 116

def position
  return 0 unless valid?
  @position
end

#samples_per_frameObject



126
127
128
# File 'lib/wahwah/mp3/mpeg_frame_header.rb', line 126

def samples_per_frame
  SAMPLES_PER_FRAME_INDEX[kind]
end

#valid?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/wahwah/mp3/mpeg_frame_header.rb', line 112

def valid?
  !@header.nil?
end