'===========================================================================
' Subject: READ ID3 TAG FROM MP3 FILES        Date: 06-13-99 (07:52)       
'  Author: Leandro Pardini                    Code: QB, QBasic, PDS        
'  Origin: lpardini@navigo.com.ar           Packet: SOUND.ABC
'===========================================================================
'Hi there,
'
'This is a little program that reads a MP3 file and displays the
'ID3 tag in a little window. At first I was trying to do a MP3
'player, but doing that knowing nothing about the MP3 format
'except the ID3 tag (that I discovered while messing with the
'Winamp 1.9 demo file) is quite hard. If anyone out there does
'have a doc about the MP3 format (or the source for a player in C
'or any other language) please send it to me.
'
'BTW, I'm the same Leandro Pardini from last year's ABC Packets,
'but with a new address (I've got five ISPs in five months). If
'you'd wrote me to lpardini@cefex.com and didn't get any answer,
'try again at lpardini@navigo.com.ar; Cefex is down for good.
'
'Read you all!

'$STATIC
DEFINT A-Z

DECLARE SUB ShowID3Info (MP3File$)

'I use all those SHAREDs because you may want to use the
'ID3 data after the SUB ends, and passing 9 variables in
'the SUB call is quite a inconvenience.
DIM SHARED ID3Genres(148) AS STRING
DIM SHARED ID3Signature AS STRING * 3
DIM SHARED ID3Title AS STRING * 30
DIM SHARED ID3Artist AS STRING * 30
DIM SHARED ID3Album AS STRING * 30
DIM SHARED ID3Year AS STRING * 4
DIM SHARED ID3Comments AS STRING * 30
DIM SHARED ID3Genre AS INTEGER
DIM SHARED ID3GenreDesc AS STRING

FOR ReadGenres = 0 TO 148
   READ ID3Genres(ReadGenres)
NEXT ReadGenres

'This little SUB provides a nice window where the
'info is displayed.
CALL ShowID3Info("C:\PROGRA~1\WINAMP\DEMO.MP3")

'Quite big list of Genres... My fingers are
'completely destroyed after typing this...
DATA "Blues","Classic Rock","Country","Dance","Disco","Funk","Grunge"
DATA "Hip-Hop","Jazz","Metal","New Age","Oldies","Other","Pop","R&B","Rap"
DATA "Reggae","Rock","Techno","Industrial","Alternative","Ska","Death Metal"
DATA "Pranks","Soundtrack","Euro-Techno","Ambient","Trip-Hop","Vocal"
DATA "Jazz+Funk","Fusion","Trance","Classica","Instrumental","Acid","House"
DATA "Game","Sound Clip","Gospel","Noise","Alternative Rock","Bass","Soul"
DATA "Punk","Space","Meditative","Instrumental Pop","Instrumental Rock"
DATA "Ethnic","Gothic","Darkwave","Techno-Industrial","Electronic","Pop-Folk"
DATA "Eurodance","Dream","Southern Rock","Comedy","Cult","Gangsta Rap"
DATA "Top 40","Christian Rap","Pop/Funk","Jungle","Native American","Cabaret"
DATA "New Wave","Psychedelic","Rave","Showtunes","Trailer","Lo-Fi","Tribal"
DATA "Acid Punk","Acid Jazz","Polka","Retro","Musical","Rock & Roll"
DATA "Hard Rock","Folk","Folk/Rock","National Folk","Swing","Fast-Fusion"
DATA "Bebob","Latin","Revival","Celtic","Bluegrass","Avantgarde"
DATA "Gothic Rock","Progressive Rock","Psychedelic Rock","Symphonic Rock"
DATA "Slow Rock","Big Band","Chorus","Easy Listening","Acoustic","Humour"
DATA "Speech","Chanson","Opera","Chamber Music","Sonata","Symphony"
DATA "Booty Bass","Primus","Porn Groove","Satire","Slow Jam","Club","Tango"
DATA "Samba","Folklore","Ballad","Power Ballad","Rhythmic Soul","Freestyle"
DATA "Duet","Punk Rock","Drum Solo","A Cappella","Euro-House","Dance Hall"
DATA "Goa","Drum & Bass","Club-House","Hardcore","Terror","Indie","BritPop"
DATA "Negerpunk","Polsk Punk","Beat","Christian Gangsta","Rap","Heavy Metal"
DATA "Black Metal","Crossover","Contemporary Christian","Christian Rock"
DATA "Merengue","Salsa","Trash Metal","Anime","JPop","Synthpop"

SUB ShowID3Info (MP3File$)

'The ID3 info is stored in the last 128 bytes of
'a MPEG Layer-3 file; that's why I use LOF-127.
OPEN MP3File$ FOR BINARY ACCESS READ AS #1
SEEK #1, LOF(1) - 127
GET #1, , ID3Signature
GET #1, , ID3Title
GET #1, , ID3Artist
GET #1, , ID3Album
GET #1, , ID3Year
GET #1, , ID3Comments
ID3Genre = ASC(INPUT$(1, 1))
CLOSE #1

'If the first 3 letters in LOF-127 aren't "TAG",
'then the file has no ID3, and this creates a
'"All fields Unknown" tag to display. Also, it
'assigns the proper description to the Genre ID.
IF ID3Signature = "TAG" THEN
   IF ID3Genre < 149 THEN ID3GenreDesc = ID3Genres(ID3Genre) ELSE ID3GenreDesc = "Unknown"
ELSE
   ID3Title = "Unknown"
   ID3Artist = "Unknown"
   ID3Album = "Unknown"
   ID3Year = "Unk."
   ID3Comments = "Unknown"
   ID3GenreDesc = "Unknown"
END IF

'This saves the current screen in the second
'video page. If you're already using page 1
'in your program, change this to PCOPY 0, 2
'or something like that.
PCOPY 0, 1

'Change this color statement for your own program.
COLOR 7, 1
LOCATE 10, 18: PRINT " É"; STRING$(42, 205); "» ";
LOCATE 11, 18: PRINT " º    Title: "; ID3Title; " º ";
LOCATE 12, 18: PRINT " º   Artist: "; ID3Artist; " º ";
LOCATE 13, 18: PRINT " º    Album: "; ID3Album; " º ";
LOCATE 14, 18: PRINT " º     Year: "; ID3Year; STRING$(19 - LEN(ID3GenreDesc), 32); "Genre: "; ID3GenreDesc; " º ";
LOCATE 15, 18: PRINT " º Comments: "; ID3Comments; " º ";
LOCATE 16, 18: PRINT " È"; STRING$(42, 205); "¼ ";
COLOR 1, 7
Info$ = " ID3 tag for " + MP3File$ + " "
LOCATE 10, 40 - (LEN(Info$) \ 2)
PRINT Info$;

'This waits for a keypress and then restores the
'original screen from the second video page.
WHILE INKEY$ = "": WEND
PCOPY 1, 0

END SUB
