add support for vorbis comments; not yet finished
authorJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 23 Aug 2002 06:44:05 +0000 (06:44 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 23 Aug 2002 06:44:05 +0000 (06:44 +0000)
src/plugin_xmms/wrap_id3.c

index b158531..09d810d 100644 (file)
@@ -28,6 +28,8 @@
 #include <xmms/configfile.h>
 #include <xmms/titlestring.h>
 
+#include "FLAC/metadata.h"
+
 #include "mylocale.h"
 #include "configure.h"
 
@@ -68,14 +70,17 @@ typedef struct id3tag_t {
        char track[16];
 } id3v2_struct;
 
-static gboolean get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *tag);
-static void flac_id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2);
-static const char *flac_get_id3_genre(unsigned char genre_code);
+static gboolean local__get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *tag);
+static void local__id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2);
+static const char *local__get_id3_genre(unsigned char genre_code);
 #endif /* FLAC__HAS_ID3LIB */
 
-static gchar *extname(const char *filename);
-static char* flac_getstr(char* str);
-static int flac_getnum(char* str);
+static gchar *local__extname(const char *filename);
+static char* local__getstr(char* str);
+static int local__getnum(char* str);
+
+static int local__vcentry_matches(const char *field_name, const FLAC__StreamMetadata_VorbisComment_Entry *entry);
+static void local__vcentry_parse_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry, gchar **dest);
 
 /*
  * Function flac_format_song_title (tag, filename)
@@ -89,34 +94,81 @@ gchar *flac_format_song_title(gchar * filename)
        gchar *ret = NULL;
        TitleInput *input = NULL;
        gboolean rc;
-
 #ifdef FLAC__HAS_ID3LIB
        File_Tag tag;
-       Initialize_File_Tag_Item (&tag);
-       rc = Id3tag_Read_File_Tag (filename, &tag);
 #else
        id3v2_struct tag;
+#endif
+       int got_vorbis_comments = 0;
+
+#ifdef FLAC__HAS_ID3LIB
+       Initialize_File_Tag_Item (&tag);
+#else
        memset(&tag, 0, sizeof(tag));
-       rc = get_id3v1_tag_as_v2_(filename, &tag);
 #endif
+
+       /* first, parse vorbis comments if they exist */
+       {
+               FLAC__Metadata_SimpleIterator *iterator = FLAC__metadata_simple_iterator_new();
+               if(0 != iterator) {
+                       do {
+                               if(FLAC__metadata_simple_iterator_get_block_type(iterator) == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
+                                       FLAC__StreamMetadata *block = FLAC__metadata_simple_iterator_get_block(iterator);
+                                       if(0 != block) {
+                                               unsigned i;
+                                               const FLAC__StreamMetadata_VorbisComment *vc = &block->data.vorbis_comment;
+                                               for(i = 0; i < vc->num_comments; i++) {
+#if 0
+@@@@@
+                                                       if(local__vcentry_matches("artist", &vc->comments[i]))
+                                                               local__vcentry_parse_value(&vc->comments[i], &tag.artist);
+                                                       else if(local__vcentry_matches("performer", &vc->comments[i]))
+                                                               local__vcentry_parse_value(&vc->comments[i], &tag.artist);
+                                                       else if(local__vcentry_matches("album", &vc->comments[i]))
+                                                               local__vcentry_parse_value(&vc->comments[i], &tag.album);
+                                                       else if(local__vcentry_matches("title", &vc->comments[i]))
+                                                               local__vcentry_parse_value(&vc->comments[i], &tag.title);
+                                                       else if(local__vcentry_matches("tracknumber", &vc->comments[i]))
+                                                               local__vcentry_parse_value(&vc->comments[i], &tag.track);
+                                                       else if(local__vcentry_matches("genre", &vc->comments[i]))
+                                                               local__vcentry_parse_value(&vc->comments[i], &tag.genre);
+                                                       else if(local__vcentry_matches("description", &vc->comments[i]))
+                                                               local__vcentry_parse_value(&vc->comments[i], &tag.comment);
+#endif
+                                               }
+                                               FLAC__metadata_object_delete(block);
+                                               got_vorbis_comments = 1;
+                                       }
+                               }
+                       } while (!got_vorbis_comments && FLAC__metadata_simple_iterator_next(iterator));
+                       FLAC__metadata_simple_iterator_delete(iterator);
+               }
+       }
+
+       if(!got_vorbis_comments) {
+#ifdef FLAC__HAS_ID3LIB
+               rc = Id3tag_Read_File_Tag(filename, &tag);
+#else
+               rc = local__get_id3v1_tag_as_v2_(filename, &tag);
+#endif
+       }
+
        XMMS_NEW_TITLEINPUT(input);
 
-       if (rc)
+       if (got_vorbis_comments || rc)
        {
-               input->performer = flac_getstr(tag.artist);
-               input->album_name = flac_getstr(tag.album);
-               input->track_name = flac_getstr(tag.title);
-               input->track_number = flac_getnum(tag.track);
-               input->year = flac_getnum(tag.year);
-               input->genre = flac_getstr(tag.genre);
-               input->comment = flac_getstr(tag.comment);
+               input->performer = local__getstr(tag.artist);
+               input->album_name = local__getstr(tag.album);
+               input->track_name = local__getstr(tag.title);
+               input->track_number = local__getnum(tag.track);
+               input->year = local__getnum(tag.year);
+               input->genre = local__getstr(tag.genre);
+               input->comment = local__getstr(tag.comment);
        }
        input->file_name = g_basename(filename);
        input->file_path = filename;
-       input->file_ext = extname(filename);
-       ret = xmms_get_titlestring(flac_cfg.tag_override ?
-                                  flac_cfg.tag_format :
-                                  xmms_get_gentitle_format(), input);
+       input->file_ext = local__extname(filename);
+       ret = xmms_get_titlestring(flac_cfg.tag_override ? flac_cfg.tag_format : xmms_get_gentitle_format(), input);
        g_free(input);
 
        if (!ret)
@@ -125,8 +177,8 @@ gchar *flac_format_song_title(gchar * filename)
                 * Format according to filename.
                 */
                ret = g_strdup(g_basename(filename));
-               if (extname(ret) != NULL)
-                       *(extname(ret) - 1) = '\0';     /* removes period */
+               if (local__extname(ret) != NULL)
+                       *(local__extname(ret) - 1) = '\0';      /* removes period */
        }
 
 #ifdef FLAC__HAS_ID3LIB
@@ -135,37 +187,6 @@ gchar *flac_format_song_title(gchar * filename)
        return ret;
 }
 
-/*
- * Function extname (filename)
- *
- *    Return pointer within filename to its extenstion, or NULL if
- *    filename has no extension.
- *
- */
-static gchar *extname(const char *filename)
-{
-       gchar *ext = strrchr(filename, '.');
-
-       if (ext != NULL)
-               ++ext;
-
-       return ext;
-}
-
-static char* flac_getstr(char* str)
-{
-       if (str && strlen(str) > 0)
-               return str;
-       return NULL;
-}
-
-static int flac_getnum(char* str)
-{
-       if (str && strlen(str) > 0)
-               return atoi(str);
-       return 0;
-}
-
 #ifndef FLAC__HAS_ID3LIB
 /*
  * Function get_idv2_tag_(filename, ID3v2tag)
@@ -173,7 +194,7 @@ static int flac_getnum(char* str)
  *    Get ID3v2 tag from file.
  *
  */
-static gboolean get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *id3v2tag)
+gboolean local__get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *id3v2tag)
 {
        FILE *file;
        id3v1_struct id3v1tag;
@@ -186,7 +207,7 @@ static gboolean get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *id3v2ta
                    (fread(&id3v1tag, 1, sizeof (id3v1tag), file) == sizeof (id3v1tag)) &&
                    (strncmp(id3v1tag.tag, "TAG", 3) == 0))
                {
-                       flac_id3v1_to_id3v2(&id3v1tag, id3v2tag);
+                       local__id3v1_to_id3v2(&id3v1tag, id3v2tag);
 
                        if (flac_cfg.convert_char_set)
                        {
@@ -232,19 +253,19 @@ static gboolean get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *id3v2ta
 }
 
 /*
- * Function flac_id3v1_to_id3v2 (v1, v2)
+ * Function local__id3v1_to_id3v2 (v1, v2)
  *
  *    Convert ID3v1 tag `v1' to ID3v2 tag `v2'.
  *
  */
-static void flac_id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2)
+void local__id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2)
 {
        memset(v2,0,sizeof(id3v2_struct));
        strncpy(v2->title, v1->title, 30);
        strncpy(v2->artist, v1->artist, 30);
        strncpy(v2->album, v1->album, 30);
        strncpy(v2->comment, v1->u.v1_0.comment, 30);
-       strncpy(v2->genre, flac_get_id3_genre(v1->genre), sizeof (v2->genre));
+       strncpy(v2->genre, local__get_id3_genre(v1->genre), sizeof (v2->genre));
        strncpy(v2->year, v1->year, 4);
 
        /* Check for v1.1 tags. */
@@ -262,7 +283,7 @@ static void flac_id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2)
        g_strstrip(v2->track);
 }
 
-static const char *flac_get_id3_genre(unsigned char genre_code)
+const char *local__get_id3_genre(unsigned char genre_code)
 {
        if (genre_code < GENRE_MAX)
                return gettext(id3_genres[genre_code]);
@@ -270,3 +291,58 @@ static const char *flac_get_id3_genre(unsigned char genre_code)
        return "";
 }
 #endif /* ifndef FLAC__HAS_ID3LIB */
+
+/*
+ * Function local__extname (filename)
+ *
+ *    Return pointer within filename to its extenstion, or NULL if
+ *    filename has no extension.
+ *
+ */
+gchar *local__extname(const char *filename)
+{
+       gchar *ext = strrchr(filename, '.');
+
+       if (ext != NULL)
+               ++ext;
+
+       return ext;
+}
+
+char* local__getstr(char* str)
+{
+       if (str && strlen(str) > 0)
+               return str;
+       return NULL;
+}
+
+int local__getnum(char* str)
+{
+       if (str && strlen(str) > 0)
+               return atoi(str);
+       return 0;
+}
+
+int local__vcentry_matches(const char *field_name, const FLAC__StreamMetadata_VorbisComment_Entry *entry)
+{
+       const FLAC__byte *eq = memchr(entry->entry, '=', entry->length);
+       const unsigned field_name_length = strlen(field_name);
+       return (0 != eq && (unsigned)(eq-entry->entry) == field_name_length && 0 == strncasecmp(field_name, entry->entry, field_name_length));
+}
+
+void local__vcentry_parse_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry, gchar **dest)
+{
+       const FLAC__byte *eq = memchr(entry->entry, '=', entry->length);
+
+       if(0 == eq)
+               return;
+       else {
+               const unsigned value_length = entry->length - (unsigned)((++eq) - entry->entry);
+
+               *dest = g_malloc(value_length + 1);
+               if(0 != *dest) {
+                       memcpy(*dest, eq, value_length);
+                       (*dest)[value_length] = '\0';
+               }
+       }
+}