summaryrefslogtreecommitdiff
path: root/src/tracker-extract/tracker-cue-sheet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tracker-extract/tracker-cue-sheet.c')
-rw-r--r--src/tracker-extract/tracker-cue-sheet.c427
1 files changed, 0 insertions, 427 deletions
diff --git a/src/tracker-extract/tracker-cue-sheet.c b/src/tracker-extract/tracker-cue-sheet.c
deleted file mode 100644
index 39722d959..000000000
--- a/src/tracker-extract/tracker-cue-sheet.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * Copyright (C) 2011, ARQ Media <sam.thursfield@codethink.co.uk>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Author: Sam Thursfield <sam.thursfield@codethink.co.uk>
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-#include <gio/gio.h>
-#include <gst/gst.h>
-#include <gst/tag/tag.h>
-
-#if defined(HAVE_LIBCUE2)
-#include <libcue.h>
-#elif defined(HAVE_LIBCUE)
-#include <libcue/libcue.h>
-#endif
-
-#include <libtracker-common/tracker-file-utils.h>
-
-#include "tracker-cue-sheet.h"
-
-TrackerToc *
-tracker_toc_new (void)
-{
- TrackerToc *toc;
-
- toc = g_slice_new (TrackerToc);
- toc->tag_list = gst_tag_list_new_empty ();
- toc->entry_list = NULL;
-
- return toc;
-}
-
-void
-tracker_toc_free (TrackerToc *toc)
-{
- TrackerTocEntry *entry;
- GList *n;
-
- if (!toc) {
- return;
- }
-
- for (n = toc->entry_list; n != NULL; n = n->next) {
- entry = n->data;
- gst_tag_list_free (entry->tag_list);
- g_slice_free (TrackerTocEntry, entry);
- }
-
- gst_tag_list_free (toc->tag_list);
- g_list_free (toc->entry_list);
-
- g_slice_free (TrackerToc, toc);
-}
-
-void
-tracker_toc_add_entry (TrackerToc *toc,
- GstTagList *tags,
- gdouble start,
- gdouble duration)
-{
- TrackerTocEntry *toc_entry;
-
- toc_entry = g_slice_new (TrackerTocEntry);
- toc_entry->tag_list = gst_tag_list_ref (tags);
- toc_entry->start = start;
- toc_entry->duration = duration;
-
- toc->entry_list = g_list_append (toc->entry_list, toc_entry);
-}
-
-#if defined(HAVE_LIBCUE)
-
-static void
-add_cdtext_string_tag (Cdtext *cd_text,
- enum Pti index,
- GstTagList *tag_list,
- const gchar *tag)
-{
- const gchar *text;
-
- text = cdtext_get (index, cd_text);
-
- if (text != NULL) {
- gst_tag_list_add (tag_list, GST_TAG_MERGE_REPLACE, tag, text, NULL);
- }
-}
-
-static void
-add_cdtext_comment_date_tag (Rem *cd_comments,
-#if defined(HAVE_LIBCUE2)
- enum RemType index,
-#elif defined(HAVE_LIBCUE)
- enum Cmt index,
-#endif
- GstTagList *tag_list,
- const gchar *tag)
-{
- const gchar *text;
- gint year;
- GDate *date;
-
- text = rem_get (index, cd_comments);
-
- if (text != NULL) {
- year = atoi (text);
-
- if (year >= 1860) {
- date = g_date_new_dmy (1, 1, year);
- gst_tag_list_add (tag_list, GST_TAG_MERGE_REPLACE, tag, date, NULL);
- g_date_free (date);
- }
- }
-}
-
-static void
-add_cdtext_comment_double_tag (Rem *cd_comments,
-#if defined(HAVE_LIBCUE2)
- enum RemType index,
-#elif defined(HAVE_LIBCUE)
- enum Cmt index,
-#endif
- GstTagList *tag_list,
- const gchar *tag)
-{
- const gchar *text;
- gdouble value;
-
- text = rem_get (index, cd_comments);
-
- if (text != NULL) {
- value = strtod (text, NULL);
-
- /* Shortcut: it just so happens that 0.0 is meaningless for the replay
- * gain properties so we can get away with testing for errors this way.
- */
- if (value != 0.0)
- gst_tag_list_add (tag_list, GST_TAG_MERGE_REPLACE, tag, value, NULL);
- }
-}
-
-static void
-set_album_tags_from_cdtext (GstTagList *tag_list,
- Cdtext *cd_text,
- Rem *cd_comments)
-{
- if (cd_text != NULL) {
- add_cdtext_string_tag (cd_text, PTI_TITLE, tag_list, GST_TAG_ALBUM);
- add_cdtext_string_tag (cd_text, PTI_PERFORMER, tag_list, GST_TAG_ALBUM_ARTIST);
- }
-
- if (cd_comments != NULL) {
- add_cdtext_comment_date_tag (cd_comments, REM_DATE, tag_list, GST_TAG_DATE);
-
- add_cdtext_comment_double_tag (cd_comments, REM_REPLAYGAIN_ALBUM_GAIN, tag_list, GST_TAG_ALBUM_GAIN);
- add_cdtext_comment_double_tag (cd_comments, REM_REPLAYGAIN_ALBUM_PEAK, tag_list, GST_TAG_ALBUM_PEAK);
- }
-}
-
-static void
-set_track_tags_from_cdtext (GstTagList *tag_list,
- Cdtext *cd_text,
- Rem *cd_comments)
-{
- if (cd_text != NULL) {
- add_cdtext_string_tag (cd_text, PTI_TITLE, tag_list, GST_TAG_TITLE);
- add_cdtext_string_tag (cd_text, PTI_PERFORMER, tag_list, GST_TAG_PERFORMER);
- add_cdtext_string_tag (cd_text, PTI_COMPOSER, tag_list, GST_TAG_COMPOSER);
- }
-
- if (cd_comments != NULL) {
- add_cdtext_comment_double_tag (cd_comments, REM_REPLAYGAIN_TRACK_GAIN, tag_list, GST_TAG_TRACK_GAIN);
- add_cdtext_comment_double_tag (cd_comments, REM_REPLAYGAIN_TRACK_PEAK, tag_list, GST_TAG_TRACK_PEAK);
- }
-}
-
-/* Some simple heuristics to fill in missing tag information. */
-static void
-process_toc_tags (TrackerToc *toc)
-{
- gint track_count;
-
- if (gst_tag_list_get_tag_size (toc->tag_list, GST_TAG_TRACK_COUNT) == 0) {
- track_count = g_list_length (toc->entry_list);
- gst_tag_list_add (toc->tag_list,
- GST_TAG_MERGE_REPLACE,
- GST_TAG_TRACK_COUNT,
- track_count,
- NULL);
- }
-}
-
-/* This function runs in two modes: for external CUE sheets, it will check
- * the FILE field for each track and build a TrackerToc for all the tracks
- * contained in @file_name. If @file_name does not appear in the CUE sheet,
- * %NULL will be returned. For embedded CUE sheets, @file_name will be NULL
- * the whole TOC will be returned regardless of any FILE information.
- */
-static TrackerToc *
-parse_cue_sheet_for_file (const gchar *cue_sheet,
- const gchar *file_name)
-{
- TrackerToc *toc;
- TrackerTocEntry *toc_entry;
- Cd *cd;
- Track *track;
- gint i;
-
- toc = NULL;
-
- cd = cue_parse_string (cue_sheet);
-
- if (cd == NULL) {
- g_debug ("Unable to parse CUE sheet for %s.",
- file_name ? file_name : "(embedded in FLAC)");
- return NULL;
- }
-
- for (i = 1; i <= cd_get_ntrack (cd); i++) {
- track = cd_get_track (cd, i);
-
- /* CUE sheets generally have the correct basename but wrong
- * extension in the FILE field, so this is what we test for.
- */
- if (file_name != NULL) {
- if (!tracker_filename_casecmp_without_extension (file_name,
- track_get_filename (track))) {
- continue;
- }
- }
-
- if (track_get_mode (track) != MODE_AUDIO)
- continue;
-
- if (toc == NULL) {
- toc = tracker_toc_new ();
-
- set_album_tags_from_cdtext (toc->tag_list,
- cd_get_cdtext (cd),
- cd_get_rem (cd));
- }
-
- toc_entry = g_slice_new (TrackerTocEntry);
- toc_entry->tag_list = gst_tag_list_new_empty ();
- toc_entry->start = track_get_start (track) / 75.0;
- toc_entry->duration = track_get_length (track) / 75.0;
-
- set_track_tags_from_cdtext (toc_entry->tag_list,
- track_get_cdtext (track),
- track_get_rem (track));
-
- gst_tag_list_add (toc_entry->tag_list,
- GST_TAG_MERGE_REPLACE,
- GST_TAG_TRACK_NUMBER,
- i,
- NULL);
-
-
- toc->entry_list = g_list_prepend (toc->entry_list, toc_entry);
- }
-
- cd_delete (cd);
-
- if (toc != NULL)
- toc->entry_list = g_list_reverse (toc->entry_list);
-
- return toc;
-}
-
-TrackerToc *
-tracker_cue_sheet_parse (const gchar *cue_sheet)
-{
- TrackerToc *result;
-
- result = parse_cue_sheet_for_file (cue_sheet, NULL);
-
- if (result)
- process_toc_tags (result);
-
- return result;
-}
-
-static GList *
-find_local_cue_sheets (GFile *audio_file)
-{
- GFile *container;
- GFile *cue_sheet;
- GFileEnumerator *e;
- GFileInfo *file_info;
- gchar *container_path;
- const gchar *file_name;
- const gchar *file_content_type;
- gchar *file_path;
- GList *result = NULL;
- GError *error = NULL;
-
- container = g_file_get_parent (audio_file);
- container_path = g_file_get_path (container);
-
- e = g_file_enumerate_children (container,
- "standard::*",
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- NULL,
- &error);
-
- if (error != NULL) {
- g_debug ("Unable to enumerate directory: %s", error->message);
- g_object_unref (container);
- g_error_free (error);
- return NULL;
- }
-
- while ((file_info = g_file_enumerator_next_file (e, NULL, NULL))) {
- file_name = g_file_info_get_attribute_byte_string (file_info,
- G_FILE_ATTRIBUTE_STANDARD_NAME);
-
- file_content_type = g_file_info_get_content_type (file_info);
-
- if (file_name == NULL || file_content_type == NULL) {
- g_debug ("Unable to get info for file %s/%s",
- container_path,
- g_file_info_get_display_name (file_info));
- } else if (strcmp (file_content_type, "application/x-cue") == 0) {
- file_path = g_build_filename (container_path, file_name, NULL);
- cue_sheet = g_file_new_for_path (file_path);
- result = g_list_prepend (result, cue_sheet);
- g_free (file_path);
- }
-
- g_object_unref (file_info);
- }
-
- g_object_unref (e);
- g_object_unref (container);
- g_free (container_path);
-
- return result;
-}
-
-TrackerToc *
-tracker_cue_sheet_parse_uri (const gchar *uri)
-{
- GFile *audio_file;
- gchar *audio_file_name;
- GList *cue_sheet_list;
- TrackerToc *toc;
- GError *error = NULL;
- GList *n;
-
- audio_file = g_file_new_for_uri (uri);
- audio_file_name = g_file_get_basename (audio_file);
-
- cue_sheet_list = find_local_cue_sheets (audio_file);
-
- toc = NULL;
-
- for (n = cue_sheet_list; n != NULL; n = n->next) {
- GFile *cue_sheet_file;
- gchar *buffer;
-
- cue_sheet_file = n->data;
-
- if (!g_file_load_contents (cue_sheet_file, NULL, &buffer, NULL, NULL, &error)) {
- g_debug ("Unable to read cue sheet: %s", error->message);
- g_error_free (error);
- continue;
- }
-
- toc = parse_cue_sheet_for_file (buffer, audio_file_name);
-
- g_free (buffer);
-
- if (toc != NULL) {
- char *path = g_file_get_path (cue_sheet_file);
- g_debug ("Using external CUE sheet: %s", path);
- g_free (path);
- break;
- }
- }
-
- g_list_foreach (cue_sheet_list, (GFunc) g_object_unref, NULL);
- g_list_free (cue_sheet_list);
-
- g_object_unref (audio_file);
- g_free (audio_file_name);
-
- if (toc)
- process_toc_tags (toc);
-
- return toc;
-}
-
-#else /* ! HAVE_LIBCUE */
-
-TrackerToc *
-tracker_cue_sheet_parse (const gchar *cue_sheet)
-{
- return NULL;
-}
-
-TrackerToc *
-tracker_cue_sheet_parse_uri (const gchar *uri)
-{
- return NULL;
-}
-
-#endif /* ! HAVE_LIBCUE */