# File lib/mp3info.rb, line 107 def initialize(filename) raise Mp3InfoError, "empty file" unless File.stat(filename).size? #FIXME @vbr = false @file = File.open(filename) begin a = find_frame_sync b, c = @file.read(4).unpack("C2") mpeg_version = (a >> 3) & 3 @mpeg_version = MPEG_VERSION[mpeg_version] raise Mp3InfoInternalError if @mpeg_version.nil? layer = (a >> 1) & 3 @layer = LAYER[layer] raise Mp3InfoInternalError if @layer.nil? @error_protection = a & 1 == 1 ? true : false bitrate = b >> 4 @bitrate = BITRATE[@mpeg_version-1][@layer-1][bitrate-1] or raise Mp3InfoInternalError samplerate = (b >> 2) & 3 @samplerate = SAMPLERATE[@mpeg_version-1][samplerate] or raise Mp3InfoInternalError # @padding_bit = (b >> 1) & 1 channel_mode = c >> 6 @channel_mode = CHANNEL_MODE[channel_mode] seek = if mpeg_version == 3 # mpeg version 1 if channel_mode == 3 15 # Single Channel else 30 end else # mpeg version 2 or 2.5 if channel_mode == 3 # Single Channel 7 else 15 end end @file.seek(seek, File::SEEK_CUR) if @file.read(4) == "Xing" # This is a VBR file @vbr = true @file.seek(4, File::SEEK_CUR) #we have the frames number after #if @file.read(4).unpack("N")[0] == 0xF #end @frames = @file.read(4).unpack("N")[0] medframe = @file.stat.size / @frames.to_f @bitrate = ( (medframe * @samplerate) / ( 1000 * ( layer==3 ? 12 : 144) ) ).to_i end @length = (( (8 * @file.stat.size) / 1000) / @bitrate).to_i rescue Mp3InfoInternalError retry ensure @file.close end end