changeset 1368:f611c44cc67b

Automated merge with ssh://hg.atheme.org//hg/audacious-plugins
author William Pitcock <nenolod@atheme-project.org>
date Wed, 25 Jul 2007 16:06:23 -0500
parents c75fd6894758 (current diff) 4c43c38bd033 (diff)
children 6d87598ff8a9 616d34396eef
files
diffstat 4 files changed, 186 insertions(+), 171 deletions(-) [+]
line wrap: on
line diff
--- a/src/cue/cuesheet.c	Wed Jul 25 16:06:17 2007 -0500
+++ b/src/cue/cuesheet.c	Wed Jul 25 16:06:23 2007 -0500
@@ -54,7 +54,10 @@
 static void cue_cleanup(void);
 static gpointer watchdog_func(gpointer data);
 
-GThread *watchdog_thread;
+static GThread *watchdog_thread = NULL;
+static GThread *play_thread = NULL;
+static GThread *real_play_thread = NULL;
+
 static GMutex *cue_mutex;
 static GCond *cue_cond;
 static enum {
@@ -63,8 +66,10 @@
     EXIT,
 } watchdog_state;
 
+static GMutex *cue_block_mutex;
+static GCond *cue_block_cond;
+
 static InputPlayback *caller_ip = NULL;
-GThread *exec_thread;
 
 static gchar *cue_file = NULL;
 static gchar *cue_title = NULL;
@@ -124,6 +129,8 @@
 {
     cue_mutex = g_mutex_new();
     cue_cond = g_cond_new();
+    cue_block_mutex = g_mutex_new();
+    cue_block_cond = g_cond_new();
 
     /* create watchdog thread */
     g_mutex_lock(cue_mutex);
@@ -146,6 +153,8 @@
 
     g_cond_free(cue_cond);
     g_mutex_free(cue_mutex);
+    g_cond_free(cue_block_cond);
+    g_mutex_free(cue_block_mutex);
 }
 
 static int is_our_file(gchar *filename)
@@ -206,7 +215,7 @@
 		g_free(tmp);
 		return;
 	}
-
+	play_thread = g_thread_self();
 	play_cue_uri(data, uri);
 }
 
@@ -232,7 +241,9 @@
     gchar *_path = strchr(path2, '?');
     gint track = 0;
 
+	ProbeResult *pr;
 	InputPlugin *dec;
+
 	TitleInput *phys_tuple, *out;
 
         if (_path != NULL && *_path == '?')
@@ -246,9 +257,11 @@
 
 	if (cue_file == NULL)
 		return NULL;
-
-	dec = input_check_file(cue_file, FALSE);
-
+    
+	pr = input_check_file(cue_file, FALSE);
+	if (pr == NULL)
+		return NULL;
+	dec = pr->ip;
 	if (dec == NULL)
 		return NULL;
 
@@ -319,35 +332,50 @@
 #ifdef DEBUG
     g_print("f: stop: playback = %p\n", data);
 #endif
-	if (real_ip != NULL)
-		real_ip->plugin->stop(real_ip);
+
+    if(play_thread) {
+        if(real_play_thread) {
+            g_cond_signal(cue_block_cond); /* kick play_cue_uri */
+
+            if (real_ip != NULL)
+                real_ip->plugin->stop(real_ip);
 #ifdef DEBUG
-    g_print("i: stop(real_ip) finished\n");
+            g_print("i: stop(real_ip) finished\n");
 #endif
-    if (data != NULL)
-        data->playing = 0;
-    if (caller_ip != NULL)
-        caller_ip->playing = 0;
+            real_play_thread = NULL;
+
+            if (data != NULL)
+                data->playing = 0;
+            if (caller_ip != NULL)
+                caller_ip->playing = 0;
 
-    g_mutex_lock(cue_mutex);
-    watchdog_state = STOP;
-    g_mutex_unlock(cue_mutex);
-    g_cond_signal(cue_cond);
+            g_mutex_lock(cue_mutex);
+            watchdog_state = STOP;
+            g_mutex_unlock(cue_mutex);
+            g_cond_signal(cue_cond);
 
-	free_cue_info();
+            free_cue_info();
 
-	if (real_ip != NULL) {
-		real_ip->plugin->set_info = cue_ip.set_info;
-		real_ip->plugin->output = NULL;
-		g_free(real_ip);
-		real_ip = NULL;
-	}
+            if (real_ip != NULL) {
+                real_ip->plugin->set_info = cue_ip.set_info;
+                real_ip->plugin->output = NULL;
+                g_free(real_ip);
+                real_ip = NULL;
+            }
+        } /* real_play_thread */
+
+        g_thread_join(play_thread);
+        play_thread = NULL;
+
+    } /*play_thread*/
+
+
 #ifdef DEBUG
     g_print("e: stop\n");
 #endif
 }
 
-// not publicly available functions.
+/* not publicly available functions. */
 extern void playback_stop(void);
 extern void mainwin_clear_song_info(void);
 
@@ -426,6 +454,7 @@
 	gint file_length = 0;
 	gint track = 0;
 	gchar *dummy = NULL;
+	ProbeResult *pr;
 	InputPlugin *real_ip_plugin;
 
 #ifdef DEBUG
@@ -451,7 +480,11 @@
     if (cue_file == NULL || !vfs_file_test(cue_file, G_FILE_TEST_EXISTS))
         return;
 
-	real_ip_plugin = input_check_file(cue_file, FALSE);
+	pr = input_check_file(cue_file, FALSE);
+	if (pr == NULL)
+		return;
+
+	real_ip_plugin = pr->ip;
 
 	if (real_ip_plugin != NULL)
 	{
@@ -467,18 +500,16 @@
 		real_ip->output = data->output;
 		real_ip->data = data->data;
 
-		real_ip->plugin->play_file(real_ip);
+		real_play_thread = g_thread_create((GThreadFunc)(real_ip->plugin->play_file), (gpointer)real_ip, TRUE, NULL);
+		g_usleep(10000); // wait for 10msec while real input plugin is initializing.
 
-		if(real_ip->plugin->mseek) { // seek by millisecond
-#ifdef DEBUG
-			g_print("mseek\n");
-#endif
+		if(real_ip->plugin->mseek) {
 			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);
 
-		// in some plugins, NULL as 2nd arg causes crash.
+		/* in some plugins, NULL as 2nd arg causes crash. */
 		real_ip->plugin->get_song_info(cue_file, &dummy, &file_length);
 		g_free(dummy);
 		cue_tracks[last_cue_track].index = file_length;
@@ -492,10 +523,14 @@
 #ifdef DEBUG
         g_print("watchdog activated\n");
 #endif
+        finetune_seek = 0;
+        if(real_play_thread) {
+            g_mutex_lock(cue_block_mutex);
+            g_cond_wait(cue_block_cond, cue_block_mutex); // block until stop() is called.
+            g_mutex_unlock(cue_block_mutex);            
+        }
 	}
 
-	finetune_seek = 0;
-
 #ifdef DEBUG
     g_print("e: play_cue_uri\n");
 #endif
@@ -569,6 +604,11 @@
             continue;
 
         time = get_output_time();
+#if 0
+#ifdef DEBUG
+        printf("t = %d\n", time);
+#endif
+#endif
         if(time == 0)
             continue;
 
@@ -759,7 +799,9 @@
 		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);	/* XXX: yaz might need to UTF validate this?? -nenolod */ /* as far as I know, all FILEs are in plain ASCII - yaz */
+			cue_file = g_strdup_printf("%s/%s", tmp, line+q);
+			/* XXX: yaz might need to UTF validate this?? -nenolod */
+			/* as far as I know, all FILEs are in plain ASCII -yaz */
 			g_free(tmp);
 		}
 		else if (strcasecmp(line+p, "TITLE") == 0) {
--- a/src/lastfm/lastfm.c	Wed Jul 25 16:06:17 2007 -0500
+++ b/src/lastfm/lastfm.c	Wed Jul 25 16:06:23 2007 -0500
@@ -103,7 +103,7 @@
         }
 }
 
-void lastfm_store(gchar *var_name,gchar* var)  /*mowgli storage wrapper, for storing global data*/
+void lastfm_store(gchar * var_name, gchar * var)  /*mowgli storage wrapper, for storing global data*/
 {
         if (mowgli_global_storage_get(var_name))
                 mowgli_global_storage_free(var_name);
@@ -156,40 +156,25 @@
         return g_strdup(strchr(input_string, '=') + 1);
 }
 
-gint lastfm_adjust(LastFM * handle,const gchar * uri)  /*tunes into a channel*/
+static gpointer lastfm_adjust(gpointer uri)  /*tunes into a channel*/
 {
-        gint status, i,ret = LASTFM_ADJUST_FAILED;
         gchar *fetch_url=NULL,
-              *session_id,
-              **split = NULL;
-        GString *res;        
-        session_id=mowgli_global_storage_get("lastfm_session_id");
+              *session_id = g_strdup(mowgli_global_storage_get("lastfm_session_id"));
+        GString *res=NULL;        
         if (!session_id)
         {
 #if DEBUG
                 g_print("LASTFM: (adjust) Adjust failed! Session ID not set.\n");
 #endif
-                return LASTFM_SESSION_MISSING;
+                return NULL ;
         }
-        fetch_url=g_strdup_printf(LASTFM_ADJUST_URL, session_id, uri);
+        fetch_url=g_strdup_printf(LASTFM_ADJUST_URL, session_id, (char*)uri);
         res= g_string_new(NULL);
-        status = lastfm_get_data_from_uri(fetch_url, res);
-
-        if (status == CURLE_OK)
-        {
-                split = g_strsplit(res->str, "\n", 2);
-                for (i = 0; split && split[i]; i++)
-                {
-                        if (g_str_has_prefix(split[i], "response=OK"))
-                                ret = LASTFM_ADJUST_OK;
-                }
-#if DEBUG
-                g_print("LASTFM: (adjust) Adjust to '%s' has completed successfully.\n",uri);
-#endif
-        }
+        lastfm_get_data_from_uri(fetch_url, res);      /*the output doesn't matter*/
         g_string_erase(res, 0, -1);
-        g_strfreev(split);
-        return ret;
+        g_free(session_id);
+        g_free(fetch_url);
+        return NULL ;
 }
 
 gboolean parse_metadata(LastFM * handle,GString * metadata_strings)
@@ -219,11 +204,6 @@
                 g_free(handle->lastfm_album);
                 handle->lastfm_album=NULL;
         }
-        if (handle->lastfm_cover)
-        {
-                g_free(handle->lastfm_cover);
-                handle->lastfm_cover=NULL;
-        }
         if (handle->lastfm_station_name)
         {
                 g_free(handle->lastfm_station_name);
@@ -249,11 +229,11 @@
                         handle->lastfm_title  = parse(split[i],"track=");
 
                 if (g_str_has_prefix(split[i], "album="))
-                        handle->lastfm_album  = parse(split[i],"album=" );
+                        lastfm_store("lastfm_album", parse(split[i],"album=" ));
 
                 if (g_str_has_prefix(split[i], "albumcover_medium="))
-                        handle->lastfm_cover  = parse(split[i],"albumcover_medium=");
-
+                        lastfm_store("lastfm_cover", parse(split[i],"albumcover_medium=")); 
+                        
                 if (g_str_has_prefix(split[i], "station="))
                         handle->lastfm_station_name = parse(split[i],"station=");
 
@@ -281,7 +261,7 @@
         gint status,res=METADATA_FETCH_FAILED;
         if(!handle)
                 return res;
-        handle->lastfm_session_id=mowgli_global_storage_get("lastfm_session_id");
+        handle->lastfm_session_id=g_strdup(mowgli_global_storage_get("lastfm_session_id"));
         if (handle->lastfm_session_id == NULL)
                 return res;  
         uri=g_strdup_printf(LASTFM_METADATA_URL, handle->lastfm_session_id);
@@ -313,6 +293,9 @@
                 err=0;
         gboolean track_end_expected=FALSE,track_beginning=TRUE;
         LastFM *handle = (LastFM *)arg;
+        /*get it right after opened the stream, so it doesnt need the mutex */
+         fetch_metadata(handle); 
+
         /* metadata is fetched 1 second after the stream is opened, 
          * and again after 2 seconds.
          * if metadata was fetched ok i'm waiting for 
@@ -324,16 +307,15 @@
         {
                 if(count%sleep_duration==0)
                 {    
-                        if(t0->tv_usec==-1)
-                                g_get_current_time (t0);
                         g_mutex_lock(metadata_mutex);
                         if(handle==NULL)
                                 break;
+                        if(t0->tv_usec==-1)
+                                g_get_current_time (t0);
 #if DEBUG
                         g_print("LASTFM: (thread) Fetching metadata:\n");
 #endif
                         status=fetch_metadata(handle);
-                        g_mutex_unlock(metadata_mutex);
                         g_get_current_time (t1);
                         if(status==METADATA_FETCH_SUCCEEDED)
                         {        
@@ -401,18 +383,14 @@
 #if DEBUG
                         g_print("LASTFM: (thread) Thread_count: %d\n",thread_count);
                         g_print("LASTFM: (thread) sleepping for %d seconds. ",err? sleep_duration/2 :sleep_duration);
-
-
-                        if((handle!= NULL))
-                                g_print("Track length = %d sec\n",handle->lastfm_duration);
+                        g_print("Track length = %d sec\n",handle->lastfm_duration);
 #endif
-
+                        g_mutex_unlock(metadata_mutex);
                 }
                 sleep(1);
                 count++;
-
         }
-        while ((g_thread_self()==metadata_thread )&& (err<7) && (handle != NULL));
+        while ((g_thread_self()==metadata_thread )&& (err<7));
 
 #if DEBUG
         g_print("LASTFM: (thread) Exiting thread, ID = %p\n", (void *)g_thread_self());
@@ -428,12 +406,11 @@
         handle->lastfm_artist=NULL;
         handle->lastfm_title=NULL;
         handle->lastfm_album=NULL;
-        handle->lastfm_cover=NULL;
         handle->lastfm_session_id=NULL;
         handle->lastfm_mp3_stream_url=NULL;
-        handle->lastfm_station_name=NULL;
+        handle->lastfm_station_name=g_strdup(path);
         int login_count = 0;
-
+        gchar * temp_path=g_strdup(path);
         if(!mowgli_global_storage_get("lastfm_session_id")) /*login only if really needed*/
         {
                 while((login_count++ <= 3)&&(lastfm_login()!= LASTFM_LOGIN_OK))
@@ -445,16 +422,14 @@
                         return NULL;
                 }
         }
-        handle->lastfm_mp3_stream_url = mowgli_global_storage_get("lastfm_stream_uri");
-        handle->proxy_fd = vfs_fopen(handle->lastfm_mp3_stream_url, mode);
-
-        handle->lastfm_session_id = mowgli_global_storage_get("lastfm_session_id");
-        lastfm_adjust(handle,path);
-        file->handle = handle;
+        handle->lastfm_session_id = g_strdup(mowgli_global_storage_get("lastfm_session_id"));
+        handle->lastfm_mp3_stream_url = g_strdup(mowgli_global_storage_get("lastfm_stream_uri"));
         g_get_current_time(t0);
+        g_thread_create(lastfm_adjust,temp_path,FALSE,NULL);
         metadata_thread = g_thread_create(lastfm_metadata_thread_func, handle, FALSE, NULL);
         thread_count++;
-        fetch_metadata(handle);
+        handle->proxy_fd = vfs_fopen(handle->lastfm_mp3_stream_url, mode);
+        file->handle = handle;
 #if DEBUG
         g_print("LASTFM: (fopen) Thread_count: %d\n",thread_count);
 #endif
@@ -473,7 +448,7 @@
                 ret = vfs_fclose(handle->proxy_fd);
                 if (!ret)
                         handle->proxy_fd = NULL;
-                g_free(handle);
+                g_free(file->handle);
                 file->handle = NULL;
                 g_mutex_unlock(metadata_mutex);
         }
@@ -501,7 +476,6 @@
 gint lastfm_vfs_ungetc_impl(gint c, VFSFile * stream)
 {
         LastFM *handle = stream->handle;
-
         return vfs_ungetc(c, handle->proxy_fd);
 }
 
@@ -541,7 +515,11 @@
 
 gchar *lastfm_vfs_metadata_impl(VFSFile * file, const gchar * field)
 {
-        LastFM *handle = file->handle;
+        LastFM * handle;
+        if(file->handle!= NULL)
+                handle = file->handle;
+        else 
+                return NULL;
 
         if (!g_ascii_strncasecmp(field, "stream-name", 11) && (handle->lastfm_station_name != NULL))
                 return g_strdup_printf("last.fm radio: %s", handle->lastfm_station_name);
@@ -577,8 +555,6 @@
                 metadata_mutex = g_mutex_new ();
         t0=g_new0(GTimeVal,1);
         t1=g_new0(GTimeVal,1);
-
-
 }
 
 static void cleanup(void)
--- a/src/madplug/plugin.c	Wed Jul 25 16:06:17 2007 -0500
+++ b/src/madplug/plugin.c	Wed Jul 25 16:06:23 2007 -0500
@@ -55,18 +55,18 @@
 extern gboolean scan_file(struct mad_info_t *info, gboolean fast);
 
 static gint mp3_bitrate_table[5][16] = {
-  { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1 },	/* MPEG1 L1 */
-  { 0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384, -1 },	/* MPEG1 L2 */
-  { 0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, -1 },	/* MPEG1 L3 */
-  { 0, 32, 48, 56,  64,  80,  96, 112, 128, 144, 160, 176, 192, 224, 256, -1 },	/* MPEG2(.5) L1 */
-  { 0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160, -1 } 	/* MPEG2(.5) L2,L3 */
+  { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1 }, /* MPEG1 L1 */
+  { 0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384, -1 }, /* MPEG1 L2 */
+  { 0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, -1 }, /* MPEG1 L3 */
+  { 0, 32, 48, 56,  64,  80,  96, 112, 128, 144, 160, 176, 192, 224, 256, -1 }, /* MPEG2(.5) L1 */
+  { 0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160, -1 }  /* MPEG2(.5) L2,L3 */
 };
 
 static gint mp3_samplerate_table[4][4] = {
-  { 11025, 12000, 8000, -1 },	/* MPEG2.5 */
-  { -1, -1, -1, -1 },		/* Reserved */
-  { 22050, 24000, 16000, -1 },	/* MPEG2 */
-  { 44100, 48000, 32000, -1 }	/* MPEG1 */
+  { 11025, 12000, 8000, -1 },   /* MPEG2.5 */
+  { -1, -1, -1, -1 },           /* Reserved */
+  { 22050, 24000, 16000, -1 },  /* MPEG2 */
+  { 44100, 48000, 32000, -1 }   /* MPEG1 */
 };
 
 /*
@@ -186,6 +186,10 @@
     g_free(audmad_config.replaygain.default_db);
     g_free(audmad_config.id3_format);
 
+    audmad_config.pregain_db = NULL;
+    audmad_config.replaygain.default_db = NULL;
+    audmad_config.id3_format = NULL;
+
     g_cond_free(mad_cond);
     g_mutex_free(mad_mutex);
     g_mutex_free(pb_mutex);
@@ -571,21 +575,21 @@
         return;
 
     scratch = g_strdup_printf(
-	_("Audacious MPEG Audio Plugin\n"
-	"\n"
-	"Compiled against libMAD version: %d.%d.%d%s\n"
-	"\n"
-	"Written by:\n"
-	"    William Pitcock <nenolod@sacredspiral.co.uk>\n"
-	"    Yoshiki Yazawa <yaz@cc.rim.or.jp>\n"
-	"\n"
-	"Portions derived from XMMS-MAD by:\n"
-	"    Sam Clegg\n"
-	"\n"
-	"ReplayGain support by:\n"
-	"    Samuel Krempp"),
-	MAD_VERSION_MAJOR, MAD_VERSION_MINOR, MAD_VERSION_PATCH,
-	MAD_VERSION_EXTRA);
+    _("Audacious MPEG Audio Plugin\n"
+    "\n"
+    "Compiled against libMAD version: %d.%d.%d%s\n"
+    "\n"
+    "Written by:\n"
+    "    William Pitcock <nenolod@sacredspiral.co.uk>\n"
+    "    Yoshiki Yazawa <yaz@cc.rim.or.jp>\n"
+    "\n"
+    "Portions derived from XMMS-MAD by:\n"
+    "    Sam Clegg\n"
+    "\n"
+    "ReplayGain support by:\n"
+    "    Samuel Krempp"),
+    MAD_VERSION_MAJOR, MAD_VERSION_MINOR, MAD_VERSION_PATCH,
+    MAD_VERSION_EXTRA);
 
     aboutbox = xmms_show_message(_("About MPEG Audio Plugin"),
                                  scratch,
--- a/src/tta/libtta.c	Wed Jul 25 16:06:17 2007 -0500
+++ b/src/tta/libtta.c	Wed Jul 25 16:06:23 2007 -0500
@@ -39,7 +39,6 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <glib.h>
-#include <pthread.h>
 #include <string.h>
 
 #include <audacious/util.h>
@@ -67,19 +66,18 @@
 static void play_file (InputPlayback *playback);
 static void tta_pause (InputPlayback *playback, short paused);
 static void stop (InputPlayback *playback);
-static void seek (InputPlayback *playback, int time);
-static int  get_time (InputPlayback *playback);
+static void mseek (InputPlayback *playback, gulong millisec);
+static void seek (InputPlayback *playback, int sec);
 static void get_song_info (char *filename, char **title, int *length);
 static void file_info (char *filename);
 static void about ();
 static TitleInput *get_song_tuple(char *filename);
 static gchar *extname(const char *filename);
 
-static pthread_t decode_thread;
+static GThread *decode_thread = NULL;
 static char sample_buffer[PCM_BUFFER_LENGTH * MAX_BSIZE * MAX_NCH];
 static tta_info info;		// currently playing file info
 static int seek_position = -1;
-static int playing = FALSE;
 static int read_samples = -1;
 
 gchar *tta_fmts[] = { "tta", NULL };
@@ -99,7 +97,7 @@
 	tta_pause,
 	seek,
 	NULL,
-	get_time,
+	NULL,
 	NULL,
 	NULL,
 	cleanup,
@@ -115,6 +113,7 @@
 	NULL, // buffer
 	NULL, // vfs
 	tta_fmts,
+	mseek,
 };
 
 InputPlugin *tta_iplist[] = { &tta_ip, NULL };
@@ -198,52 +197,50 @@
 }
 
 static void *
-play_loop (void *arg)
+play_loop (InputPlayback *playback)
 {
-	InputPlayback *playback = arg;
 	int  bufsize = PCM_BUFFER_LENGTH  * info.BSIZE * info.NCH;
 
 	////////////////////////////////////////
 	// decode PCM_BUFFER_LENGTH samples
 	// into the current PCM buffer position
 
-	while (playing)
+	while (playback->playing)
 	{
 	    while ((read_samples = get_samples ((unsigned char *)sample_buffer)) > 0)
 	    {
 
-		while ((playback->output->buffer_free () < bufsize)
-		    && seek_position == -1)
-		{
-		    if (!playing)
-			goto DONE;
-		    xmms_usleep (10000);
-		}
-
-		if (seek_position == -1)
-		{
-		    produce_audio(playback->output->written_time(),
-			      ((info.BPS == 8) ? FMT_U8 : FMT_S16_LE),
-			      info.NCH,
-			      read_samples * info.NCH * info.BSIZE,
-			      sample_buffer,
-			      NULL);
-		}
-		else
-		{
-		    set_position (seek_position);
-		    playback->output->flush (seek_position * SEEK_STEP);
-		    seek_position = -1;
-		}
-		if(!playing)
-			goto DONE;
+            while ((playback->output->buffer_free () < bufsize)
+                   && seek_position == -1)
+            {
+                if (!playback->playing)
+                    goto DONE;
+                xmms_usleep (10000);
+            }
+            if (seek_position == -1)
+            {
+                produce_audio(playback->output->written_time(),
+                              ((info.BPS == 8) ? FMT_U8 : FMT_S16_LE),
+                              info.NCH,
+                              read_samples * info.NCH * info.BSIZE,
+                              sample_buffer,
+                              &playback->playing);
+            }
+            else
+            {
+                set_position (seek_position);
+                playback->output->flush (seek_position * SEEK_STEP);
+                seek_position = -1;
+            }
+            if(!playback->playing)
+                goto DONE;
 	    }
 
 	    playback->output->buffer_free ();
 	    playback->output->buffer_free ();
 	    while (playback->output->buffer_playing()) {
 		    xmms_usleep(10000);
-		    if(!playing)
+		    if(!playback->playing)
 			    goto DONE;
 	    }
 	}
@@ -257,7 +254,7 @@
 	// close currently playing file
 	close_tta_file (&info);
 
-	pthread_exit (NULL);
+	return NULL;
 }
 
 static void
@@ -478,8 +475,6 @@
 	int datasize, origsize, bitrate;
 	TitleInput *tuple = NULL;
 
-	playing = FALSE;
-
 	////////////////////////////////////////
 	// open TTA file
 	if (open_tta_file (filename, &info, 0) > 0)
@@ -521,12 +516,12 @@
 	if (title)
 	    g_free (title);
 
-	playing = TRUE;
 	playback->playing = 1;
 	seek_position = -1;
 	read_samples = -1;
 
-	pthread_create (&decode_thread, NULL, play_loop, playback);
+	decode_thread = g_thread_self();
+	play_loop(playback);
 }
 
 static void
@@ -538,36 +533,34 @@
 static void
 stop (InputPlayback *playback)
 {
-	if (playing)
+	if (playback->playing)
 	{
-	    playing = FALSE;
 	    playback->playing = 0;
-	    pthread_join (decode_thread, NULL);
+	    g_thread_join(decode_thread);
+	    decode_thread = NULL;
 	    playback->output->close_audio ();
 	    close_tta_file (&info);
-	    read_samples = 0;
+	    read_samples = -1;
 	}
 }
 
 static void
-seek (InputPlayback *data, int time)
+mseek (InputPlayback *data, gulong millisec)
 {
-	if (playing)
+	if (data->playing)
 	{
-	    seek_position = 1000 * time / SEEK_STEP;
+	    seek_position = (int)(millisec / SEEK_STEP);
 
 	    while (seek_position != -1)
 		xmms_usleep (10000);
 	}
 }
 
-static int
-get_time (InputPlayback *playback)
+static void
+seek (InputPlayback *data, int sec)
 {
-	if (playing && (read_samples || playback->output->buffer_playing()))
-    	    return playback->output->output_time();
-
-	return -1;
+    gulong millisec = 1000 * sec;
+    mseek(data, millisec);
 }
 
 static TitleInput *