diff --git a/Makefile.am b/Makefile.am index 34e46a87d..c11e8db11 100644 --- a/Makefile.am +++ b/Makefile.am @@ -152,7 +152,8 @@ mpd_headers = \ src/archive_api.h \ src/archive_internal.h \ src/archive_list.h \ - src/input/archive_input_plugin.h + src/input/archive_input_plugin.h \ + src/cue/cue_tag.h src_mpd_SOURCES = \ $(mpd_headers) \ @@ -295,7 +296,8 @@ DECODER_CFLAGS = \ $(FLUIDSYNTH_CFLAGS) \ $(WILDMIDI_CFLAGS) \ $(MAD_CFLAGS) \ - $(FFMPEG_CFLAGS) + $(FFMPEG_CFLAGS) \ + $(CUE_CFLAGS) DECODER_LIBS = \ $(OGGVORBIS_LIBS) $(FLAC_LIBS) \ @@ -306,7 +308,8 @@ DECODER_LIBS = \ $(WILDMIDI_LIBS) \ $(MAD_LIBS) \ $(MP4FF_LIBS) \ - $(FFMPEG_LIBS) + $(FFMPEG_LIBS) \ + $(CUE_LIBS) DECODER_SRC = \ src/decoder_buffer.c \ @@ -415,6 +418,9 @@ src_mpd_SOURCES += src/zeroconf-bonjour.c endif endif +if HAVE_CUE +DECODER_SRC += src/cue/cue_tag.c +endif # # input plugins diff --git a/configure.ac b/configure.ac index e4e0c2ea9..b77344825 100644 --- a/configure.ac +++ b/configure.ac @@ -169,6 +169,20 @@ dnl ## dnl misc libraries dnl ## +AC_ARG_ENABLE(cue, + AS_HELP_STRING([--enable-cue], + [enable support for libcue support]),, + enable_cue=auto) + +MPD_AUTO_PKG(cue, CUE, [libcue], + [libcue parsing library], [libcue not found]) +if test x$enable_cue = xyes; then + AC_DEFINE([HAVE_CUE], 1, + [Define to enable libcue support]) +fi + +AM_CONDITIONAL(HAVE_CUE, test x$enable_cue = xyes) + dnl ## dnl Avahi / Zeroconf dnl ## @@ -1385,6 +1399,12 @@ else echo " Zeroconf support ..............disabled" fi +if test x$enable_cue = xyes; then + echo " libcue support ................enabled" +else + echo " libcue support ................disabled" +fi + echo "" echo "##########################################" echo "" diff --git a/src/cue/cue_tag.c b/src/cue/cue_tag.c new file mode 100644 index 000000000..ce8202a81 --- /dev/null +++ b/src/cue/cue_tag.c @@ -0,0 +1,276 @@ +#include "cue_tag.h" + +static struct tag* +cue_tag_cd(struct Cdtext* cdtext, struct Rem* rem) +{ + char* tmp = NULL; + struct tag* tag = NULL; + + //if (cdtext == NULL) + //return NULL; + + tag = tag_new(); + + tag_begin_add(tag); + + { /* TAG_ITEM_ALBUM_ARTIST */ + if ((tmp = cdtext_get(PTI_PERFORMER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ALBUM_ARTIST, tmp); + + else if ((tmp = cdtext_get(PTI_SONGWRITER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ALBUM_ARTIST, tmp); + + else if ((tmp = cdtext_get(PTI_COMPOSER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ALBUM_ARTIST, tmp); + + else if ((tmp = cdtext_get(PTI_ARRANGER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ALBUM_ARTIST, tmp); + /* TAG_ITEM_ALBUM_ARTIST */ } + + { /* TAG_ITEM_ARTIST */ + if ((tmp = cdtext_get(PTI_PERFORMER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ARTIST, tmp); + + else if ((tmp = cdtext_get(PTI_SONGWRITER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ARTIST, tmp); + + else if ((tmp = cdtext_get(PTI_COMPOSER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ARTIST, tmp); + + else if ((tmp = cdtext_get(PTI_ARRANGER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ARTIST, tmp); + /* TAG_ITEM_ARTIST */ } + + /* TAG_ITEM_PERFORMER */ + if ((tmp = cdtext_get(PTI_PERFORMER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_PERFORMER, tmp); + + /* TAG_ITEM_COMPOSER */ + if ((tmp = cdtext_get(PTI_COMPOSER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_COMPOSER, tmp); + + /* TAG_ITEM_ALBUM */ + if ((tmp = cdtext_get(PTI_TITLE, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ALBUM, tmp); + + /* TAG_ITEM_GENRE */ + if ((tmp = cdtext_get(PTI_GENRE, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_GENRE, tmp); + + /* TAG_ITEM_DATE */ + if ((tmp = rem_get(REM_DATE, rem)) != NULL) + tag_add_item(tag, TAG_ITEM_DATE, tmp); + + /* TAG_ITEM_COMMENT */ + if ((tmp = cdtext_get(PTI_MESSAGE, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_COMMENT, tmp); + + /* TAG_ITEM_DISC */ + if ((tmp = cdtext_get(PTI_DISC_ID, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_DISC, tmp); + + /* stream name, usually empty + * tag_add_item(tag, TAG_ITEM_NAME,); + */ + + /* REM MUSICBRAINZ entry? + tag_add_item(tag, TAG_MUSICBRAINZ_ARTISTID,); + tag_add_item(tag, TAG_MUSICBRAINZ_ALBUMID,); + tag_add_item(tag, TAG_MUSICBRAINZ_ALBUMARTISTID,); + tag_add_item(tag, TAG_MUSICBRAINZ_TRACKID,); + */ + + tag_end_add(tag); + + if (tag != NULL) + { + if (tag_is_empty(tag)) + { + tag_free(tag); + return NULL; + } + else + return tag; + } + else + return NULL; +} + +static struct tag* +cue_tag_track(struct Cdtext* cdtext, struct Rem* rem) +{ + char* tmp = NULL; + struct tag* tag = NULL; + + //if (cdtext == NULL) + //return NULL; + + tag = tag_new(); + + tag_begin_add(tag); + + { /* TAG_ITEM_ARTIST */ + if ((tmp = cdtext_get(PTI_PERFORMER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ARTIST, tmp); + + else if ((tmp = cdtext_get(PTI_SONGWRITER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ARTIST, tmp); + + else if ((tmp = cdtext_get(PTI_COMPOSER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ARTIST, tmp); + + else if ((tmp = cdtext_get(PTI_ARRANGER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_ARTIST, tmp); + /* TAG_ITEM_ARTIST */ } + + /* TAG_ITEM_TITLE */ + if ((tmp = cdtext_get(PTI_TITLE, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_TITLE, tmp); + + /* TAG_ITEM_GENRE */ + if ((tmp = cdtext_get(PTI_GENRE, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_GENRE, tmp); + + /* TAG_ITEM_DATE */ + if ((tmp = rem_get(REM_DATE, rem)) != NULL) + tag_add_item(tag, TAG_ITEM_DATE, tmp); + + /* TAG_ITEM_COMPOSER */ + if ((tmp = cdtext_get(PTI_COMPOSER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_COMPOSER, tmp); + + /* TAG_ITEM_PERFORMER */ + if ((tmp = cdtext_get(PTI_PERFORMER, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_PERFORMER, tmp); + + /* TAG_ITEM_COMMENT */ + if ((tmp = cdtext_get(PTI_MESSAGE, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_COMMENT, tmp); + + /* TAG_ITEM_DISC */ + if ((tmp = cdtext_get(PTI_DISC_ID, cdtext)) != NULL) + tag_add_item(tag, TAG_ITEM_DISC, tmp); + + tag_end_add(tag); + + if (tag != NULL) + { + if (tag_is_empty(tag)) + { + tag_free(tag); + return NULL; + } + else + return tag; + } + else + return NULL; +} + +struct tag* +cue_tag_file( FILE* fp, + const unsigned int tnum) +{ + struct tag* cd_tag = NULL; + struct tag* track_tag = NULL; + struct tag* merge_tag = NULL; + struct Cd* cd = NULL; + + if (tnum > 256) + return NULL; + + if (fp == NULL) + return NULL; + else + cd = cue_parse_file(fp); + + if (cd == NULL) + return NULL; + else + { + /* tag from CDtext info */ + cd_tag = cue_tag_cd( cd_get_cdtext(cd), + cd_get_rem(cd)); + + /* tag from TRACKtext info */ + track_tag = cue_tag_track( track_get_cdtext( cd_get_track(cd, tnum)), + track_get_rem( cd_get_track(cd, tnum))); + + cd_delete(cd); + } + + if ((cd_tag != NULL) && (track_tag != NULL)) + { + merge_tag = tag_merge(cd_tag, track_tag); + tag_free(cd_tag); + tag_free(track_tag); + return merge_tag; + } + + else if (cd_tag != NULL) + { + return cd_tag; + } + + else if (track_tag != NULL) + { + return track_tag; + } + + else + return NULL; +} + +struct tag* +cue_tag_string( char* str, + const unsigned int tnum) +{ + struct tag* cd_tag = NULL; + struct tag* track_tag = NULL; + struct tag* merge_tag = NULL; + struct Cd* cd = NULL; + + if (tnum > 256) + return NULL; + + if (str == NULL) + return NULL; + else + cd = cue_parse_string(str); + + if (cd == NULL) + return NULL; + else + { + /* tag from CDtext info */ + cd_tag = cue_tag_cd( cd_get_cdtext(cd), + cd_get_rem(cd)); + + /* tag from TRACKtext info */ + track_tag = cue_tag_track( track_get_cdtext( cd_get_track(cd, tnum)), + track_get_rem( cd_get_track(cd, tnum))); + + cd_delete(cd); + } + + if ((cd_tag != NULL) && (track_tag != NULL)) + { + merge_tag = tag_merge(cd_tag, track_tag); + tag_free(cd_tag); + tag_free(track_tag); + return merge_tag; + } + + else if (cd_tag != NULL) + { + return cd_tag; + } + + else if (track_tag != NULL) + { + return track_tag; + } + + else + return NULL; +} diff --git a/src/cue/cue_tag.h b/src/cue/cue_tag.h new file mode 100644 index 000000000..adc4c466e --- /dev/null +++ b/src/cue/cue_tag.h @@ -0,0 +1,20 @@ +#ifndef MPD_CUE_TAG_H +#define MPD_CUE_TAG_H + +#include "config.h" + +#ifdef HAVE_CUE /* libcue */ + +#include +#include "../tag.h" + +struct tag* +cue_tag_file( FILE*, + const unsigned int); + +struct tag* +cue_tag_string( char*, + const unsigned int); + +#endif /* libcue */ +#endif diff --git a/src/decoder/flac_plugin.c b/src/decoder/flac_plugin.c index 6d874a886..e0a2cfe4c 100644 --- a/src/decoder/flac_plugin.c +++ b/src/decoder/flac_plugin.c @@ -27,6 +27,10 @@ #include #include +#ifdef HAVE_CUE /* libcue */ +#include "../cue/cue_tag.h" +#endif + /* this code was based on flac123, from flac-tools */ static flac_read_status @@ -290,20 +294,44 @@ flac_cue_tag_load(const char *file) { struct tag* tag = NULL; char* char_tnum = NULL; - char* slash = NULL; + char* ptr = NULL; + unsigned int i = 0; unsigned int tnum = 0; unsigned int sample_rate = 0; FLAC__uint64 track_time = 0; +#ifdef HAVE_CUE /* libcue */ + FLAC__StreamMetadata* vc = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); +#endif /* libcue */ FLAC__StreamMetadata* si = FLAC__metadata_object_new(FLAC__METADATA_TYPE_STREAMINFO); 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'; + ptr = strrchr(file, '/'); + *ptr = '\0'; - tag = flac_tag_load(file, char_tnum); +#ifdef HAVE_CUE /* libcue */ + if (FLAC__metadata_get_tags(file, &vc)) + { + for (i = 0; i < vc->data.vorbis_comment.num_comments; i++) + { + if ((ptr = (char*)vc->data.vorbis_comment.comments[i].entry) != NULL) + { + if (g_ascii_strncasecmp(ptr, "cuesheet", 8) == 0) + { + while (*(++ptr) != '='); + tag = cue_tag_string( ++ptr, + tnum); + } + } + } + FLAC__metadata_object_delete(vc); + } +#endif /* libcue */ + + if (tag == NULL) + tag = flac_tag_load(file, char_tnum); if (char_tnum != NULL) { @@ -316,6 +344,7 @@ flac_cue_tag_load(const char *file) if (FLAC__metadata_get_streaminfo(file, si)) { sample_rate = si->data.stream_info.sample_rate; + FLAC__metadata_object_delete(si); } if (FLAC__metadata_get_cuesheet(file, &cs)) @@ -323,10 +352,9 @@ flac_cue_tag_load(const char *file) if (cs->data.cue_sheet.tracks != NULL && (tnum <= cs->data.cue_sheet.num_tracks - 1)) { - track_time = cs->data.cue_sheet.tracks[tnum].offset - 1 + track_time = cs->data.cue_sheet.tracks[tnum].offset - cs->data.cue_sheet.tracks[tnum - 1].offset; } - FLAC__metadata_object_delete(cs); } @@ -778,14 +806,6 @@ flac_filedecode(struct decoder *decoder, const char *fname) flac_container_decode(decoder, fname, false); } else flac_filedecode_internal(decoder, fname, false); - - /* - if (directory->device == CONTAINER) - { - flac_container_decode(decoder, fname, is_ogg); - return; - } - */ } #endif /* FLAC_API_VERSION_CURRENT >= 7 */