/****************************************************/
/* */
/* C-Library zum Auslesen von ID3v1-TAGs */
/* */
/* Version: 2.0.0.0. */
/* Autor: tgc_md */
/* Copyright: tgc_md */
/* Datum: 12.12.2002 */
/* Mail: coding@tool-garage.de */
/* */
/****************************************************/
/*********** Includes ***********/
#ifndef ID3
#define ID3
# include "ID3v1.h"
#endif
/*********** Defines ***********/
const int TAG = -128;
const int TITLE = -125;
const int ARTIST = -95;
const int ALBUM = -65;
const int YEAR = -35;
const int COMMENT = -31;
const int TRACK = -2;
const int GENRE = -1;
/*********** Globals ***********/
char *Genres[148] = { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age",
"Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks",
"Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid",
"House", "Game", "Sound Clip", "Gospel", "Noise", "Alternative Rock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop",
"Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock",
"Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native US", "Cabaret", "New Wave", "Psychadelic", "Rave",
"Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk",
"Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock",
"Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour",
"Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club",
"Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhytmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "Acapella",
"Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk",
"Beat", "Christian Gangsta", "Heavy Metal", "Black Metal", "Crossover", "Contemporary C", "Christian Rock", "Merengue", "Salsa",
"Thrash Metal", "Anime", "JPop", "SynthPop" };
/*********** Functions ***********/
int checkID3v1(char *path)
{
FILE *fp;
char *tag = (char *) calloc(1, 4);
if(fp = fopen( path, "rb"))
{
fseek(fp, TAG, SEEK_END);
fread(tag, 3, 1, fp);
fclose(fp);
if(!strcmp(tag, "TAG"))
return 0;
else
return 1;
}
return 2;
}
/*---------------------------------------------*/
/************************************/
/* Ermittelt ID3Tag-Version */
/* RETURN-VALUES: */
/* 1 => kein TAG */
/* 2 => Datei nicht gefunden */
/* 10 => ID3Tagv1.0 */
/* 11 => ID3Tagv1.1 */
/************************************/
int checkVersion(char *path)
{
FILE *fp2;
char byte28, byte29;
int i = checkID3v1(path);
if(i == 0) /* TAG valid */
{
if(fp2 = fopen( path, "rb"))
{
fseek(fp2, TRACK-1, SEEK_END);
fread(&byte28, 1, 1, fp2);
fread(&byte29, 1, 1, fp2);
fclose(fp2);
if( byte28=='\0' && byte29!='\0') /* 28.Byte = 0 und 29.Byte nicht 0 => 29.Byte enth�lt Tracknummer ==> ID3v1.1 */
return 11;
else
return 10;
}
}
return i;
}
/*---------------------------------------------*/
int removeTag(char *path)
{
FILE *fp;
int i = checkID3v1(path);
if(i == 0) /* TAG exists */
{
if(fp = fopen(path, "r+b"))
{
if( !chsize(fileno(fp), filelength( fileno(fp) ) - 128) )
{
fclose(fp);
return 0; /* TAG entfernt */
}
}
}
if(i == 1) return 0; /* had no TAG */
return 1; /* file not found */
}
/*---------------------------------------------*/
char *getTitle(char *path)
{
FILE *fp;
char *title = (char *) calloc(1, 31);
int i = checkID3v1(path);
if(i == 0)
{
if(fp = fopen(path, "rb"))
{
fseek(fp, TITLE, SEEK_END);
fread(title, 30, 1, fp);
fclose(fp);
return title;
}
}
if(i == 1)
return "noTAG";
return "FileNotFound";
}
/*---------------------------------------------*/
int setTitle(char *path, char *newTitle)
{
FILE *fp;
int i = checkID3v1(path);
/* TAG existiert schon */
if(i == 0)
{
if(fp = fopen(path, "r+b"))
{
fseek(fp, TITLE, SEEK_END);
if( fwrite(newTitle, 30, 1, fp) )
{
fclose(fp);
return 0;
}
else
{
fclose(fp);
return 1;
}
}
}
/* TAG existiert noch nicht */
if(i == 1)
{
if(fp = fopen(path, "r+b"))
{
chsize( fileno(fp), filelength( fileno(fp) ) + 128 );
fseek(fp, TAG, SEEK_END);
fwrite("TAG", 3, 1, fp);
fseek(fp, TITLE, SEEK_END);
if( fwrite(newTitle, 30, 1, fp) )
{
fclose(fp);
return 0;
}
else
{
fclose(fp);
return 1;
}
}
}
return 2;
}
/*---------------------------------------------*/
char *getArtist(char *path)
{
FILE *fp;
char *artist = (char *) calloc(1, 31);
int i = checkID3v1(path);
if(i == 0)
{
if(fp = fopen(path, "rb"))
{
fseek(fp, ARTIST, SEEK_END);
fread(artist, 30, 1, fp);
fclose(fp);
return artist;
}
}
if(i == 1)
return "noTAG";
return "FileNotFound";
}
/*---------------------------------------------*/
int setArtist(char *path, char *newArtist)
{
FILE *fp;
int i = checkID3v1(path);
/* TAG existiert schon */
if(i == 0)
{
if(fp = fopen(path, "r+b"))
{
fseek(fp, ARTIST, SEEK_END);
if( fwrite(newArtist, 30, 1, fp) )
{
fclose(fp);
return 0;
}
else
{
fclose(fp);
return 1;
}
}
}
/* TAG existiert noch nicht */
if(i == 1)
{
if(fp = fopen(path, "r+b"))
{
chsize( fileno(fp), filelength( fileno(fp) ) + 128 );
fseek(fp, TAG, SEEK_END);
fwrite("TAG", 3, 1, fp);
fseek(fp, ARTIST, SEEK_END);
if( fwrite(newArtist, 30, 1, fp) )
{
fclose(fp);
return 0;
}
else
{
fclose(fp);
return 1;
}
}
}
return 2;
}
/*---------------------------------------------*/
char *getAlbum(char *path)
{
FILE *fp;
char *album = (char *) calloc(1, 31);
int i = checkID3v1(path);
if(i == 0)
{
if(fp = fopen(path, "rb"))
{
fseek(fp, ALBUM, SEEK_END);
fread(album, 30, 1, fp);
fclose(fp)