1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329:
| type TID3Tag = record ID: string[3]; Titel: string[30]; Artist: string[30]; Album: string[30]; Year: string[4]; Comment: string[30]; Genre: byte; end; TmpegHeader =record position:integer; version:integer; layer:integer; protection:boolean; bitrate:integer; samplerate:integer; channelmode:byte; extension:byte; copyright:boolean; original:boolean; frames:longint; dauer:longint; vbr:boolean; end;
const MPEG_BIT_RATES : array[1..3] of array[1..3] of array[0..15] of word = (((0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0), (0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,0), (0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,0)), ((0,32,48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0), (0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0), (0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0)), ((0,32,48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0), (0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0), (0, 8,16,24, 32, 40, 48, 56, 64, 80, 96, 112,128,144,160,0)));
sample_rates: array[1..3] of array [0..3] of word= ((44100,48000,32000,0), (22050,24000,16000,0), (11025,12000,8000,0)); channel_modes:array[0..3] of string=('Stereo','Joint stereo','Dual channel (Stereo)','Single channel (Mono)'); extensions:array[1..3] of array [0..3] of string= (('bands 4 to 31','bands 8 to 32','bands 12 to 31','bands 16 to 31'), ('bands 4 to 31','bands 8 to 32','bands 12 to 31','bands 16 to 31'), ('IS:off, MS:off','IS:on, MS:off','IS:off, MS:on','IS:on, MS:on'));
procedure Tform1.mp3Info(filename:string; var mpegheader:Tmpegheader; var id3v2_artist,id3v2_titel,id3v2_album:string; var id3tag:Tid3tag);
var F: File; id3v1_tag:array[1..128] of char; mp3_header: array[1..4] of char; buffer:array[0..5999] of char; bytes:longint; i:integer;
id3v1_size:integer; xing_header_size:integer; id3_version, id3_number,id3_flags:byte; id3_unsync,id3_extended,id3_footer:boolean; id3_frame_id:string[4]; id3_pos:integer; id3_size,id3_extended_size,id3_frame_size:longint;
bitrateindex, versionindex: byte; erfolg,valid:boolean; position:integer; padding,samplerateindex:byte; framelength:longint; Xing_Offset:integer; Xing_Flags:byte;
begin AssignFile(F, filename); FileMode := 0; Reset(F,1); bytes:=filesize(f); blockread(f,buffer,6000); Seek(F,FileSize(F)-128); BlockRead(F, id3v1_tag, 128); CloseFile(F); position:=-1;
if (id3v1_tag[1]='T') AND (id3v1_tag[2]='A') AND (id3v1_tag[3]='G') then begin id3tag.id:='TAG'; id3v1_size:=128; id3tag.Titel:=trim(copy(id3v1_tag,4,30)); id3tag.Artist:=trim(copy(id3v1_tag,34,30)); id3tag.Album:=trim(copy(id3v1_tag,64,30)); id3tag.Year:=trim(copy(id3v1_tag,94,4)); id3tag.Comment:=trim(copy(id3v1_tag,98,30)); id3tag.Genre:=ord(id3v1_tag[128]); end else id3v1_size:=0;
if (buffer[0]='I') AND (buffer[1]='D') AND (buffer[2]='3') then begin id3_version:=ord(buffer[3]); id3_number:=ord(buffer[4]); id3_flags:=ord(buffer[5]); id3_unsync:=((id3_flags shr 7) AND 1)=1; id3_extended:=((id3_flags shr 6) AND 1)=1; id3_footer:=((id3_flags shr 4) AND 1)=1; id3_size:=2097152*ord(buffer[6]) + 16384*ord(buffer[7]) + 128*ord(buffer[8]) + ord(buffer[9])+10; if id3_footer then inc(id3_size,10); position:=id3_size-1; if id3_extended then begin id3_extended_size:=2097152*ord(buffer[10]) + 16384*ord(buffer[11]) + 128*ord(buffer[12]) + ord(buffer[13]); end else id3_extended_size:=0; id3_pos:=10+id3_extended_size; while (id3_pos<position) do begin id3_frame_id:=buffer[id3_pos] +buffer[id3_pos+1] +buffer[id3_pos+2] +buffer[id3_pos+3]; id3_frame_size:=2097152*ord(buffer[id3_pos+4]) + 16384*ord(buffer[id3_pos+5]) + 128*ord(buffer[id3_pos+6]) + ord(buffer[id3_pos+7])+10; if id3_frame_id='TALB' then begin if id3_frame_size>11 then setlength(id3v2_album,id3_frame_size-11); for i:=id3_pos+11 to id3_pos+id3_frame_size do id3v2_album[i-id3_pos-10]:=buffer[i]; end; if id3_frame_id='TIT2' then begin if id3_frame_size>11 then setlength(id3v2_titel,id3_frame_size-11); for i:=id3_pos+11 to id3_pos+id3_frame_size do id3v2_titel[i-id3_pos-10]:=buffer[i]; end; if id3_frame_id='TPE1' then begin if id3_frame_size>11 then setlength(id3v2_artist,id3_frame_size-11); for i:=id3_pos+11 to id3_pos+id3_frame_size do id3v2_artist[i-id3_pos-10]:=buffer[i]; end; inc(id3_pos,id3_frame_size); end; end else id3_size:=0;
erfolg:=false; mpegheader.position:=-1; position:=id3_size-1; while NOT ((erfolg) or (position>5800)) do begin inc(position); if (ord(buffer[position])=$FF) AND (ord(buffer[position+1])>=$E0) then begin valid:=true; Versionindex:=((ord(buffer[position+1]) shr 3) and 3); case versionindex of 0: mpegheader.version:=3; 1: mpegheader.version:=0; 2: mpegheader.version:=2; 3: mpegheader.version:=1; end; mpegheader.Layer:=4-((ord(buffer[position+1]) shr 1) and 3); mpegheader.protection:=((ord(buffer[position+1]) AND 1)=0);
bitrateindex:=((ord(buffer[position+2]) shr 4) AND $F); mpegheader.bitrate:=MPEG_BIT_RATES[mpegheader.version][mpegheader.layer][bitrateindex]; if bitrateindex=$F then valid:=false; samplerateindex:=((ord(buffer[position+2]) shr 2) AND 3); mpegheader.samplerate:=sample_rates[mpegheader.version][samplerateindex]; padding:=((ord(buffer[position+2]) shr 1) AND 1);
mpegheader.channelmode:=((ord(buffer[position+3]) shr 6) AND 3); mpegheader.extension:=((ord(buffer[position+3]) shr 4) AND 3); mpegheader.copyright:=((ord(buffer[position+3]) shr 3) AND 1)=1; mpegheader.original:=((ord(buffer[position+3]) shr 2) AND 1)=1;
if mpegheader.version=1 then if mpegheader.channelmode<>3 then xing_offset:=32+4 else xing_offset:=17+4 else if mpegheader.channelmode<>3 then xing_offset:=17+4 else xing_offset:=9+4; if (buffer[position+xing_offset]='X') AND (buffer[position+xing_offset+1]='i') AND (buffer[position+xing_offset+2]='n') AND (buffer[position+xing_offset+3]='g') then begin Xing_flags:=ord(buffer[position+xing_offset+7]); if (Xing_flags AND 1)=1 then begin mpegheader.frames:=16777216*ord(buffer[position+xing_offset+8]) + 65536*ord(buffer[position+xing_offset+9]) + 256*ord(buffer[position+xing_offset+10]) + ord(buffer[position+xing_offset+11]); end; xing_header_size:=trunc(144*(MPEG_BIT_RATES[mpegheader.version][mpegheader.layer][bitrateindex]*1000/mpegheader.samplerate)+padding); mpegheader.bitrate:=trunc((mpegheader.samplerate/1000*(bytes-id3_size-id3v1_size-xing_header_size))/(mpegheader.frames*144)); mpegheader.vbr:=true; end else begin framelength:=trunc(144*(MPEG_BIT_RATES[mpegheader.version][mpegheader.layer][bitrateindex]*1000/mpegheader.samplerate)+padding); mpegheader.frames:=trunc((bytes-id3_size-id3v1_size-xing_header_size)/framelength); mpegheader.vbr:=false; xing_header_size:=0; end;
framelength:=trunc(144*(MPEG_BIT_RATES[mpegheader.version][mpegheader.layer][bitrateindex]*1000/mpegheader.samplerate)+padding); if position+framelength>length(buffer)-2 then begin Reset(F,1); Seek(F,position+framelength); blockread(f,mp3_header,4); CloseFile(F); end else begin mp3_header[1]:=buffer[position+framelength]; mp3_header[2]:=buffer[position+framelength+1]; end; if (ord(mp3_header[1])<>$FF) or (ord(mp3_header[2])<$E0) then valid:=false; if valid then begin erfolg:=true; mpegheader.dauer:=((bytes-id3_size-id3v1_size-xing_header_size)*8) div ((mpegheader.bitrate)*1000); mpegheader.position:=position; end; end; end; end; |