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
# 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

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



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

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

#positionObject



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

def position
  return 0 unless valid?
  @position
end

#samples_per_frameObject



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

def samples_per_frame
  SAMPLES_PER_FRAME_INDEX[kind]
end

#valid?Boolean

Returns:

  • (Boolean)


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

def valid?
  !@header.nil?
end