From 36dab871f12a6e82a7837e782e79a4ec3828de64 Mon Sep 17 00:00:00 2001 From: Mario Lenz Date: Sun, 15 Mar 2009 23:31:07 +0100 Subject: flac: get CUE track titles from additional FLAC comments The cue sheet embedded in a flac file doen't contain any information about track titles and similar. There are three possibilities: Use an external cue sheet that includes these information, use a tag CUESHEET with a cue sheet including these information or use tags. I think the latter is the best option and is already used by other projects. --- src/decoder/_flac_common.c | 39 ++++++++++++++++++++++++--------------- src/decoder/_flac_common.h | 2 +- src/decoder/flac_plugin.c | 12 ++++++------ src/decoder/oggflac_plugin.c | 2 +- 4 files changed, 32 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/decoder/_flac_common.c b/src/decoder/_flac_common.c index fdb326e13..20ac01815 100644 --- a/src/decoder/_flac_common.c +++ b/src/decoder/_flac_common.c @@ -100,16 +100,24 @@ flac_parse_replay_gain(const FLAC__StreamMetadata *block, */ static const char * flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry, - const char *name, size_t *length_r) + const char *name, const char *char_tnum, size_t *length_r) { size_t name_length = strlen(name); + size_t char_tnum_length = strlen(char_tnum); const char *comment = (const char*)entry->entry; if (entry->length > name_length && - g_ascii_strncasecmp(comment, name, name_length) == 0 && - comment[name_length] == '=') { - *length_r = entry->length - name_length - 1; - return comment + name_length + 1; + g_ascii_strncasecmp(comment, name, name_length) == 0) { + if (char_tnum != NULL) { + char_tnum_length = strlen(char_tnum); + if (g_ascii_strncasecmp(comment + name_length, + char_tnum, char_tnum_length) == 0) + name_length = name_length + char_tnum_length; + } + if (comment[name_length] == '=') { + *length_r = entry->length - name_length - 1; + return comment + name_length + 1; + } } return NULL; @@ -122,12 +130,13 @@ flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry, static bool flac_copy_comment(struct tag *tag, const FLAC__StreamMetadata_VorbisComment_Entry *entry, - const char *name, enum tag_type tag_type) + const char *name, enum tag_type tag_type, + const char *char_tnum) { const char *value; size_t value_length; - value = flac_comment_value(entry, name, &value_length); + value = flac_comment_value(entry, name, char_tnum, &value_length); if (value != NULL) { tag_add_item_n(tag, tag_type, value, value_length); return true; @@ -142,34 +151,34 @@ static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber"; static const char *VORBIS_COMMENT_DISC_KEY = "discnumber"; static void -flac_parse_comment(struct tag *tag, +flac_parse_comment(struct tag *tag, const char *char_tnum, const FLAC__StreamMetadata_VorbisComment_Entry *entry) { assert(tag != NULL); if (flac_copy_comment(tag, entry, VORBIS_COMMENT_TRACK_KEY, - TAG_ITEM_TRACK) || + TAG_ITEM_TRACK, char_tnum) || flac_copy_comment(tag, entry, VORBIS_COMMENT_DISC_KEY, - TAG_ITEM_DISC) || + TAG_ITEM_DISC, char_tnum) || flac_copy_comment(tag, entry, "album artist", - TAG_ITEM_ALBUM_ARTIST)) + TAG_ITEM_ALBUM_ARTIST, char_tnum)) return; for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) if (flac_copy_comment(tag, entry, - tag_item_names[i], i)) + tag_item_names[i], i, char_tnum)) return; } void -flac_vorbis_comments_to_tag(struct tag *tag, +flac_vorbis_comments_to_tag(struct tag *tag, const char *char_tnum, const FLAC__StreamMetadata *block) { FLAC__StreamMetadata_VorbisComment_Entry *comments = block->data.vorbis_comment.comments; for (unsigned i = block->data.vorbis_comment.num_comments; i > 0; --i) - flac_parse_comment(tag, comments++); + flac_parse_comment(tag, char_tnum, comments++); } void flac_metadata_common_cb(const FLAC__StreamMetadata * block, @@ -188,7 +197,7 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block, flac_parse_replay_gain(block, data); if (data->tag != NULL) - flac_vorbis_comments_to_tag(data->tag, block); + flac_vorbis_comments_to_tag(data->tag, NULL, block); default: break; diff --git a/src/decoder/_flac_common.h b/src/decoder/_flac_common.h index ec8a47e96..68de7e969 100644 --- a/src/decoder/_flac_common.h +++ b/src/decoder/_flac_common.h @@ -170,7 +170,7 @@ void flac_error_common_cb(const char *plugin, struct flac_data *data); void -flac_vorbis_comments_to_tag(struct tag *tag, +flac_vorbis_comments_to_tag(struct tag *tag, const char *char_tnum, const FLAC__StreamMetadata *block); FLAC__StreamDecoderWriteStatus diff --git a/src/decoder/flac_plugin.c b/src/decoder/flac_plugin.c index 1eac7cfe0..bde1cb7e2 100644 --- a/src/decoder/flac_plugin.c +++ b/src/decoder/flac_plugin.c @@ -227,7 +227,7 @@ flac_write_cb(const flac_decoder *dec, const FLAC__Frame *frame, } static struct tag * -flac_tag_load(const char *file) +flac_tag_load(const char *file, const char *char_tnum) { struct tag *tag; FLAC__Metadata_SimpleIterator *it; @@ -265,7 +265,7 @@ flac_tag_load(const char *file) if (!block) break; if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { - flac_vorbis_comments_to_tag(tag, block); + flac_vorbis_comments_to_tag(tag, char_tnum, block); } else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) { tag->time = ((float)block->data.stream_info.total_samples) / block->data.stream_info.sample_rate + 0.5; @@ -298,13 +298,13 @@ flac_cue_tag_load(const char *file) FLAC__StreamMetadata* cs = FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET); tnum = flac_vtrack_tnum(file); + char_tnum = g_strdup_printf("%u", tnum); slash = strrchr(file, '/'); *slash = '\0'; - tag = flac_tag_load(file); + tag = flac_tag_load(file, char_tnum); - char_tnum = g_strdup_printf("%u", tnum); if (char_tnum != NULL) { tag_add_item( tag, @@ -350,7 +350,7 @@ flac_tag_dup(const char *file) return flac_cue_tag_load(file); else #endif /* FLAC_API_VERSION_CURRENT >= 7 */ - return flac_tag_load(file); + return flac_tag_load(file, NULL); } static void @@ -823,7 +823,7 @@ oggflac_tag_dup(const char *file) if (!(block = FLAC__metadata_iterator_get_block(it))) break; if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { - flac_vorbis_comments_to_tag(ret, block); + flac_vorbis_comments_to_tag(ret, NULL, block); } else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) { ret->time = ((float)block->data.stream_info. total_samples) / diff --git a/src/decoder/oggflac_plugin.c b/src/decoder/oggflac_plugin.c index d31df76d5..fedfdcb48 100644 --- a/src/decoder/oggflac_plugin.c +++ b/src/decoder/oggflac_plugin.c @@ -180,7 +180,7 @@ static void of_metadata_dup_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecode block->data.stream_info.sample_rate + 0.5; return; case FLAC__METADATA_TYPE_VORBIS_COMMENT: - flac_vorbis_comments_to_tag(data->tag, block); + flac_vorbis_comments_to_tag(data->tag, NULL, block); default: break; } -- cgit v1.2.3