Mercurial > audlegacy-plugins
diff src/cue/cuesheet.c @ 809:29ae10725c4c trunk
[svn] - make use of new millisecond seek API.
- watchdog_func has been implemented as a thread. this thread will wake up every 10msec and will check changes of track while playing.
author | yaz |
---|---|
date | Mon, 12 Mar 2007 11:31:14 -0700 |
parents | 1ba5f86aeac9 |
children | 2452835bbfcf |
line wrap: on
line diff
--- a/src/cue/cuesheet.c Mon Mar 12 11:18:54 2007 -0700 +++ b/src/cue/cuesheet.c Mon Mar 12 11:31:14 2007 -0700 @@ -15,6 +15,8 @@ #include "config.h" #endif +#define DEBUG 1 + #include <string.h> #include <stdlib.h> #include <stdio.h> @@ -44,8 +46,18 @@ static TitleInput *get_tuple(gchar *uri); static TitleInput *get_tuple_uri(gchar *uri); static void get_song_info(gchar *uri, gchar **title, gint *length); +static void cue_init(void); +static void cue_cleanup(void); +static gpointer watchdog_func(gpointer data); -static gint watchdog_func(gpointer data); +GThread *watchdog_thread; +static GMutex *cue_mutex; +static GCond *cue_cond; +static enum { + STOP, + RUN, + EXIT, +} watchdog_state; static gchar *cue_file = NULL; static gchar *cue_title = NULL; @@ -63,7 +75,6 @@ gint index; } cue_tracks[MAX_CUE_TRACKS]; -static gint timeout_tag = 0; static gint finetune_seek = 0; static InputPlayback *real_ip = NULL; @@ -73,7 +84,7 @@ NULL, /* handle */ NULL, /* filename */ NULL, /* description */ - NULL, /* init */ + cue_init, /* init */ NULL, /* about */ NULL, /* configure */ is_our_file, @@ -86,7 +97,7 @@ get_time, NULL, NULL, - NULL, /* cleanup */ + cue_cleanup, /* cleanup */ NULL, NULL, NULL, @@ -98,6 +109,34 @@ NULL }; +static void cue_init(void) +{ + cue_mutex = g_mutex_new(); + cue_cond = g_cond_new(); + + /* 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); +#ifdef DEBUG + g_print("watchdog_thread = %p\n", watchdog_thread); +#endif +} + +static void cue_cleanup(void) +{ + g_mutex_lock(cue_mutex); + watchdog_state = EXIT; + g_cond_signal(cue_cond); + g_mutex_unlock(cue_mutex); + + g_thread_join(watchdog_thread); + + g_cond_free(cue_cond); + g_mutex_free(cue_mutex); +} + static int is_our_file(gchar *filename) { gchar *ext; @@ -141,7 +180,7 @@ static void play(InputPlayback *data) { - gchar *uri = data->filename; + gchar *uri = data->filename; /* this isn't a cue:// uri? */ if (strncasecmp("cue://", uri, 6)) { @@ -254,10 +293,14 @@ if (real_ip != NULL) real_ip->plugin->stop(real_ip); - if (data != NULL) - data->playing = 0; + if (data != NULL) + data->playing = 0; - gtk_timeout_remove(timeout_tag); + g_mutex_lock(cue_mutex); + watchdog_state = STOP; + g_cond_signal(cue_cond); + g_mutex_unlock(cue_mutex); + free_cue_info(); if (real_ip != NULL) { @@ -295,32 +338,41 @@ static void play_cue_uri(InputPlayback * data, gchar *uri) { - gchar *path2 = g_strdup(uri + 6); - gchar *_path = strchr(path2, '?'); + gchar *path2 = g_strdup(uri + 6); + gchar *_path = strchr(path2, '?'); gint file_length = 0; gint track = 0; gchar *dummy = NULL; InputPlugin *real_ip_plugin; - if (_path != NULL && *_path == '?') - { - *_path = '\0'; - _path++; - track = atoi(_path); - } +#ifdef DEBUG + g_print("f: play_cue_uri\n"); +#endif + /* stop watchdog thread */ + g_mutex_lock(cue_mutex); + watchdog_state = STOP; + g_cond_signal(cue_cond); + g_mutex_unlock(cue_mutex); + if (_path != NULL && *_path == '?') + { + *_path = '\0'; + _path++; + track = atoi(_path); + } + cur_cue_track = track; cache_cue_file(path2); - if (cue_file == NULL) - return; + if (cue_file == NULL) + return; real_ip_plugin = input_check_file(cue_file, FALSE); if (real_ip_plugin != NULL) { - if (real_ip) - g_free(real_ip); - real_ip = g_new0(InputPlayback, 1); + if (real_ip) + g_free(real_ip); + real_ip = g_new0(InputPlayback, 1); real_ip->plugin = real_ip_plugin; real_ip->plugin->set_info = set_info_override; real_ip->plugin->output = cue_ip.output; @@ -331,7 +383,22 @@ real_ip->data = data->data; real_ip->plugin->play_file(real_ip); - real_ip->plugin->seek(real_ip, finetune_seek ? finetune_seek / 1000 : cue_tracks[track].index / 1000 + 1); + + if(real_ip->plugin->mseek) { // seek by millisecond +#ifdef DEBUG + g_print("mseek\n"); +#endif + real_ip->plugin->mseek(real_ip, finetune_seek ? finetune_seek : cue_tracks[track].index); + } + else + real_ip->plugin->seek(real_ip, finetune_seek ? finetune_seek / 1000 : cue_tracks[track].index / 1000 + 1); + + /* kick watchdog thread */ + g_mutex_lock(cue_mutex); + watchdog_state = RUN; + g_cond_signal(cue_cond); + g_mutex_unlock(cue_mutex); + // in some plugins, NULL as 2nd arg causes crash. real_ip->plugin->get_song_info(cue_file, &dummy, &file_length); g_free(dummy); @@ -340,9 +407,9 @@ finetune_seek = 0; - cur_cue_track = track; - - timeout_tag = gtk_timeout_add(100, watchdog_func, data); +#ifdef DEBUG + g_print("e: play_cue_uri\n"); +#endif } InputPlugin *get_iplugin_info(void) @@ -368,41 +435,96 @@ * * - nenolod */ -static gint watchdog_func(gpointer data) +static gpointer watchdog_func(gpointer data) { - gint time = get_output_time(); - gboolean dir = FALSE; - Playlist *playlist = playlist_get_active(); + gint time = 0; + Playlist *playlist = NULL; + GTimeVal sleep_time, startup_time; + +#ifdef DEBUG + g_print("f: watchdog\n"); +#endif - if (time == -1) - time = G_MAXINT; + while(1) { +#if 0 +#if DEBUG + g_print("time = %d cur = %d cidx = %d nidx = %d\n", time, cur_cue_track, + cue_tracks[cur_cue_track].index, + cue_tracks[cur_cue_track+1].index); +#endif +#endif + g_get_current_time(&sleep_time); + g_time_val_add(&sleep_time, 10000); // 10msec - while (time < cue_tracks[cur_cue_track].index) - { - cur_cue_track--; - if (!(time < cue_tracks[cur_cue_track].index)) - finetune_seek = time; - playlist_prev(playlist); - dir = TRUE; - time = get_output_time(); - g_usleep(10000); - } + g_mutex_lock(cue_mutex); + switch(watchdog_state) { + case EXIT: +#ifdef DEBUG + g_print("e: watchdog exit\n"); +#endif + g_mutex_unlock(cue_mutex); // stop() locks cue_mutex. + stop(real_ip); // need not to care about real_ip != NULL here. + g_thread_exit(NULL); + break; + case RUN: + if(!playlist) + playlist = playlist_get_active(); + g_cond_timed_wait(cue_cond, cue_mutex, &sleep_time); + break; + case STOP: +#ifdef DEBUG + g_print("watchdog deactivated\n"); +#endif + g_cond_wait(cue_cond, cue_mutex); + playlist = playlist_get_active(); + break; + } + g_mutex_unlock(cue_mutex); + + time = get_output_time(); + + if(time == 0 || (real_ip && real_ip->playing == 0)) + continue; - while (dir == FALSE && cur_cue_track != last_cue_track && (time > cue_tracks[cur_cue_track + 1].index)) - { - cur_cue_track++; - if (!(time > cue_tracks[cur_cue_track].index)) - finetune_seek = time; - if(cfg.stopaftersong) { - stop(data); - return TRUE; - } - playlist_next(playlist); - time = get_output_time(); - g_usleep(10000); - } + // prev track + if (time < cue_tracks[cur_cue_track].index) + { +#ifdef DEBUG + g_print("i: watchdog prev\n"); + g_print("time = %d cur = %d cidx = %d nidx = %d\n", time, cur_cue_track, + cue_tracks[cur_cue_track].index, + cue_tracks[cur_cue_track+1].index); +#endif + cur_cue_track--; + if (time >= cue_tracks[cur_cue_track].index) + finetune_seek = time; + playlist_prev(playlist); + } - return TRUE; + // next track + if (cur_cue_track != last_cue_track && (time > cue_tracks[cur_cue_track + 1].index)) + { +#ifdef DEBUG + g_print("i: watchdog next\n"); + g_print("time = %d cur = %d cidx = %d nidx = %d\n", time, cur_cue_track, + cue_tracks[cur_cue_track].index, + cue_tracks[cur_cue_track+1].index); +#endif + cur_cue_track++; + if (time <= cue_tracks[cur_cue_track].index) + finetune_seek = time; + + if(cfg.stopaftersong) + stop(real_ip); + else + playlist_next(playlist); + } + } + +#ifdef DEBUG + g_print("e: watchdog\n"); +#endif + return NULL; // dummy. } /******************************************************** cuefile */ @@ -422,6 +544,10 @@ g_free(cue_tracks[last_cue_track-1].title); cue_tracks[last_cue_track-1].title = NULL; } +#ifdef DEBUG + g_print("last_cue_track = %d\n", last_cue_track); +#endif + last_cue_track = 0; } static void cache_cue_file(char *f)