diff options
Diffstat (limited to 'src/decoder/vorbis_comments.c')
-rw-r--r-- | src/decoder/vorbis_comments.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/decoder/vorbis_comments.c b/src/decoder/vorbis_comments.c new file mode 100644 index 000000000..98b5166e5 --- /dev/null +++ b/src/decoder/vorbis_comments.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2003-2012 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "vorbis_comments.h" +#include "tag.h" +#include "replay_gain_info.h" + +#include <glib.h> +#include <assert.h> +#include <stddef.h> +#include <string.h> +#include <stdlib.h> + +static const char * +vorbis_comment_value(const char *comment, const char *needle) +{ + size_t len = strlen(needle); + + if (g_ascii_strncasecmp(comment, needle, len) == 0 && + comment[len] == '=') + return comment + len + 1; + + return NULL; +} + +bool +vorbis_comments_to_replay_gain(struct replay_gain_info *rgi, char **comments) +{ + const char *temp; + bool found = false; + + replay_gain_info_init(rgi); + + while (*comments) { + if ((temp = + vorbis_comment_value(*comments, "replaygain_track_gain"))) { + rgi->tuples[REPLAY_GAIN_TRACK].gain = atof(temp); + found = true; + } else if ((temp = vorbis_comment_value(*comments, + "replaygain_album_gain"))) { + rgi->tuples[REPLAY_GAIN_ALBUM].gain = atof(temp); + found = true; + } else if ((temp = vorbis_comment_value(*comments, + "replaygain_track_peak"))) { + rgi->tuples[REPLAY_GAIN_TRACK].peak = atof(temp); + found = true; + } else if ((temp = vorbis_comment_value(*comments, + "replaygain_album_peak"))) { + rgi->tuples[REPLAY_GAIN_ALBUM].peak = atof(temp); + found = true; + } + + comments++; + } + + return found; +} + +static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber"; +static const char *VORBIS_COMMENT_DISC_KEY = "discnumber"; + +/** + * Check if the comment's name equals the passed name, and if so, copy + * the comment value into the tag. + */ +static bool +vorbis_copy_comment(struct tag *tag, const char *comment, + const char *name, enum tag_type tag_type) +{ + const char *value; + + value = vorbis_comment_value(comment, name); + if (value != NULL) { + tag_add_item(tag, tag_type, value); + return true; + } + + return false; +} + +static void +vorbis_parse_comment(struct tag *tag, const char *comment) +{ + assert(tag != NULL); + + if (vorbis_copy_comment(tag, comment, VORBIS_COMMENT_TRACK_KEY, + TAG_TRACK) || + vorbis_copy_comment(tag, comment, VORBIS_COMMENT_DISC_KEY, + TAG_DISC) || + vorbis_copy_comment(tag, comment, "album artist", + TAG_ALBUM_ARTIST)) + return; + + for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) + if (vorbis_copy_comment(tag, comment, + tag_item_names[i], i)) + return; +} + +struct tag * +vorbis_comments_to_tag(char **comments) +{ + struct tag *tag = tag_new(); + + while (*comments) + vorbis_parse_comment(tag, *comments++); + + if (tag_is_empty(tag)) { + tag_free(tag); + tag = NULL; + } + + return tag; +} |