aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am12
-rw-r--r--configure.ac20
-rw-r--r--src/cue/cue_tag.c276
-rw-r--r--src/cue/cue_tag.h20
-rw-r--r--src/decoder/flac_plugin.c48
5 files changed, 359 insertions, 17 deletions
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 <libcue/libcue.h>
+#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 <sys/stat.h>
#include <sys/types.h>
+#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';
+
+#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 */
- tag = flac_tag_load(file, char_tnum);
+ 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 */