lib/mp3file/mp3_header.rb in mp3file-1.1.5 vs lib/mp3file/mp3_header.rb in mp3file-1.2.0
- old
+ new
@@ -3,30 +3,30 @@
class MP3Header
attr_reader(:version, :layer, :has_crc, :bitrate,
:samplerate, :has_padding, :mode, :mode_extension,
:copyright, :original, :emphasis, :samples, :frame_size,
- :side_bytes)
+ :side_bytes, :raw)
class MP3HeaderFormat < BinData::Record
- uint8(:sync1, :value => 255, :check_value => lambda { value == 255 })
+ uint8(:sync1, asserted_value: 255)
- bit3(:sync2, :value => 7, :check_value => lambda { value == 7 })
- bit2(:version, :check_value => lambda { value != 1 })
- bit2(:layer, :check_value => lambda { value != 0 })
+ bit3(:sync2, asserted_value: 7)
+ bit2(:version, assert: -> { value != 1 })
+ bit2(:layer, assert: -> { value != 0 })
bit1(:crc)
- bit4(:bitrate, :check_value => lambda { value != 15 && value != 0 })
- bit2(:samplerate, :check_value => lambda { value != 3 })
+ bit4(:bitrate, assert: -> { value != 15 && value != 0 })
+ bit2(:samplerate, assert: -> { value != 3 })
bit1(:padding)
bit1(:private)
bit2(:mode)
bit2(:mode_extension)
bit1(:copyright)
bit1(:original)
- bit2(:emphasis, :check_value => lambda { value != 2 })
+ bit2(:emphasis, assert: -> { value != 2 })
end
MPEG_VERSIONS = [ 'MPEG 2.5', nil, 'MPEG 2', 'MPEG 1' ]
LAYERS = [ nil, 'Layer III', 'Layer II', 'Layer I' ]
BITRATES = [
@@ -76,14 +76,26 @@
head = MP3HeaderFormat.read(io)
rescue BinData::ValidityError => ve
raise InvalidMP3HeaderError, ve.message
end
+ @raw = head
@version = MPEG_VERSIONS[head.version]
@layer = LAYERS[head.layer]
@has_crc = head.crc == 0
- @bitrate = BITRATES[head.version][head.layer][head.bitrate - 1] * 1000
+
+ if @version.nil? || @layer.nil?
+ raise InvalidMP3HeaderError, "Bad MPEG version or layer."
+ end
+
+ kbitrate = BITRATES[head.version][head.layer][head.bitrate - 1]
+
+ if kbitrate.nil?
+ raise InvalidMP3HeaderError, "Bad bitrate."
+ end
+
+ @bitrate = kbitrate * 1000
@samplerate = SAMPLERATES[head.version][head.samplerate]
@has_padding = head.padding == 1
@mode = MODES[head.mode]
@mode_extension = nil
@@ -102,8 +114,22 @@
slot_size = layer == 'Layer I' ? 4 : 1
pad_slots = has_padding ? 1 : 0
@frame_size = (((samples.to_f * bitrate.to_f) / (8 * slot_size.to_f * samplerate.to_f)) + pad_slots).to_i * slot_size
@side_bytes = SIDE_BYTES[head.version][head.mode]
+ end
+
+ def to_i
+ @raw.to_binary_s
+ .reverse
+ .each_byte
+ .each_with_index
+ .inject(0) { |m, (b, i)| m += b << (i*8) }
+ end
+
+ def same_header?(other)
+ # Borrowed from ffmpeg.
+ same_header_mask = 0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)
+ (to_i & same_header_mask) == (other.to_i & same_header_mask)
end
end
end