ich hab mal vor ein paar Wochen mir eine id3tag Klasse zum auslesen der Tags gebaut v1 und v2.
Der Sourcecode ist zwar nicht der beste, aber besser als nix.
Zwei Sachen gefallen mir noch nicht:
1. Wenn ein Attribute gezipped ist, wird es nicht richtig angezeigt (da hab ich dann aufgehört) - sprich der ausgelesen Text ist nicht lesbar
2. Um die Bitrate zu lesen, habe ich mir den Code von einem anderen Thread hier im Forum geholt. Hier wird die Datei dann noch mal geöffnet und diesmal mit C-Funktionen ausgelesen. Das müsste noch auf C++ umgestellt werden um sauber zu sein...
Wenn jemand lust hat, kann er ja noch die angesprochenen Punkte verbessern und hier wieder posten
Ist vielleicht was fürs FAQ, da ja schon öfters nach id3tag Klassen gefragt wurde.
//////////////////////////////////////////////////////////////////////////
// read now the next frame
// reset the memory
memset(frameName, 5, 0);
// read from file, if we are not at the end if (file.tellg() < ((int) fileSize) - 4) {
file.read(frameName, 4) ;
}
}
}
catch (std::exception)
{
file.close();
return false;
}
// finding first frame for MPEG 1 LAYER III bool flag = false;
do {
if ((curch = fgetc(file)) == EOF)
return false;
if (curch == 255)
{
if ((curch = fgetc(file)) == EOF)
return false;
if (tolower(curch/16) == 15)
flag = true;
}
} while(!flag);
// version check MPEG 1/2... int impegversion=tolower(((curch%16)/4)/2);
if(impegversion==1)
m_strMpegVersion = "MPEG 1";
else if (impegversion==0)
m_strMpegVersion = "MPEG 2";
// layer check.... int layer = tolower((((curch%16)/4)%2)*2+(((curch%16)%4)/2));
switch (layer)
{
case 0:
m_strMpegLayer = "Reserved";
break;
case 1:
m_strMpegLayer = "Layer III";
break;
case 2:
m_strMpegLayer = "Layer II";
break;
case 3:
m_strMpegLayer = "Layer I";
break;
}
//get next byte to read 3rd byte of header. if ((curch = fgetc(file)) == EOF)
return false;
std::string CMp3TagInfo::GetMp3Genre(std::string number)
{
// is the genre for example (09) than we have to resolve the number if (number.length() != 4)
return number;
if ((number[0] != '(') || (number[3] != ')'))
return number;
number = number.substr(1, number.length() - 2);
int i = atoi(number.c_str());
return GetMp3Genre(i);
}
std::string CMp3TagInfo::GetMp3Genre(int number)
{
switch(number)
{
case 0: return "Blues";
case 1: return "Classic Rock";
case 2: return "Country";
case 3: return "Dance";
case 4: return "Disco";
case 5: return "Funk";
case 6: return "Grunge";
case 7: return "Hip-Hop";
case 8: return "Jazz";
case 9: return "Metal";
case 10: return "New Age";
case 11: return "Oldies";
case 12: return "Other";
case 13: return "Pop";
case 14: return "R&B";
case 15: return "Rap";
case 16: return "Reggae";
case 17: return "Rock";
case 18: return "Techno";
case 19: return "Industrial";
case 20: return "Alternative";
case 21: return "Ska";
case 22: return "Death Metal";
case 23: return "Pranks";
case 24: return "Soundtrack";
case 25: return "Euro-Techno";
case 26: return "Ambient";
case 27: return "Trip-Hop";
case 28: return "Vocal";
case 29: return "Jazz&Funk";
case 30: return "Fusion";
case 31: return "Trance";
case 32: return "Classical";
case 33: return "Instrumental";
case 34: return "Acid";
case 35: return "House";
case 36: return "Game";
case 37: return "Sound Clip";
case 38: return "Gospel";
case 39: return "Noise";
case 40: return "Alternative Rock";
case 41: return "Bass";
case 42: return "Soul";
case 43: return "Punk";
case 44: return "Space";
case 45: return "Meditative";
case 46: return "Instrumental Pop";
case 47: return "Instrumental Rock";
case 48: return "Ethnic";
case 49: return "Gothic";
case 50: return "Darkwave";
case 51: return "Techno-Industrial";
case 52: return "Electronic";
case 53: return "Pop-Folk";
case 54: return "Eurodance";
case 55: return "Dream";
case 56: return "Southern Rock";
case 57: return "Comedy";
case 58: return "Cult";
case 59: return "Gangsta";
case 60: return "Top 40";
case 61: return "Christian Rap";
case 62: return "Pop/Funk";
case 63: return "Jungle";
case 64: return "Native US";
case 65: return "Cabaret";
case 66: return "New Wave";
case 67: return "Psychedelic";
case 68: return "Rave";
case 69: return "Showtunes";
case 70: return "Trailer";
case 71: return "Lo-Fi";
case 72: return "Tribal";
case 73: return "Acid Punk";
case 74: return "Acid Jazz";
case 75: return "Polka";
case 76: return "Retro";
case 77: return "Musical";
case 78: return "Rock & Roll";
case 79: return "Hard Rock";
case 80: return "Folk";
case 81: return "Folk-Rock";
case 82: return "National Folk";
case 83: return "Swing";
case 84: return "Fast Fusion";
case 85: return "Bebop";
case 86: return "Latin";
case 87: return "Revival";
case 88: return "Celtic";
case 89: return "Bluegrass";
case 90: return "Avantgarde";
case 91: return "Gothic Rock";
case 92: return "Progressive Rock";
case 93: return "Psychedelic Rock";
case 94: return "Symphonic Rock";
case 95: return "Slow Rock";
case 96: return "Big Band";
case 97: return "Chorus";
case 98: return "Easy Listening";
case 99: return "Acoustic";
case 100: return "Humour";
case 101: return "Speech";
case 102: return "Chanson";
case 103: return "Opera";
case 104: return "Chamber Music";
case 105: return "Sonata";
case 106: return "Symphony";
case 107: return "Booty Bass";
case 108: return "Primus";
case 109: return "Porn Groove";
case 110: return "Satire";
case 111: return "Slow Jam";
case 112: return "Club";
case 113: return "Tango";
case 114: return "Samba (Musik)";
case 115: return "Folklore";
case 116: return "Ballad";
case 117: return "Power Ballad";
case 118: return "Rhytmic Soul";
case 119: return "Freestyle";
case 120: return "Duet";
case 121: return "Punk Rock";
case 122: return "Drum Solo";
case 123: return "Acapella";
case 124: return "Euro-House";
case 125: return "Dance Hall";
case 126: return "Goa";
case 127: return "Drum’n’Bass";
case 128: return "Club-House";
case 129: return "Hardcore";
case 130: return "Terror";
case 131: return "Indie";
case 132: return "BritPop";
case 133: return "Negerpunk";
case 134: return "Polsk Punk";
case 135: return "Beat";
case 136: return "Christian Gangsta";
case 137: return "Heavy Metal";
case 138: return "Black Metal";
case 139: return "Crossover";
case 140: return "Contemporary Christian";
case 141: return "Christian Rock";
case 142: return "Merengue";
case 143: return "Salsa";
case 144: return "Thrash Metal";
case 145: return "Anime";
case 146: return "JPop";
case 147: return "SynthPop";
default: return "";
}
}
bool CMp3TagInfo::IsInit()
{
return m_bInit;
}
//////////////////////////////////////////////////////////////////////////
// all the getter
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// read now the next frame
// reset the memory
memset(frameName, 5, 0);
// read from file, if we are not at the end if (file.tellg() < ((int) fileSize) - 4) {
file.read(frameName, 4) ;
}
}
}
catch (std::exception)
{
file.close();
return false;
}
// finding first frame for MPEG 1 LAYER III bool flag = false;
do {
if ((curch = fgetc(file)) == EOF)
return false;
if (curch == 255)
{
if ((curch = fgetc(file)) == EOF)
return false;
if (tolower(curch/16) == 15)
flag = true;
}
} while(!flag);
// version check MPEG 1/2... int impegversion=tolower(((curch%16)/4)/2);
if(impegversion==1)
m_strMpegVersion = "MPEG 1";
else if (impegversion==0)
m_strMpegVersion = "MPEG 2";
// layer check.... int layer = tolower((((curch%16)/4)%2)*2+(((curch%16)%4)/2));
switch (layer)
{
case 0:
m_strMpegLayer = "Reserved";
break;
case 1:
m_strMpegLayer = "Layer III";
break;
case 2:
m_strMpegLayer = "Layer II";
break;
case 3:
m_strMpegLayer = "Layer I";
break;
}
//get next byte to read 3rd byte of header. if ((curch = fgetc(file)) == EOF)
return false;
std::string CMp3TagInfo::GetMp3Genre(std::string number)
{
// is the genre for example (09) than we have to resolve the number if (number.length() != 4)
return number;
if ((number[0] != '(') || (number[3] != ')'))
return number;
number = number.substr(1, number.length() - 2);
int i = atoi(number.c_str());
return GetMp3Genre(i);
}
std::string CMp3TagInfo::GetMp3Genre(int number)
{
switch(number)
{
case 0: return "Blues";
case 1: return "Classic Rock";
case 2: return "Country";
case 3: return "Dance";
case 4: return "Disco";
case 5: return "Funk";
case 6: return "Grunge";
case 7: return "Hip-Hop";
case 8: return "Jazz";
case 9: return "Metal";
case 10: return "New Age";
case 11: return "Oldies";
case 12: return "Other";
case 13: return "Pop";
case 14: return "R&B";
case 15: return "Rap";
case 16: return "Reggae";
case 17: return "Rock";
case 18: return "Techno";
case 19: return "Industrial";
case 20: return "Alternative";
case 21: return "Ska";
case 22: return "Death Metal";
case 23: return "Pranks";
case 24: return "Soundtrack";
case 25: return "Euro-Techno";
case 26: return "Ambient";
case 27: return "Trip-Hop";
case 28: return "Vocal";
case 29: return "Jazz&Funk";
case 30: return "Fusion";
case 31: return "Trance";
case 32: return "Classical";
case 33: return "Instrumental";
case 34: return "Acid";
case 35: return "House";
case 36: return "Game";
case 37: return "Sound Clip";
case 38: return "Gospel";
case 39: return "Noise";
case 40: return "Alternative Rock";
case 41: return "Bass";
case 42: return "Soul";
case 43: return "Punk";
case 44: return "Space";
case 45: return "Meditative";
case 46: return "Instrumental Pop";
case 47: return "Instrumental Rock";
case 48: return "Ethnic";
case 49: return "Gothic";
case 50: return "Darkwave";
case 51: return "Techno-Industrial";
case 52: return "Electronic";
case 53: return "Pop-Folk";
case 54: return "Eurodance";
case 55: return "Dream";
case 56: return "Southern Rock";
case 57: return "Comedy";
case 58: return "Cult";
case 59: return "Gangsta";
case 60: return "Top 40";
case 61: return "Christian Rap";
case 62: return "Pop/Funk";
case 63: return "Jungle";
case 64: return "Native US";
case 65: return "Cabaret";
case 66: return "New Wave";
case 67: return "Psychedelic";
case 68: return "Rave";
case 69: return "Showtunes";
case 70: return "Trailer";
case 71: return "Lo-Fi";
case 72: return "Tribal";
case 73: return "Acid Punk";
case 74: return "Acid Jazz";
case 75: return "Polka";
case 76: return "Retro";
case 77: return "Musical";
case 78: return "Rock & Roll";
case 79: return "Hard Rock";
case 80: return "Folk";
case 81: return "Folk-Rock";
case 82: return "National Folk";
case 83: return "Swing";
case 84: return "Fast Fusion";
case 85: return "Bebop";
case 86: return "Latin";
case 87: return "Revival";
case 88: return "Celtic";
case 89: return "Bluegrass";
case 90: return "Avantgarde";
case 91: return "Gothic Rock";
case 92: return "Progressive Rock";
case 93: return "Psychedelic Rock";
case 94: return "Symphonic Rock";
case 95: return "Slow Rock";
case 96: return "Big Band";
case 97: return "Chorus";
case 98: return "Easy Listening";
case 99: return "Acoustic";
case 100: return "Humour";
case 101: return "Speech";
case 102: return "Chanson";
case 103: return "Opera";
case 104: return "Chamber Music";
case 105: return "Sonata";
case 106: return "Symphony";
case 107: return "Booty Bass";
case 108: return "Primus";
case 109: return "Porn Groove";
case 110: return "Satire";
case 111: return "Slow Jam";
case 112: return "Club";
case 113: return "Tango";
case 114: return "Samba (Musik)";
case 115: return "Folklore";
case 116: return "Ballad";
case 117: return "Power Ballad";
case 118: return "Rhytmic Soul";
case 119: return "Freestyle";
case 120: return "Duet";
case 121: return "Punk Rock";
case 122: return "Drum Solo";
case 123: return "Acapella";
case 124: return "Euro-House";
case 125: return "Dance Hall";
case 126: return "Goa";
case 127: return "Drum’n’Bass";
case 128: return "Club-House";
case 129: return "Hardcore";
case 130: return "Terror";
case 131: return "Indie";
case 132: return "BritPop";
case 133: return "Negerpunk";
case 134: return "Polsk Punk";
case 135: return "Beat";
case 136: return "Christian Gangsta";
case 137: return "Heavy Metal";
case 138: return "Black Metal";
case 139: return "Crossover";
case 140: return "Contemporary Christian";
case 141: return "Christian Rock";
case 142: return "Merengue";
case 143: return "Salsa";
case 144: return "Thrash Metal";
case 145: return "Anime";
case 146: return "JPop";
case 147: return "SynthPop";
default: return "";
}
}
bool CMp3TagInfo::IsInit()
{
return m_bInit;
}
//////////////////////////////////////////////////////////////////////////
// all the getter
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// read now the next frame
// reset the memory
memset(frameName, 5, 0);
// read from file, if we are not at the end if (file.tellg() < ((int) fileSize) - 4) {
file.read(frameName, 4) ;
}
}
}
catch (std::exception)
{
file.close();
return false;
}
// finding first frame for MPEG 1 LAYER III bool flag = false;
do {
if ((curch = fgetc(file)) == EOF)
return false;
if (curch == 255)
{
if ((curch = fgetc(file)) == EOF)
return false;
if (tolower(curch/16) == 15)
flag = true;
}
} while(!flag);
// version check MPEG 1/2... int impegversion=tolower(((curch%16)/4)/2);
if(impegversion==1)
m_strMpegVersion = "MPEG 1";
else if (impegversion==0)
m_strMpegVersion = "MPEG 2";
// layer check.... int layer = tolower((((curch%16)/4)%2)*2+(((curch%16)%4)/2));
switch (layer)
{
case 0:
m_strMpegLayer = "Reserved";
break;
case 1:
m_strMpegLayer = "Layer III";
break;
case 2:
m_strMpegLayer = "Layer II";
break;
case 3:
m_strMpegLayer = "Layer I";
break;
}
//get next byte to read 3rd byte of header. if ((curch = fgetc(file)) == EOF)
return false;
std::string CMp3TagInfo::GetMp3Genre(std::string number)
{
// is the genre for example (09) than we have to resolve the number if (number.length() != 4)
return number;
if ((number[0] != '(') || (number[3] != ')'))
return number;
number = number.substr(1, number.length() - 2);
int i = atoi(number.c_str());
return GetMp3Genre(i);
}
std::string CMp3TagInfo::GetMp3Genre(int number)
{
switch(number)
{
case 0: return "Blues";
case 1: return "Classic Rock";
case 2: return "Country";
case 3: return "Dance";
case 4: return "Disco";
case 5: return "Funk";
case 6: return "Grunge";
case 7: return "Hip-Hop";
case 8: return "Jazz";
case 9: return "Metal";
case 10: return "New Age";
case 11: return "Oldies";
case 12: return "Other";
case 13: return "Pop";
case 14: return "R&B";
case 15: return "Rap";
case 16: return "Reggae";
case 17: return "Rock";
case 18: return "Techno";
case 19: return "Industrial";
case 20: return "Alternative";
case 21: return "Ska";
case 22: return "Death Metal";
case 23: return "Pranks";
case 24: return "Soundtrack";
case 25: return "Euro-Techno";
case 26: return "Ambient";
case 27: return "Trip-Hop";
case 28: return "Vocal";
case 29: return "Jazz&Funk";
case 30: return "Fusion";
case 31: return "Trance";
case 32: return "Classical";
case 33: return "Instrumental";
case 34: return "Acid";
case 35: return "House";
case 36: return "Game";
case 37: return "Sound Clip";
case 38: return "Gospel";
case 39: return "Noise";
case 40: return "Alternative Rock";
case 41: return "Bass";
case 42: return "Soul";
case 43: return "Punk";
case 44: return "Space";
case 45: return "Meditative";
case 46: return "Instrumental Pop";
case 47: return "Instrumental Rock";
case 48: return "Ethnic";
case 49: return "Gothic";
case 50: return "Darkwave";
case 51: return "Techno-Industrial";
case 52: return "Electronic";
case 53: return "Pop-Folk";
case 54: return "Eurodance";
case 55: return "Dream";
case 56: return "Southern Rock";
case 57: return "Comedy";
case 58: return "Cult";
case 59: return "Gangsta";
case 60: return "Top 40";
case 61: return "Christian Rap";
case 62: return "Pop/Funk";
case 63: return "Jungle";
case 64: return "Native US";
case 65: return "Cabaret";
case 66: return "New Wave";
case 67: return "Psychedelic";
case 68: return "Rave";
case 69: return "Showtunes";
case 70: return "Trailer";
case 71: return "Lo-Fi";
case 72: return "Tribal";
case 73: return "Acid Punk";
case 74: return "Acid Jazz";
case 75: return "Polka";
case 76: return "Retro";
case 77: return "Musical";
case 78: return "Rock & Roll";
case 79: return "Hard Rock";
case 80: return "Folk";
case 81: return "Folk-Rock";
case 82: return "National Folk";
case 83: return "Swing";
case 84: return "Fast Fusion";
case 85: return "Bebop";
case 86: return "Latin";
case 87: return "Revival";
case 88: return "Celtic";
case 89: return "Bluegrass";
case 90: return "Avantgarde";
case 91: return "Gothic Rock";
case 92: return "Progressive Rock";
case 93: return "Psychedelic Rock";
case 94: return "Symphonic Rock";
case 95: return "Slow Rock";
case 96: return "Big Band";
case 97: return "Chorus";
case 98: return "Easy Listening";
case 99: return "Acoustic";
case 100: return "Humour";
case 101: return "Speech";
case 102: return "Chanson";
case 103: return "Opera";
case 104: return "Chamber Music";
case 105: return "Sonata";
case 106: return "Symphony";
case 107: return "Booty Bass";
case 108: return "Primus";
case 109: return "Porn Groove";
case 110: return "Satire";
case 111: return "Slow Jam";
case 112: return "Club";
case 113: return "Tango";
case 114: return "Samba (Musik)";
case 115: return "Folklore";
case 116: return "Ballad";
case 117: return "Power Ballad";
case 118: return "Rhytmic Soul";
case 119: return "Freestyle";
case 120: return "Duet";
case 121: return "Punk Rock";
case 122: return "Drum Solo";
case 123: return "Acapella";
case 124: return "Euro-House";
case 125: return "Dance Hall";
case 126: return "Goa";
case 127: return "Drum’n’Bass";
case 128: return "Club-House";
case 129: return "Hardcore";
case 130: return "Terror";
case 131: return "Indie";
case 132: return "BritPop";
case 133: return "Negerpunk";
case 134: return "Polsk Punk";
case 135: return "Beat";
case 136: return "Christian Gangsta";
case 137: return "Heavy Metal";
case 138: return "Black Metal";
case 139: return "Crossover";
case 140: return "Contemporary Christian";
case 141: return "Christian Rock";
case 142: return "Merengue";
case 143: return "Salsa";
case 144: return "Thrash Metal";
case 145: return "Anime";
case 146: return "JPop";
case 147: return "SynthPop";
default: return "";
}
}
bool CMp3TagInfo::IsInit()
{
return m_bInit;
}
//////////////////////////////////////////////////////////////////////////
// all the getter
//////////////////////////////////////////////////////////////////////////
Ich wollte keinen Code Review... ich dachte nur dass es jemand brauchen kann.
Aber wenn jemand was zum anmerken am Code hat freu ich mich natürlich auch.
Allerdings wurde das ganze auch nur schnell zusammen gebaut... weiß selber das es nicht das Beste ist – aber es funktioniert!
Was genau gefällt dir den an dem Code nicht?
Will ja auch was hinzu lernen...
Header:
-Dateiheader in einer Struktur ablagern, damit die Datenstruktur "abgekapselt" ist und die Hauptklasse nicht so riesig wird
-Bei GetMp3Genre(std::string) und GetMp3Genre(int i) können die Datentypen ruhig const und die fnc's auch const sein
Cpp:
-CleanUp() sieht böse aus
-Zeile 109-134 schreien gerade zu automatisiert zu werden
-GetMp3Genre() hm, da fällt mir sicherlich auch noch was schöneres ein...
Ansonsten:
-Es sollte nicht Sinn einer Klasse sein, Getter für alle mem-vars bereitzustellen, das ist schlechtes Design
-Mit std::ifstream::exception() lassen sich flags zur Exception-Kontrolle setzen
-Eindeutige Namen für die mem-fncs erfinden (wtf ist V1 oder V2!?)
Macht es Laufzeittechnisch einen Unterschied wenn ich bei einer Funktion den int Übergabewert const mache (GetMp3Genre(int i))?
Nein, macht keinen Unterschied.
Auch wird Laufzeittechnisch alles was du machst im Vergleich zum File-IO verblassen.
Solche Mikro-Optimierungen, in Funktionen, die aus Files lesen müssen (oder in Files schreiben), machen überhaupt garkeinen Sinn.
Zitat:
Zitat:
-Es sollte nicht Sinn einer Klasse sein, Getter für alle mem-vars bereitzustellen, das ist schlechtes Design
Wäre eine Funktion in der man einen Identifier rein gibt und dann das entsprechende"Object" zurück bekommt besser? oder woran hast du gedacht?
Ich weiss nicht woran er gedacht hat, aber ich würde es vermutlich eher so angehen, dass ich eine Klasse habe die den Tag-Inhalt beschreibt. Und dann habe ich eine Helper-Funktion, die die Infos aus einem File lädt, und so eine "TagContents" Klasse zurückgibt. Der "TagContents" Klasse dann Getter und Setter für alle möglichen Felder zu verpassen, halte ich dagegen eher für guten Stil.
Die Definition wie so ein Tag-Inhalt aussieht, und wie man ihn aus einem File laden kann, sind für mich zwei verschiedene Dinge. Und sollten daher auch getrennt werden.
Zitat:
Zitat:
-CleanUp() sieht böse aus
Ich ruf jedesmal cleanup auf wenn auf der Instance ein Init aufgerufen wird. Wie könnte / sollte ich das besser lösen?
Wenn du den ganzen IO/Parsing Code aus der Tag-Klasse raus nimmst, brauchst du auch keine CleanUp() Funktion mehr.
Stattdessen solltest du vermutlich sicher stellen dass der Assignment-Operator korrekt funktioniert, und dass ein default-konstruiertes Tag Objekt "leer" ist. Wenn du dann irgendwo die "Cleanup" Funktionalität brauchst, kannst du einfach schreiben:
Nächstes Thema anzeigen Vorheriges Thema anzeigen
Sie können keine Beiträge in dieses Forum schreiben. Sie können auf Beiträge in diesem Forum nicht antworten. Sie können Ihre Beiträge in diesem Forum nicht bearbeiten. Sie können Ihre Beiträge in diesem Forum nicht löschen. Sie können an Umfragen in diesem Forum nicht mitmachen.
Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de
enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt
(vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in
privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden.
Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere
übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.