ref: b75f3026a0663937207c78eb39e4d108f24f707b
parent: 0ab055fe640979fa9161ae5ddea6160e2340fd16
author: menno <menno>
date: Tue Jul 1 17:26:32 EDT 2003
new tagging stuff
--- a/common/mp4v2/atom_meta.cpp
+++ b/common/mp4v2/atom_meta.cpp
@@ -94,9 +94,10 @@
ExpectChildAtom("�day", Optional, OnlyOne); /* date */
ExpectChildAtom("�too", Optional, OnlyOne); /* tool */
ExpectChildAtom("�cmt", Optional, OnlyOne); /* comment */
+ ExpectChildAtom("�gen", Optional, OnlyOne); /* custom genre */
ExpectChildAtom("trkn", Optional, OnlyOne); /* tracknumber */
ExpectChildAtom("disk", Optional, OnlyOne); /* disknumber */
- ExpectChildAtom("gnre", Optional, OnlyOne); /* genre */
+ ExpectChildAtom("gnre", Optional, OnlyOne); /* genre (ID3v1 index + 1) */
ExpectChildAtom("cpil", Optional, OnlyOne); /* compilation */
ExpectChildAtom("tmpo", Optional, OnlyOne); /* BPM */
ExpectChildAtom("----", Optional, Many); /* ---- free form */
@@ -154,6 +155,12 @@
MP4DayAtom::MP4DayAtom()
: MP4Atom("�day")
+{
+ ExpectChildAtom("data", Required, OnlyOne);
+}
+
+MP4GenAtom::MP4GenAtom()
+ : MP4Atom("�gen")
{
ExpectChildAtom("data", Required, OnlyOne);
}
--- a/common/mp4v2/atoms.h
+++ b/common/mp4v2/atoms.h
@@ -540,6 +540,11 @@
MP4AlbAtom();
};
+class MP4GenAtom : public MP4Atom {
+public:
+ MP4GenAtom();
+};
+
class MP4TrknAtom : public MP4Atom {
public:
MP4TrknAtom();
--- a/common/mp4v2/mp4.cpp
+++ b/common/mp4v2/mp4.cpp
@@ -3061,7 +3061,7 @@
return false;
}
-extern "C" bool MP4SetMetadataGenre(MP4FileHandle hFile, u_int16_t genre)
+extern "C" bool MP4SetMetadataGenre(MP4FileHandle hFile, const char* genre)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
@@ -3075,7 +3075,7 @@
return false;
}
-extern "C" bool MP4GetMetadataGenre(MP4FileHandle hFile, u_int16_t* genre)
+extern "C" bool MP4GetMetadataGenre(MP4FileHandle hFile, char** genre)
{
if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
try {
--- a/common/mp4v2/mp4.h
+++ b/common/mp4v2/mp4.h
@@ -943,8 +943,8 @@
u_int16_t disk, u_int16_t totalDisks);
bool MP4GetMetadataDisk(MP4FileHandle hFile,
u_int16_t* disk, u_int16_t* totalDisks);
-bool MP4SetMetadataGenre(MP4FileHandle hFile, u_int16_t genre);
-bool MP4GetMetadataGenre(MP4FileHandle hFile, u_int16_t* genre);
+bool MP4SetMetadataGenre(MP4FileHandle hFile, const char* genre);
+bool MP4GetMetadataGenre(MP4FileHandle hFile, char** genre);
bool MP4SetMetadataTempo(MP4FileHandle hFile, u_int16_t tempo);
bool MP4GetMetadataTempo(MP4FileHandle hFile, u_int16_t* tempo);
bool MP4SetMetadataCompilation(MP4FileHandle hFile, u_int8_t cpl);
--- a/common/mp4v2/mp4atom.cpp
+++ b/common/mp4v2/mp4atom.cpp
@@ -307,6 +307,8 @@
pAtom = new MP4TooAtom();
} else if (ATOMID(type) == ATOMID("�cmt")) { /* Apple iTunes */
pAtom = new MP4CmtAtom();
+ } else if (ATOMID(type) == ATOMID("�gen")) { /* Apple iTunes */
+ pAtom = new MP4GenAtom();
}
break;
case '-':
--- a/common/mp4v2/mp4file.h
+++ b/common/mp4v2/mp4file.h
@@ -455,7 +455,7 @@
bool SetMetadataYear(const char* value);
bool SetMetadataTrack(u_int16_t track, u_int16_t totalTracks);
bool SetMetadataDisk(u_int16_t disk, u_int16_t totalDisks);
- bool SetMetadataGenre(u_int16_t genreIndex);
+ bool SetMetadataGenre(const char* genreIndex);
bool SetMetadataTempo(u_int16_t tempo);
bool SetMetadataCompilation(u_int8_t compilation);
bool SetMetadataCoverArt(u_int8_t *coverArt, u_int32_t size);
@@ -474,7 +474,7 @@
bool GetMetadataYear(char** value);
bool GetMetadataTrack(u_int16_t* track, u_int16_t* totalTracks);
bool GetMetadataDisk(u_int16_t* disk, u_int16_t* totalDisks);
- bool GetMetadataGenre(u_int16_t* genreIndex);
+ bool GetMetadataGenre(char** genre);
bool GetMetadataTempo(u_int16_t* tempo);
bool GetMetadataCompilation(u_int8_t* compilation);
bool GetMetadataCoverArt(u_int8_t **coverArt, u_int32_t* size);
--- a/common/mp4v2/mp4meta.cpp
+++ b/common/mp4v2/mp4meta.cpp
@@ -34,6 +34,7 @@
- �day : Year (4 bytes, e.g. "2003") (string)
- �too : Tool(s) used to create the file (string)
- �cmt : Comment (string)
+ - �gen : Custom genre (string)
- trkn : Tracknumber (8 byte string)
16 bit: empty
16 bit: tracknumber
@@ -44,7 +45,7 @@
16 bit: disknumber
16 bit: total number of disks
16 bit: empty
- - gnre : Genre (16 bit genre)
+ - gnre : Genre (16 bit genre) (ID3v1 index + 1)
- cpil : Part of a compilation (1 byte, 1 or 0)
- tmpo : Tempo in BPM (16 bit)
- covr : Cover art (xx bytes binary data)
@@ -542,51 +543,159 @@
return true;
}
-bool MP4File::SetMetadataGenre(u_int16_t genreIndex)
+static const char* ID3v1GenreList[] = {
+ "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", "AlternRock", "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 American", "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", "Rhythmic Soul", "Freestyle", "Duet",
+ "Punk Rock", "Drum Solo", "A capella", "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",
+};
+
+int GenreToString(char** GenreStr, const int genre)
{
+ if (genre > 0 && genre <= sizeof(ID3v1GenreList)/sizeof(*ID3v1GenreList))
+ {
+ *GenreStr = (char*)malloc(strlen((ID3v1GenreList[genre-1])+1)*sizeof(char));
+ strcpy(*GenreStr, ID3v1GenreList[genre-1]);
+ return 0;
+ } else {
+ *GenreStr[0] = '\0';
+ return 1;
+ }
+}
+
+int StringToGenre(const char* GenreStr)
+{
+ int i;
+
+ for (i = 0; i < sizeof(ID3v1GenreList)/sizeof(*ID3v1GenreList); i++)
+ {
+ if (strcasecmp(GenreStr, ID3v1GenreList[i]) == 0)
+ return i+1;
+ }
+ return 0;
+}
+
+bool MP4File::SetMetadataGenre(const char* value)
+{
+ u_int16_t genreIndex = 0;
unsigned char t[3];
- const char *s = "moov.udta.meta.ilst.gnre.data";
MP4BytesProperty *pMetadataProperty = NULL;
MP4Atom *pMetaAtom = NULL;
-
- pMetaAtom = m_pRootAtom->FindAtom(s);
- if (!pMetaAtom)
- {
- if (!CreateMetadataAtom("gnre"))
- return false;
+ genreIndex = StringToGenre(value);
+ if (genreIndex != 0)
+ {
+ const char *s = "moov.udta.meta.ilst.gnre.data";
pMetaAtom = m_pRootAtom->FindAtom(s);
- }
- memset(t, 0, 3*sizeof(unsigned char));
- t[0] = (unsigned char)(genreIndex>>8)&0xFF;
- t[1] = (unsigned char)(genreIndex)&0xFF;
+ if (!pMetaAtom)
+ {
+ if (!CreateMetadataAtom("gnre"))
+ return false;
- pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
- ASSERT(pMetadataProperty);
+ pMetaAtom = m_pRootAtom->FindAtom(s);
+ }
- pMetadataProperty->SetValue((u_int8_t*)t, 2);
+ memset(t, 0, 3*sizeof(unsigned char));
+ t[0] = (unsigned char)(genreIndex>>8)&0xFF;
+ t[1] = (unsigned char)(genreIndex)&0xFF;
- return true;
+ pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
+ ASSERT(pMetadataProperty);
+
+ pMetadataProperty->SetValue((u_int8_t*)t, 2);
+
+ return true;
+ } else {
+ const char *s2 = "moov.udta.meta.ilst.�gen.data";
+ pMetaAtom = m_pRootAtom->FindAtom(s2);
+
+ if (!pMetaAtom)
+ {
+ if (!CreateMetadataAtom("�gen"))
+ return false;
+
+ pMetaAtom = m_pRootAtom->FindAtom(s2);
+ }
+
+ pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
+ ASSERT(pMetadataProperty);
+
+ pMetadataProperty->SetValue((u_int8_t*)value, strlen(value));
+
+ return true;
+ }
+
+ return false;
}
-bool MP4File::GetMetadataGenre(u_int16_t* genreIndex)
+bool MP4File::GetMetadataGenre(char** value)
{
+ u_int16_t genreIndex = 0;
unsigned char *val = NULL;
u_int32_t valSize = 0;
+ const char *t = "moov.udta.meta.ilst.gnre";
const char *s = "moov.udta.meta.ilst.gnre.data.metadata";
- GetBytesProperty(s, (u_int8_t**)&val, &valSize);
- *genreIndex = 0;
+ MP4Atom *gnre = FindAtom(t);
- if (valSize != 2)
- return false;
+ if (gnre)
+ {
+ GetBytesProperty(s, (u_int8_t**)&val, &valSize);
- *genreIndex = (u_int16_t)(val[1]);
- *genreIndex += (u_int16_t)(val[0]<<8);
+ if (valSize != 2)
+ return false;
- return true;
+ genreIndex = (u_int16_t)(val[1]);
+ genreIndex += (u_int16_t)(val[0]<<8);
+
+ GenreToString(value, genreIndex);
+
+ return true;
+ } else {
+ const char *s2 = "moov.udta.meta.ilst.�gen.data.metadata";
+
+ val = NULL;
+ valSize = 0;
+
+ GetBytesProperty(s2, (u_int8_t**)&val, &valSize);
+
+ if (valSize > 0)
+ {
+ *value = (char*)malloc((valSize+1)*sizeof(unsigned char));
+ memset(*value, 0, (valSize+1)*sizeof(unsigned char));
+ memcpy(*value, val, valSize*sizeof(unsigned char));
+ return true;
+ } else {
+ *value = NULL;
+ return false;
+ }
+ }
+
+ return false;
}
bool MP4File::SetMetadataTempo(u_int16_t tempo)
--- a/plugins/foo_mp4/foo_mp4.cpp
+++ b/plugins/foo_mp4/foo_mp4.cpp
@@ -16,7 +16,7 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
-** $Id: foo_mp4.cpp,v 1.35 2003/06/29 21:41:00 menno Exp $
+** $Id: foo_mp4.cpp,v 1.36 2003/07/01 21:26:32 menno Exp $
**/
#include <mp4.h>
@@ -44,7 +44,7 @@
#endif
DECLARE_COMPONENT_VERSION ("MPEG-4 AAC decoder",
- "$Revision: 1.35 $",
+ "$Revision: 1.36 $",
"Based on FAAD2 v" FAAD2_VERSION "\nCopyright (C) 2002-2003 http://www.audiocoding.com" );
class input_mp4 : public input
@@ -209,7 +209,6 @@
virtual int set_info(reader *r,const file_info * info)
{
-#if 0
m_reader = r;
hFile = MP4ModifyCb(0, 0, open_cb, close_cb, read_cb, write_cb,
@@ -216,55 +215,6 @@
setpos_cb, getpos_cb, filesize_cb, (void*)m_reader);
if (hFile == MP4_INVALID_FILE_HANDLE) return 0;
- track = GetAACTrack(hFile);
- if (track < 1)
- {
- console::error("No valid AAC track found.", "foo_mp4");
- return 0;
- }
-
- MP4TagDelete(hFile, track);
-
- /* replay gain writing */
- const char *p = NULL;
-
- p = info->info_get("REPLAYGAIN_TRACK_PEAK");
- if (p)
- MP4TagAddEntry(hFile, track, "REPLAYGAIN_TRACK_PEAK", p);
- p = info->info_get("REPLAYGAIN_TRACK_GAIN");
- if (p)
- MP4TagAddEntry(hFile, track, "REPLAYGAIN_TRACK_GAIN", p);
- p = info->info_get("REPLAYGAIN_ALBUM_PEAK");
- if (p)
- MP4TagAddEntry(hFile, track, "REPLAYGAIN_ALBUM_PEAK", p);
- p = info->info_get("REPLAYGAIN_ALBUM_GAIN");
- if (p)
- MP4TagAddEntry(hFile, track, "REPLAYGAIN_ALBUM_GAIN", p);
-
- int numItems = info->meta_get_count();
- if (numItems > 0)
- {
- for (int i = 0; i < numItems; i++)
- {
- const char *n = info->meta_enum_name(i);
- const char *v = info->meta_enum_value(i);
- MP4TagAddEntry(hFile, track, n, v);
- }
- }
-
- numItems = MP4TagGetNumEntries(hFile, track);
- if (numItems == 0)
- MP4TagDelete(hFile, track);
-
- /* end */
- return 1;
-#else
- m_reader = r;
-
- hFile = MP4ModifyCb(0, 0, open_cb, close_cb, read_cb, write_cb,
- setpos_cb, getpos_cb, filesize_cb, (void*)m_reader);
- if (hFile == MP4_INVALID_FILE_HANDLE) return 0;
-
MP4MetadataDelete(hFile);
/* replay gain writing */
@@ -307,8 +257,7 @@
} else if (strcmp(pName, "COMMENT") == 0) {
MP4SetMetadataComment(hFile, val);
} else if (strcmp(pName, "GENRE") == 0) {
- unsigned __int16 genre = 0;
- MP4SetMetadataGenre(hFile, genre);
+ MP4SetMetadataGenre(hFile, val);
} else if (strcmp(pName, "TRACKNUMBER") == 0) {
unsigned __int16 trkn = 0, tot = 0;
sscanf(val, "%d", &trkn);
@@ -333,7 +282,6 @@
/* end */
return 1;
-#endif
}
virtual int seek(double seconds)
@@ -395,17 +343,17 @@
} else if (memcmp(pName, "�day", 4) == 0) {
info->meta_add("YEAR", val);
} else if (memcmp(pName, "�too", 4) == 0) {
- info->meta_add("TOOL", val);
+ info->info_set("TOOL", val);
} else if (memcmp(pName, "�cmt", 4) == 0) {
info->meta_add("COMMENT", val);
+ } else if (memcmp(pName, "�gen", 4) == 0) {
+ info->meta_add("GENRE", val);
} else {
info->meta_add(pName, val);
}
} else if (memcmp(pName, "gnre", 4) == 0) {
- unsigned __int16 genre = 0;
- char t[200];
- MP4GetMetadataGenre(hFile, &genre);
- wsprintf(t, "%d", genre);
+ char *t;
+ MP4GetMetadataGenre(hFile, &t);
info->meta_add("GENRE", t);
} else if (memcmp(pName, "trkn", 4) == 0) {
unsigned __int16 trkn = 0, tot = 0;