changeset 2952:63bf9d97ce65

- now cuesheet plugin calculates duration of subtune correctly even if pregap information is not available. - made cache_cue_file() not be called too frequently. - fixed handling for fraction in index calculation. - tweaked debug messages.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 14 Oct 2008 22:28:14 +0900
parents 6abe60a81301
children 2cbc458d8286
files src/cue/cuesheet.c src/cue/cuesheet.h src/cue/watchdog.c
diffstat 3 files changed, 99 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/src/cue/cuesheet.c	Sat Oct 11 20:03:01 2008 +0900
+++ b/src/cue/cuesheet.c	Tue Oct 14 22:28:14 2008 +0900
@@ -17,8 +17,6 @@
 
 #include "cuesheet.h"
 
-#define USE_WATCHDOG 1
-
 static GThread *watchdog_thread = NULL;
 static GThread *play_thread = NULL;
 static GThread *real_play_thread = NULL;
@@ -84,27 +82,24 @@
     cue_block_cond = g_cond_new();
     cue_target_time_mutex = g_mutex_new();
 
-#if USE_WATCHDOG
     /* create watchdog thread */
     g_mutex_lock(cue_mutex);
     watchdog_state = STOP;
     g_mutex_unlock(cue_mutex);
     watchdog_thread = g_thread_create(watchdog_func, NULL, TRUE, NULL);
     AUDDBG("watchdog_thread = %p\n", watchdog_thread);
-#endif
 }
 
 void
 cue_cleanup(void)
 {
-#if USE_WATCHDOG
     g_mutex_lock(cue_mutex);
     watchdog_state = EXIT;
     g_mutex_unlock(cue_mutex);
     g_cond_broadcast(cue_cond);
 
     g_thread_join(watchdog_thread);
-#endif
+
     g_cond_free(cue_cond);
     g_mutex_free(cue_mutex);
     g_cond_free(cue_block_cond);
@@ -122,9 +117,15 @@
     if(!is_our_file(uri))
         return NULL;
 
-	/* Get subtune information */
-	tuple = get_song_tuple(uri);
-	return tuple;
+    /* invalidate cache */
+    free_cue_info();
+
+    /* cache cue info */
+    cache_cue_file(uri);
+
+    /* Get subtune information */
+    tuple = get_song_tuple(uri);
+    return tuple;
 }
 
 
@@ -161,8 +162,7 @@
 {
     gchar *uri = g_strdup(data->filename);
 
-    AUDDBG("play: playback = %p\n", data);
-    AUDDBG("play: uri = %s\n", uri);
+    AUDDBG("playback = %p uri = %s\n", data, uri);
 
     caller_ip = data;
 
@@ -204,7 +204,9 @@
     }
 
     /* parse file of uri and find actual file to play */
-    cache_cue_file(path2);
+    if(!cue_file)
+        cache_cue_file(path2);
+    g_free(path2);
 
     /* obtain probe result for actual file */
     pr = aud_input_check_file(cue_file, FALSE);
@@ -221,7 +223,6 @@
     if(!phys_tuple)
         return NULL;
 
-
     /* build tuple to be returned */
     gchar *realfn = g_filename_from_uri(cue_file, NULL, NULL);
     if(!realfn)
@@ -274,13 +275,11 @@
 void
 mseek(InputPlayback *input, gulong time)
 {
-    AUDDBG("cur_cue_track=%d\n",cur_cue_track);
-
     g_mutex_lock(cue_target_time_mutex);
     target_time = time + cue_tracks[cur_cue_track].index;
     g_mutex_unlock(cue_target_time_mutex);
 
-    AUDDBG("cue: mseek: target_time = %lu\n", target_time);
+    AUDDBG("cur_cue_track=%d target_time = %lu\n", cur_cue_track, target_time);
 
     if (real_ip != NULL) {
         if(real_ip->plugin->mseek)
@@ -300,7 +299,7 @@
 void
 stop(InputPlayback * data)
 {
-    AUDDBG("f: stop: playback = %p\n", data);
+    AUDDBG("f: playback = %p\n", data);
 
     if(play_thread) {
         if(real_play_thread) {
@@ -318,13 +317,10 @@
             if (caller_ip != NULL)
                 caller_ip->playing = 0;
 
-#if USE_WATCHDOG
             g_mutex_lock(cue_mutex);
             watchdog_state = STOP;
             g_mutex_unlock(cue_mutex);
             g_cond_signal(cue_cond);
-#endif
-            free_cue_info();
 
             if (real_ip != NULL) {
                 real_ip->plugin->set_info = cue_ip.set_info;
@@ -338,7 +334,6 @@
 
     } /*play_thread*/
 
-
     AUDDBG("e: stop\n");
 }
 
@@ -381,27 +376,26 @@
     InputPlugin *real_ip_plugin;
     Tuple *tuple = NULL;
 
-    AUDDBG("f: play_cue_uri\n");
-    AUDDBG("play_cue_uri: playback = %p\n", data);
-    AUDDBG("play_cue_uri: path2 = %s\n", path2);
+    AUDDBG("playback = %p path2 = %s\n", data, path2);
 
     /* stop watchdog thread */
-#if USE_WATCHDOG
     g_mutex_lock(cue_mutex);
     watchdog_state = STOP;
     g_mutex_unlock(cue_mutex);
     g_cond_signal(cue_cond);
-#endif
 
     if (_path != NULL && *_path == '?')
     {
         *_path = '\0';
         _path++;
         track = atoi(_path) - 1;
-        AUDDBG("track=%d\n",track);
+        AUDDBG("track = %d\n", track);
     }
     cur_cue_track = track;
-    cache_cue_file(path2); /* path2 should be uri. */
+
+    if(!cue_file)
+        cache_cue_file(path2);
+    g_free(path2);
 
     if (cue_file == NULL || !aud_vfs_file_test(cue_file, G_FILE_TEST_EXISTS))
         return;
@@ -445,7 +439,7 @@
         target_time = finetune_seek ? finetune_seek : cue_tracks[track].index;
         g_mutex_unlock(cue_target_time_mutex);
 
-        AUDDBG("cue: play_cue_uri: target_time = %lu\n", target_time);
+        AUDDBG("target_time = %lu\n", target_time);
 
         tuple = real_ip->plugin->get_song_tuple(cue_file);
         if(tuple) {
@@ -455,14 +449,12 @@
         }
 
         /* kick watchdog thread */
-#if USE_WATCHDOG
         g_mutex_lock(cue_mutex);
         watchdog_state = RUN;
         g_mutex_unlock(cue_mutex);
         g_cond_signal(cue_cond);
+        AUDDBG("watchdog activated\n");
 
-        AUDDBG("watchdog activated\n");
-#endif
         finetune_seek = 0;
         if(real_play_thread) {
             g_mutex_lock(cue_block_mutex);
@@ -489,16 +481,41 @@
     g_free(cue_track);    cue_track = NULL;
 
     for (; last_cue_track > 0; last_cue_track--) {
+        g_free(cue_tracks[last_cue_track-1].title);
+        cue_tracks[last_cue_track-1].title = NULL;
         g_free(cue_tracks[last_cue_track-1].performer);
         cue_tracks[last_cue_track-1].performer = NULL;
-        g_free(cue_tracks[last_cue_track-1].title);
-        cue_tracks[last_cue_track-1].title = NULL;
+        cue_tracks[last_cue_track-1].index = 0;
+        cue_tracks[last_cue_track-1].index00 = 0;
     }
     AUDDBG("free_cue_info: last_cue_track = %d\n", last_cue_track);
     last_cue_track = 0;
 }
 
 void
+get_full_length(gchar *cue_file)
+{
+    Tuple *phys_tuple = NULL;
+    ProbeResult *pr = NULL;
+    InputPlugin *dec = NULL;
+
+    /* obtain probe result for actual file */
+    pr = aud_input_check_file(cue_file, FALSE);
+    if (pr == NULL)
+        return;
+    dec = pr->ip;
+    if (dec == NULL)
+        return;
+
+    /* get tuple for actual file */
+    if (dec->get_song_tuple)
+        phys_tuple = dec->get_song_tuple(cue_file);
+
+    full_length = aud_tuple_get_int(phys_tuple, FIELD_LENGTH, NULL);
+    aud_tuple_free(phys_tuple);
+}
+
+void
 cache_cue_file(char *f)
 {
     VFSFile *file = aud_vfs_fopen(f, "rb");
@@ -507,13 +524,19 @@
     if(!file)
         return;
 
-    while (TRUE) {
+    while (1) {
         gint p, q;
 
         if (aud_vfs_fgets(line, MAX_CUE_LINE_LENGTH+1, file) == NULL) {
             aud_vfs_fclose(file);
             cue_tracks[last_cue_track-1].duration =
                 full_length - cue_tracks[last_cue_track-1].index;
+
+            AUDDBG("last_cue_track = %d full_length = %d duration=%d\n",
+                   last_cue_track,
+                   full_length,
+                   cue_tracks[last_cue_track-1].duration);
+
             return;
         }
 
@@ -553,12 +576,14 @@
             if (last_cue_track == 0)
                 cue_performer = aud_str_to_utf8(line + q);
             else
-                cue_tracks[last_cue_track - 1].performer = aud_str_to_utf8(line + q);
+                cue_tracks[last_cue_track - 1].performer =
+                    aud_str_to_utf8(line + q);
         }
         else if (strcasecmp(line+p, "FILE") == 0) {
             gchar *tmp = g_path_get_dirname(f);
             fix_cue_argument(line+q);
             cue_file = g_strdup_printf("%s/%s", tmp, line+q);
+            get_full_length(cue_file);
             g_free(tmp);
         }
         else if (strcasecmp(line+p, "TITLE") == 0) {
@@ -566,7 +591,8 @@
             if (last_cue_track == 0)
                 cue_title = aud_str_to_utf8(line + q);
             else
-                cue_tracks[last_cue_track-1].title = aud_str_to_utf8(line + q);
+                cue_tracks[last_cue_track-1].title =
+                    aud_str_to_utf8(line + q);
         }
         else if (strcasecmp(line+p, "TRACK") == 0) {
             gint track;
@@ -581,9 +607,11 @@
             if (track >= MAX_CUE_TRACKS)
                 continue;
             last_cue_track = track;
-            cue_tracks[last_cue_track-1].index = 0;
+            cue_tracks[last_cue_track-1].title = NULL;
             cue_tracks[last_cue_track-1].performer = NULL;
-            cue_tracks[last_cue_track-1].title = NULL;
+            cue_tracks[last_cue_track-1].index = 0;
+            cue_tracks[last_cue_track-1].index00 = 0;
+            cue_tracks[last_cue_track-1].duration = 0;
         }
         else if (strcasecmp(line+p, "INDEX") == 0) {
             gint min, sec, frac;
@@ -591,24 +619,45 @@
             if (!line[p])
                 continue;
             line[p] = '\0';
+
             for (p++; line[p] && isspace((int) line[p]); p++);
+            /* start */
             if(strcasecmp(line+q, "01") == 0) {
                 fix_cue_argument(line+p);
                 if(sscanf(line+p, "%d:%d:%d", &min, &sec, &frac) == 3) {
-                    cue_tracks[last_cue_track-1].index =
+                    gint index01 =
                         min * 60000 + sec * 1000 + frac * 1000 / 75;
+
+                    cue_tracks[last_cue_track-1].index = index01;
+
+                    if(last_cue_track-2 >= 0) {
+                        gint index00 = cue_tracks[last_cue_track-1].index00;
+
+                        if(index00 > 0) {
+                            cue_tracks[last_cue_track-2].duration =
+                                index00 - cue_tracks[last_cue_track-2].index;
+                        }
+                        else {
+                            cue_tracks[last_cue_track-2].duration =
+                            index01 - cue_tracks[last_cue_track-2].index;
+                        }
+
+                        AUDDBG("duration=%d\n",
+                               cue_tracks[last_cue_track-2].duration);
+                    }
                 }
             }
+            /* pregap */
             else if(strcasecmp(line+q, "00") == 0) {
                 if(sscanf(line+p, "%d:%d:%d", &min, &sec, &frac) == 3) {
-                    gint index0 = min * 60000 + sec * 1000 + frac * 10;
-                    cue_tracks[last_cue_track-2].duration =
-                        index0 - cue_tracks[last_cue_track-2].index;
+                    gint index00 =
+                        min * 60000 + sec * 1000 + frac * 1000 / 75;
+
+                    cue_tracks[last_cue_track-2].index00 = index00;
                 }
             }
         }
     }
-
     aud_vfs_fclose(file);
 }
 
--- a/src/cue/cuesheet.h	Sat Oct 11 20:03:01 2008 +0900
+++ b/src/cue/cuesheet.h	Tue Oct 14 22:28:14 2008 +0900
@@ -3,7 +3,7 @@
 
 #include "config.h"
 
-#define AUD_DEBUG 1
+/* #define AUD_DEBUG 1 */
 
 #include <string.h>
 #include <stdlib.h>
@@ -35,6 +35,7 @@
     gchar *title;
     gchar *performer;
     gint index;
+    gint index00;
     gint duration;
 } cue_tracks_t;
 
--- a/src/cue/watchdog.c	Sat Oct 11 20:03:01 2008 +0900
+++ b/src/cue/watchdog.c	Tue Oct 14 22:28:14 2008 +0900
@@ -3,9 +3,9 @@
 gboolean
 do_stop(gpointer data)
 {
-    AUDDBG("f: do_stop\n");
+    AUDDBG("f:\n");
     audacious_drct_stop();
-    AUDDBG("e: do_stop\n");
+    AUDDBG("e:\n");
 
     return FALSE; /* only once */
 }
@@ -24,7 +24,7 @@
     if(pos < 0)
         pos = 0;
 
-    AUDDBG("do_setpos: pos = %d\n\n", pos);
+    AUDDBG("pos = %d\n\n", pos);
 
     if (!playlist)
         return FALSE;
@@ -87,7 +87,7 @@
         time = real_ip->output->output_time();
 
 #if 0
-        AUDDBG("time = %d target_time = %lu durattion = %d\n",
+        AUDDBG("time = %d target_time = %lu duration = %d\n",
                time,
                target_time,
                cue_tracks[cur_cue_track].duration);