shithub: aacdec

Download patch

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;