diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tag_id3.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/tag_id3.c b/src/tag_id3.c index 62a14060a..f919111d5 100644 --- a/src/tag_id3.c +++ b/src/tag_id3.c @@ -24,6 +24,7 @@ #include <id3tag.h> #include <stdio.h> +#include <stdlib.h> #include <errno.h> #include <string.h> @@ -49,6 +50,23 @@ #define ID3_FRAME_ALBUM_ARTIST "TPE2" #endif +static id3_utf8_t * +tag_id3_getstring(const struct id3_frame *frame, unsigned i) +{ + union id3_field *field; + const id3_ucs4_t *ucs4; + + field = id3_frame_field(frame, i); + if (field == NULL) + return NULL; + + ucs4 = id3_field_getstring(field); + if (ucs4 == NULL) + return NULL; + + return id3_ucs4_utf8duplicate(ucs4); +} + /* This will try to convert a string to utf-8, */ static id3_utf8_t * processID3FieldString (int is_id3v1, const id3_ucs4_t *ucs4, int type) @@ -205,6 +223,65 @@ getID3Info(struct id3_tag *tag, const char *id, int type, struct tag *mpdTag) g_debug("Unsupported tag type requrested"); } +/** + * Parse a TXXX name, and convert it to a tag_type enum value. + * Returns TAG_NUM_OF_ITEM_TYPES if the TXXX name is not understood. + */ +static enum tag_type +tag_id3_parse_txxx_name(const char *name) +{ + static const struct { + enum tag_type type; + const char *name; + } musicbrainz_txxx[] = { + { TAG_MUSICBRAINZ_ARTISTID, "MusicBrainz Artist Id" }, + { TAG_MUSICBRAINZ_ALBUMID, "MusicBrainz Album Id" }, + { TAG_MUSICBRAINZ_ALBUMARTISTID, + "MusicBrainz Album Artist Id" }, + { TAG_MUSICBRAINZ_TRACKID, "MusicBrainz Track Id" }, + }; + + for (unsigned i = 0; i < G_N_ELEMENTS(musicbrainz_txxx); ++i) + if (strcmp(name, musicbrainz_txxx[i].name) == 0) + return musicbrainz_txxx[i].type; + + return TAG_NUM_OF_ITEM_TYPES; +} + +/** + * Import all known MusicBrainz tags from TXXX frames. + */ +static void +tag_id3_import_musicbrainz(struct tag *mpd_tag, struct id3_tag *id3_tag) +{ + for (unsigned i = 0;; ++i) { + const struct id3_frame *frame; + id3_utf8_t *name, *value; + enum tag_type type; + + frame = id3_tag_findframe(id3_tag, "TXXX", i); + if (frame == NULL) + break; + + name = tag_id3_getstring(frame, 1); + if (name == NULL) + continue; + + type = tag_id3_parse_txxx_name((const char*)name); + free(name); + + if (type == TAG_NUM_OF_ITEM_TYPES) + continue; + + value = tag_id3_getstring(frame, 2); + if (value == NULL) + continue; + + tag_add_item(mpd_tag, type, (const char*)value); + free(value); + } +} + struct tag *tag_id3_import(struct id3_tag * tag) { struct tag *ret = tag_new(); @@ -224,6 +301,8 @@ struct tag *tag_id3_import(struct id3_tag * tag) getID3Info(tag, ID3_FRAME_COMMENT, TAG_ITEM_COMMENT, ret); getID3Info(tag, ID3_FRAME_DISC, TAG_ITEM_DISC, ret); + tag_id3_import_musicbrainz(ret, tag); + if (tag_is_empty(ret)) { tag_free(ret); ret = NULL; |