# File lib/mp3info.rb, line 547 def to_s "id3v1: \#{hastag1? && @tag1.inspect} id3v2: \#{hastag2? && @tag2.inspect} MPEG \#{@mpeg_version} Layer \#{@layer} \#{@vbr ? \"VBR\" : \"CBR\"} \#{@bitrate} Kbps \\\n\#{@channel_mode} \#{@samplerate} Hz length \#{@length} sec. \\\nerror protection \#{@error_protection}\nEOF\n end\n\nprivate\n def gettag1\n h = {}\n return h if @file.stat.size < TAGSIZE\n @file.seek(-TAGSIZE, File::SEEK_END)\n if @file.read(3) == \"TAG\"\n \#read id3v1.0 tag\n \#@tag1[\"version\"] = \"0\"\n h[\"title\"],\n h[\"artist\"],\n h[\"album\"],\n year_s,\n h[\"comments\"],\n h[\"genre\"] = @file.read(TAGSIZE - 3).unpack('A30A30A30A4A30C')\# accept zero/space padded input\n \#read id3v1.1 tag\n if h[\"comments\"][28] == 0\n \#@tag1[\"version\"] = \"1\"\n h[\"tracknum\"] = h[\"comments\"][29].to_i\n end\n [\"title\", \"artist\", \"album\", \"comments\"].each { |key| h[key].sub!(/\\0.*$/, '') }\n year_s.sub!(/\\0.*$/, '')\n h[\"year\"] = year_s.to_i\n end\n h\n end\n\n \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n \# compute size of 4 bytes\n \# with unsync method\n \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n def size_syncsafe(bytes)\n c = bytes.unpack(\"C4\")\n c[0]*(0x80**3) +\n c[1]*(0x80**2) +\n c[2]*0x80 +\n c[3]\n end\n\n def find_frame_sync\n pos = @file.pos\n 65536.times do |i|\n @file.pos = pos+i\n str = @file.read(2)\n raise Mp3InfoError if str.nil?\n if str.unpack(\"B11\")[0] == \"1\"*11\n @file.pos = pos+i\n return\n end\n end\n raise Mp3InfoError\n end\n\n def check_head(h)\n head = h.unpack(\"N\")[0]\n return false if head & 0xffe00000 != 0xffe00000\n return false if (head >> 17) & 3 == 0\n return false if (head >> 12) & 0xf == 0xf\n return false if (head >> 10) & 0x3 == 0x3\n return false if (head & 0xffff0000) == 0xfffe0000\n bitrate_index = ((head>>12)&0xf)\n lay = 4-((head>>17)&3)\n return false if lay != 3\n return false if bitrate_index == 0 \#free format bitstream\n true\n end\n\n def extract_infos_from_head(head)\n h = {}\n dummy, a, b, c = head.unpack(\"C4\")\n h[:mpeg_version] = 2 - ((a >> 3) & 1)\n lay = (a >> 1) & 3\n h[:layer] = LAYER[lay]\n raise Mp3InfoInternalError if h[:layer].nil?\n h[:error_protection] = a & 1 == 1\n bitrate = b >> 4\n h[:bitrate] = BITRATE[h[:mpeg_version]-1][h[:layer]-1][bitrate-1] || raise(Mp3InfoInternalError, message)\n srate = (b >> 2) & 3\n h[:samplerate] = SAMPLERATE[h[:mpeg_version]-1][srate] || raise(Mp3InfoInternalError, message)\n h[:padding] = (b >> 1) & 1\n h[:channel_num] = c >> 6 & 3\n h[:channel_mode] = CHANNEL_MODE[h[:channel_num]]\n factor = (h[:layer] == 1 ? 48000 : 144000)/h[:mpeg_version]\n h[:size] = (factor*h[:bitrate])/h[:samplerate] + h[:padding]\n h\n end\nend\n\nif $0 == __FILE__\n while filename = ARGV.shift\n begin\n info = Mp3Info.new(filename)\n puts filename\n \#puts \"MPEG \#{info.mpeg_version} Layer \#{info.layer} \#{info.vbr ? \"VBR\" : \"CBR\"} \#{info.bitrate} Kbps \\\n \#{info.channel_mode} \#{info.samplerate} Hz length \#{info.length} sec.\"\n puts info\n rescue Mp3InfoError => e\n puts \"\#{filename}\\nERROR: \#{e}\"\n end\n puts\n end\nend\n"