changeset 561:914c96de3244 trunk

[svn] Convert plugins to use InputPlayback.output instead of InputPlugin.output
author iabervon
date Sun, 28 Jan 2007 21:09:12 -0800
parents 7b4b37819c9d
children 997496d252d4
files ChangeLog src/aac/src/libmp4.c src/adplug/adplug-xmms.cc src/alac/plugin.c src/amidi-plug/amidi-plug.c src/amidi-plug/amidi-plug.h src/cdaudio/cdaudio.c src/console/Audacious_Driver.cxx src/flac112/plugin.c src/flac113/plugin.c src/metronom/metronom.c src/modplug/plugin.cxx src/mpg123/layer1.c src/mpg123/layer2.c src/mpg123/layer3.c src/mpg123/mpg123.c src/mpg123/mpg123.h src/sexypsf/xmms.c src/sid/xmms-sid.c src/sid/xmms-sid.h src/tonegen/tonegen.c src/tta/aud-tta.c src/vorbis/vorbis.c src/wav/wav-sndfile.c src/wav/wav-sndfile.h src/wav/wav.c src/wma/wma.c
diffstat 27 files changed, 415 insertions(+), 381 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Jan 28 17:41:50 2007 -0800
+++ b/ChangeLog	Sun Jan 28 21:09:12 2007 -0800
@@ -1,3 +1,10 @@
+2007-01-29 01:41:50 +0000  Kiyoshi Aman <kiyoshi.aman@gmail.com>
+  revision [1206]
+  made null always build
+  trunk/configure.ac |   20 ++------------------
+  1 file changed, 2 insertions(+), 18 deletions(-)
+
+
 2007-01-29 01:02:41 +0000  Daniel Barkalow <barkalow@iabervon.org>
   revision [1204]
   Update plugins to the new input plugin API
--- a/src/aac/src/libmp4.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/aac/src/libmp4.c	Sun Jan 28 21:09:12 2007 -0800
@@ -140,18 +140,17 @@
   return;
 }
 
-static void mp4_play(InputPlayback *data)
+static void mp4_play(InputPlayback *playback)
 {
-  char *filename = data->filename;
   buffer_playing = TRUE;
-  decodeThread = g_thread_create((GThreadFunc)mp4Decode, g_strdup(filename), TRUE, NULL);
+  decodeThread = g_thread_create((GThreadFunc)mp4Decode, playback, TRUE, NULL);
 }
 
-static void mp4_stop(InputPlayback *data)
+static void mp4_stop(InputPlayback *playback)
 {
   if(buffer_playing){
     buffer_playing = FALSE;
-    mp4_ip.output->close_audio();
+    playback->output->close_audio();
     g_thread_join(decodeThread);
   }
 }
@@ -230,9 +229,9 @@
                      &aboutbox);
 }
 
-static void	mp4_pause(InputPlayback *data, short flag)
+static void	mp4_pause(InputPlayback *playback, short flag)
 {
-  mp4_ip.output->pause(flag);
+  playback->output->pause(flag);
 }
 
 static void	mp4_seek(InputPlayback *data, int time)
@@ -242,12 +241,12 @@
     xmms_usleep(10000);
 }
 
-static int	mp4_getTime(InputPlayback *data)
+static int	mp4_getTime(InputPlayback *playback)
 {
   if(!buffer_playing)
     return (-1);
   else
-    return (mp4_ip.output->output_time());
+    return (playback->output->output_time());
 }
 
 static void	mp4_cleanup(void)
@@ -405,7 +404,7 @@
 	(*len_real) = -1;
 }
 
-static int my_decode_mp4( char *filename, mp4ff_t *mp4file )
+static int my_decode_mp4( InputPlayback *playback, char *filename, mp4ff_t *mp4file )
 {
 	// We are reading a MP4 file
 	gint mp4track= getAACTrack(mp4file);
@@ -461,8 +460,8 @@
 		}
 		numSamples = mp4ff_num_samples(mp4file, mp4track);
 		msDuration = ((float)numSamples * (float)(framesize - 1.0)/(float)samplerate) * 1000;
-		mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels);
-		mp4_ip.output->flush(0);
+		playback->output->open_audio(FMT_S16_NE, samplerate, channels);
+		playback->output->flush(0);
 
 		mp4_ip.set_info(xmmstitle, msDuration, 
 				mp4ff_get_avg_bitrate( mp4file, mp4track ), 
@@ -476,7 +475,7 @@
 			/* Seek if seek position has changed */
 			if ( seekPosition!=-1 ) {
 				sampleID =  (float)seekPosition*(float)samplerate/(float)(framesize - 1.0);
-				mp4_ip.output->flush(seekPosition*1000);
+				playback->output->flush(seekPosition*1000);
 				seekPosition = -1;
 			}
 
@@ -488,12 +487,12 @@
 			if(sampleID >= numSamples){
 				/* Finish playing before we close the
 				   output. */
-				while ( mp4_ip.output->buffer_playing() ) {
+				while ( playback->output->buffer_playing() ) {
 					xmms_usleep(10000);
 				}
 
-				mp4_ip.output->flush(seekPosition*1000);
-				mp4_ip.output->close_audio();
+				playback->output->flush(seekPosition*1000);
+				playback->output->close_audio();
 				faacDecClose(decoder);
 
 				g_static_mutex_lock(&mutex);
@@ -513,8 +512,8 @@
 				g_print("MP4: read error\n");
 				sampleBuffer = NULL;
 				sampleID=0;
-				mp4_ip.output->buffer_free();
-				mp4_ip.output->close_audio();
+				playback->output->buffer_free();
+				playback->output->close_audio();
 
 				faacDecClose(decoder);
 
@@ -532,7 +531,7 @@
 			if(frameInfo.error > 0){
 				g_print("MP4: %s\n",
 					faacDecGetErrorMessage(frameInfo.error));
-				mp4_ip.output->close_audio();
+				playback->output->close_audio();
 				faacDecClose(decoder);
 
 				return FALSE;
@@ -544,16 +543,16 @@
 			}
 			if (buffer_playing == FALSE)
 			{
-				mp4_ip.output->close_audio();
+			        playback->output->close_audio();
 				return FALSE;
 			}
-			produce_audio(mp4_ip.output->written_time(),
+			produce_audio(playback->output->written_time(),
 					   FMT_S16_NE,
 					   channels,
 					   frameInfo.samples<<1,
 					   sampleBuffer, &buffer_playing);
 		}
-		mp4_ip.output->close_audio();
+		playback->output->close_audio();
 
 		faacDecClose(decoder);
 	}
@@ -561,7 +560,7 @@
 	return TRUE;
 }
 
-static void my_decode_aac( char *filename )
+static void my_decode_aac( InputPlayback *playback, char *filename )
 {
 	// WE ARE READING AN AAC FILE
 	VFSFile		*file = NULL;
@@ -637,12 +636,12 @@
 				     buffervalid,
 				     &samplerate,
 				     &channels);
-	if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){
+	if(playback->output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){
 		g_print("AAC: Output Error\n");
 		g_free(buffer); buffer=0;
 		faacDecClose(decoder);
 		vfs_fclose(file);
-		mp4_ip.output->close_audio();
+		playback->output->close_audio();
 		g_free(xmmstitle);
 		buffer_playing = FALSE;
 		g_static_mutex_unlock(&mutex);
@@ -650,7 +649,7 @@
 	}
 
 	mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels);
-	mp4_ip.output->flush(0);
+	playback->output->flush(0);
 
 	while(buffer_playing && buffervalid > 0){
 		faacDecFrameInfo	finfo;
@@ -691,12 +690,12 @@
 			g_print("AAC: error sample decoding\n");
 			continue;
 		}
-		produce_audio(mp4_ip.output->written_time(),
+		produce_audio(playback->output->written_time(),
 				   FMT_S16_LE, channels,
 				   samplesdecoded<<1, sample_buffer, &buffer_playing);
 	}
-	mp4_ip.output->buffer_free();
-	mp4_ip.output->close_audio();
+	playback->output->buffer_free();
+	playback->output->close_audio();
 	buffer_playing = FALSE;
 	g_free(buffer);
 	faacDecClose(decoder);
@@ -715,7 +714,8 @@
 	VFSFile *mp4fh;
 	mp4ff_t *mp4file;
 
-	char* url= (char*)args;
+	InputPlayback *playback = args;
+	char* url= (char*)playback->data;
 	char filename[255];
 	memset( filename, '\0', 255 );
 
@@ -757,7 +757,7 @@
 	}
 
 	if ( mp4cfg.file_type == FILE_MP4 ) {
-		my_decode_mp4( filename, mp4file );
+		my_decode_mp4( playback, filename, mp4file );
 
 		g_free(args);
 		vfs_fclose(mp4fh);
@@ -767,7 +767,7 @@
 		g_thread_exit(NULL);
 	}
 	else {
-		my_decode_aac( filename );
+		my_decode_aac( playback, filename );
 	}
 
 	return NULL;
--- a/src/adplug/adplug-xmms.cc	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/adplug/adplug-xmms.cc	Sun Jan 28 21:09:12 2007 -0800
@@ -588,10 +588,12 @@
 // Define sampsize macro (only usable inside play_loop()!)
 #define sampsize ((bit16 ? 2 : 1) * (stereo ? 2 : 1))
 
-static void *play_loop(void *filename)
+static void *play_loop(void *data)
 /* Main playback thread. Takes the filename to play as argument. */
 {
-  dbg_printf("play_loop(\"%s\"): ", (char *)filename);
+  InputPlayback *playback = (InputPlayback *) data;
+  char *filename = (char *) playback->data;
+  dbg_printf("play_loop(\"%s\"): ", filename);
   CEmuopl opl(cfg.freq, cfg.bit16, cfg.stereo);
   long toadd = 0, i, towrite;
   char *sndbuf, *sndbufpos;
@@ -602,7 +604,7 @@
 
   // Try to load module
   dbg_printf("factory, ");
-  if(!(plr.p = factory((char *)filename, &opl))) {
+  if(!(plr.p = factory(filename, &opl))) {
     dbg_printf("error!\n");
    // MessageBox("AdPlug :: Error", "File could not be opened!", "Ok");
     plr.playing = false;
@@ -622,8 +624,8 @@
 
   // reset to first subsong on new file
   dbg_printf("subsong, ");
-  if(strcmp((char *)filename, plr.filename)) {
-    strcpy(plr.filename, (char *)filename);
+  if(strcmp(filename, plr.filename)) {
+    strcpy(plr.filename, filename);
     plr.subsong = 0;
   }
 
@@ -656,7 +658,7 @@
         plr.time_ms += 1000 / plr.p->getrefresh();
 
       // Reset output plugin and some values
-      adplug_ip.output->flush((int)plr.time_ms);
+      playback->output->flush((int)plr.time_ms);
       plr.seek = -1;
     }
 
@@ -675,8 +677,8 @@
     }
 
     // write sound buffer
-    while(adplug_ip.output->buffer_free() < SNDBUFSIZE * sampsize) xmms_usleep(10000);
-    produce_audio(adplug_ip.output->written_time(),
+    while(playback->output->buffer_free() < SNDBUFSIZE * sampsize) xmms_usleep(10000);
+    produce_audio(playback->output->written_time(),
 			  bit16 ? FORMAT_16 : FORMAT_8,
 			  stereo ? 2 : 1, SNDBUFSIZE * sampsize, sndbuf, NULL);
 
@@ -685,13 +687,13 @@
   }
 
   // playback finished - deinit
-  dbg_printf("play_loop(\"%s\"): ", (char *)filename);
+  dbg_printf("play_loop(\"%s\"): ", filename);
   if(!playing) { // wait for output plugin to finish if song has self-ended
     dbg_printf("wait, ");
-    while(adplug_ip.output->buffer_playing()) xmms_usleep(10000);
+    while(playback->output->buffer_playing()) xmms_usleep(10000);
   } else { // or else, flush its output buffers
     dbg_printf("flush, ");
-    adplug_ip.output->buffer_free(); adplug_ip.output->buffer_free();
+    playback->output->buffer_free(); playback->output->buffer_free();
   }
 
   // free everything and exit
@@ -731,7 +733,7 @@
 {
   if(audio_error) { dbg_printf("adplug_get_time(): returned -2\n"); return -2; }
   if(!plr.playing) { dbg_printf("adplug_get_time(): returned -1\n"); return -1; }
-  return adplug_ip.output->output_time();
+  return playback->output->output_time();
 }
 
 static void adplug_song_info(char *filename, char **title, int *length)
@@ -776,7 +778,7 @@
 
   // open output plugin
   dbg_printf("open, ");
-  if (!adplug_ip.output->open_audio(cfg.bit16 ? FORMAT_16 : FORMAT_8, cfg.freq, cfg.stereo ? 2 : 1)) {
+  if (!playback->output->open_audio(cfg.bit16 ? FORMAT_16 : FORMAT_8, cfg.freq, cfg.stereo ? 2 : 1)) {
     audio_error = TRUE;
     return;
   }
@@ -789,22 +791,22 @@
 
   // start player thread
   dbg_printf("create");
-  plr.play_thread = g_thread_create(play_loop, filename, TRUE, NULL);
+  plr.play_thread = g_thread_create(play_loop, playback, TRUE, NULL);
   dbg_printf(".\n");
 }
 
-static void adplug_stop(InputPlayback * data)
+static void adplug_stop(InputPlayback * playback)
 {
   dbg_printf("adplug_stop(): join, ");
   plr.playing = false; g_thread_join(plr.play_thread); // stop player thread
-  dbg_printf("close"); adplug_ip.output->close_audio();
+  dbg_printf("close"); playback->output->close_audio();
   dbg_printf(".\n");
 }
 
-static void adplug_pause(InputPlayback * data, short paused)
+static void adplug_pause(InputPlayback * playback, short paused)
 {
   dbg_printf("adplug_pause(%d)\n", paused);
-  adplug_ip.output->pause(paused);
+  playback->output->pause(paused);
 }
 
 static void adplug_seek(InputPlayback * data, int time)
--- a/src/alac/plugin.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/alac/plugin.c	Sun Jan 28 21:09:12 2007 -0800
@@ -178,10 +178,13 @@
     return build_tuple_from_demux(&demux_res, filename);
 }
 
+static InputPlayback *playback;
+
 static void play_file(InputPlayback *data)
 {
     char *filename = data->filename;
     going = 1;
+    playback = data;
     playback_thread = g_thread_create(decode_thread, filename, TRUE, NULL);
 }
 
@@ -326,7 +329,7 @@
         /* write */
         bytes_read += outputBytes;
 
-        produce_audio(alac_ip.output->written_time(), FMT_S16_LE, demux_res->num_channels, outputBytes, pDestBuffer, &going);
+        produce_audio(playback->output->written_time(), FMT_S16_LE, demux_res->num_channels, outputBytes, pDestBuffer, &going);
     }
 
     free(buffer);
@@ -373,7 +376,7 @@
     duration = (demux_res.num_sample_byte_sizes * (float)((1024 * demux_res.sample_size) - 1.0) /
 	(float)(demux_res.sample_rate / 251));
 
-    alac_ip.output->open_audio(FMT_S16_LE, demux_res.sample_rate, demux_res.num_channels);
+    playback->output->open_audio(FMT_S16_LE, demux_res.sample_rate, demux_res.num_channels);
     alac_ip.set_info(title, duration, -1, demux_res.sample_rate, demux_res.num_channels);
 
     /* will convert the entire buffer */
@@ -386,7 +389,7 @@
     if (input_opened)
         vfs_fclose(input_file);
 
-    alac_ip.output->close_audio();
+    playback->output->close_audio();
 
     return NULL;
 }
--- a/src/amidi-plug/amidi-plug.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/amidi-plug/amidi-plug.c	Sun Jan 28 21:09:12 2007 -0800
@@ -129,7 +129,7 @@
 }
 
 
-static void amidiplug_stop( InputPlayback * data )
+static void amidiplug_stop( InputPlayback * playback )
 {
   DEBUGMSG( "STOP request at tick: %i\n" , midifile.playing_tick );
   pthread_mutex_lock( &amidiplug_playing_mutex );
@@ -168,16 +168,16 @@
   if (( backend.gmodule != NULL ) && ( backend.autonomous_audio == FALSE ))
   {
     DEBUGMSG( "STOP activated, closing audio output plugin\n" );
-    amidiplug_ip.output->buffer_free();
-    amidiplug_ip.output->buffer_free();
-    amidiplug_ip.output->close_audio();
+    playback->output->buffer_free();
+    playback->output->buffer_free();
+    playback->output->close_audio();
   }
   /* free midi data (if it has not been freed yet) */
   i_midi_free( &midifile );
 }
 
 
-static void amidiplug_pause( InputPlayback * data, gshort paused )
+static void amidiplug_pause( InputPlayback * playback, gshort paused )
 {
   if ( paused )
   {
@@ -195,7 +195,7 @@
     DEBUGMSG( "PAUSE activated (play thread joined)\n" , midifile.playing_tick );
 
     if ( backend.autonomous_audio == FALSE )
-      amidiplug_ip.output->pause(paused);
+      playback->output->pause(paused);
 
     /* kill the sequencer */
     backend.seq_off();
@@ -212,12 +212,12 @@
     amidiplug_skipto( midifile.playing_tick );
 
     if ( backend.autonomous_audio == FALSE )
-      amidiplug_ip.output->pause(paused);
+      playback->output->pause(paused);
 
     pthread_mutex_lock( &amidiplug_playing_mutex );
     /* play play play! */
     DEBUGMSG( "PAUSE deactivated, starting play thread again\n" );
-    pthread_create(&amidiplug_play_thread, NULL, amidiplug_play_loop, NULL);
+    pthread_create(&amidiplug_play_thread, NULL, amidiplug_play_loop, playback);
     /* this cond is used to avoid race conditions */
     while ( amidiplug_playing_status != AMIDIPLUG_PLAY )
       pthread_cond_wait( &amidiplug_playing_cond , &amidiplug_playing_mutex );
@@ -226,7 +226,7 @@
 }
 
 
-static void amidiplug_seek( InputPlayback * data, gint time )
+static void amidiplug_seek( InputPlayback * playback, gint time )
 {
   DEBUGMSG( "SEEK requested (time %i), pausing song...\n" , time );
   pthread_mutex_lock( &amidiplug_playing_mutex );
@@ -254,25 +254,25 @@
   amidiplug_skipto( midifile.playing_tick );
 
   if ( backend.autonomous_audio == FALSE )
-    amidiplug_ip.output->flush(time * 1000);
+    playback->output->flush(time * 1000);
 
   /* play play play! */
   DEBUGMSG( "SEEK done, starting play thread again\n" );
-  pthread_create(&amidiplug_play_thread, NULL, amidiplug_play_loop, NULL);
+  pthread_create(&amidiplug_play_thread, NULL, amidiplug_play_loop, playback);
 }
 
 
-static gint amidiplug_get_time( InputPlayback *data )
+static gint amidiplug_get_time( InputPlayback *playback )
 {
   if ( backend.autonomous_audio == FALSE )
   {
     pthread_mutex_lock( &amidiplug_playing_mutex );
     if (( amidiplug_playing_status == AMIDIPLUG_PLAY ) ||
         ( amidiplug_playing_status == AMIDIPLUG_PAUSE ) ||
-        (( amidiplug_playing_status == AMIDIPLUG_STOP ) && ( amidiplug_ip.output->buffer_playing() )))
+        (( amidiplug_playing_status == AMIDIPLUG_STOP ) && ( playback->output->buffer_playing() )))
     {
       pthread_mutex_unlock( &amidiplug_playing_mutex );
-      return amidiplug_ip.output->output_time();
+      return playback->output->output_time();
     }
     else if ( amidiplug_playing_status == AMIDIPLUG_STOP )
     {
@@ -318,23 +318,25 @@
 }
 
 
-static void amidiplug_get_volume( gint * l_p , gint * r_p )
+static gint amidiplug_get_volume( gint * l_p , gint * r_p )
 {
   if ( backend.autonomous_audio == TRUE )
+  {
     backend.audio_volume_get( l_p , r_p );
-  else
-    amidiplug_ip.output->get_volume( l_p , r_p );
-  return;
+    return 1;
+  }
+  return 0;
 }
 
 
-static void amidiplug_set_volume( gint  l , gint  r )
+static gint amidiplug_set_volume( gint  l , gint  r )
 {
   if ( backend.autonomous_audio == TRUE )
+  {
     backend.audio_volume_set( l , r );
-  else
-    amidiplug_ip.output->set_volume( l , r );
-  return;
+    return 1;
+  }
+  return 0;
 }
 
 
@@ -359,16 +361,16 @@
 
     i_midi_free( &mf );
   }
-  else  
+  else
     *length = -1;
 
   return;
 }
 
 
-static void amidiplug_play( InputPlayback * data)
+static void amidiplug_play( InputPlayback * playback)
 {
-  gchar * filename = data->filename;
+  gchar * filename = playback->filename;
   gint port_count = 0;
   gint au_samplerate = -1, au_bitdepth = -1, au_channels = -1;
 
@@ -390,7 +392,7 @@
   if ( backend.autonomous_audio == FALSE )
   {
     DEBUGMSG( "PLAY requested, opening audio output plugin\n" );
-    amidiplug_ip.output->open_audio( FMT_S16_NE , au_samplerate , au_channels );
+    playback->output->open_audio( FMT_S16_NE , au_samplerate , au_channels );
   }
 
   DEBUGMSG( "PLAY requested, midifile init\n" );
@@ -473,7 +475,7 @@
       /* play play play! */
       DEBUGMSG( "PLAY requested, starting play thread\n" );
       amidiplug_playing_status = AMIDIPLUG_PLAY;
-      pthread_create(&amidiplug_play_thread, NULL, amidiplug_play_loop, NULL);
+      pthread_create(&amidiplug_play_thread, NULL, amidiplug_play_loop, playback);
       break;
     }
 
@@ -492,6 +494,7 @@
 
 void * amidiplug_play_loop( void * arg )
 {
+  InputPlayback *playback = arg;
   gint i = 0;
   gboolean rewind = FALSE;
 
@@ -519,7 +522,7 @@
 
   if ( backend.autonomous_audio == FALSE )
   {
-    pthread_create(&amidiplug_audio_thread, NULL, amidiplug_audio_loop, NULL);
+    pthread_create(&amidiplug_audio_thread, NULL, amidiplug_audio_loop, playback);
   }
 
   /* common settings for all our events */
@@ -739,6 +742,7 @@
 
 void * amidiplug_audio_loop( void * arg )
 {
+  InputPlayback *playback = arg;
   gboolean going = 1;
   gpointer buffer = NULL;
   gint buffer_size = 0;
@@ -746,9 +750,9 @@
   {
     if ( backend.seq_output( &buffer , &buffer_size ) )
     {
-      while( ( amidiplug_ip.output->buffer_free() < buffer_size ) && ( going == TRUE ) )
+      while( ( playback->output->buffer_free() < buffer_size ) && ( going == TRUE ) )
         G_USLEEP(10000);
-      produce_audio( amidiplug_ip.output->written_time() ,
+      produce_audio( playback->output->written_time() ,
                      FMT_S16_NE , 2 , buffer_size , buffer , &going );
     }
     pthread_mutex_lock( &amidiplug_playing_mutex );
--- a/src/amidi-plug/amidi-plug.h	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/amidi-plug/amidi-plug.h	Sun Jan 28 21:09:12 2007 -0800
@@ -77,8 +77,8 @@
 static void amidiplug_pause( InputPlayback *, gshort );
 static void amidiplug_seek( InputPlayback *, gint );
 static gint amidiplug_get_time( InputPlayback * );
-static void amidiplug_get_volume( gint * , gint * );
-static void amidiplug_set_volume( gint , gint );
+static gint amidiplug_get_volume( gint * , gint * );
+static gint amidiplug_set_volume( gint , gint );
 static void amidiplug_get_song_info( gchar * , gchar ** , gint * );
 static void amidiplug_file_info_box( gchar * );
 
--- a/src/cdaudio/cdaudio.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/cdaudio/cdaudio.c	Sun Jan 28 21:09:12 2007 -0800
@@ -117,8 +117,8 @@
 static int get_time(InputPlayback *playback);
 static void get_song_info(char *filename, char **title, int *length);
 static TitleInput *get_song_tuple(char *filename);
-static void get_volume(int *l, int *r);
-static void set_volume(int l, int r);
+static gint get_volume(int *l, int *r);
+static gint set_volume(int l, int r);
 static void cleanup(void);
 void cdda_fileinfo(char *filename);
 
@@ -857,8 +857,9 @@
 }
 
 static void *
-dae_play_loop(void *arg)
+dae_play_loop(void *data)
 {
+    InputPlayback *playback = data;
     char *buffer = g_malloc(CD_FRAMESIZE_RAW * CDDA_DAE_FRAMES);
     int pos = LBA(cdda_playing.cd_toc.track[cdda_playing.track]);
     int end, frames;
@@ -873,7 +874,7 @@
         char *data;
 
         if (dae_data.seek != -1) {
-            cdda_ip.output->flush(dae_data.seek * 1000);
+	    playback->output->flush(dae_data.seek * 1000);
             pos = LBA(cdda_playing.cd_toc.track[cdda_playing.track])
                 + dae_data.seek * 75;
             dae_data.seek = -1;
@@ -909,21 +910,21 @@
         data = buffer;
         while (cdda_playing.playing && left > 0 && dae_data.seek == -1) {
             int cur = MIN(512 * 2 * 2, left);
-            cdda_ip.add_vis_pcm(cdda_ip.output->written_time(),
+            cdda_ip.add_vis_pcm(playback->output->written_time(),
                                 FMT_S16_LE, 2, cur, data);
-            while (cdda_ip.output->buffer_free() < cur &&
+            while (playback->output->buffer_free() < cur &&
                    cdda_playing.playing && dae_data.seek == -1)
                 xmms_usleep(30000);
             if (cdda_playing.playing && dae_data.seek == -1)
-                produce_audio(cdda_ip.output->written_time(), FMT_S16_LE, 2, cur, data, &cdda_playing.playing);
+                produce_audio(playback->output->written_time(), FMT_S16_LE, 2, cur, data, &cdda_playing.playing);
             left -= cur;
             data += cur;
         }
         pos += frames;
     }
 
-    cdda_ip.output->buffer_free();
-    cdda_ip.output->buffer_free();
+    playback->output->buffer_free();
+    playback->output->buffer_free();
     g_free(buffer);
 
     g_thread_exit(NULL);
@@ -931,9 +932,9 @@
 }
 
 static void
-dae_play(void)
+dae_play(InputPlayback *playback)
 {
-    if (cdda_ip.output->open_audio(FMT_S16_LE, 44100, 2) == 0) {
+    if (playback->output->open_audio(FMT_S16_LE, 44100, 2) == 0) {
         dae_data.audio_error = TRUE;
         cdda_playing.playing = FALSE;
         return;
@@ -941,7 +942,7 @@
     dae_data.seek = -1;
     dae_data.eof = FALSE;
     dae_data.audio_error = FALSE;
-    dae_data.thread = g_thread_create(dae_play_loop, NULL, TRUE, NULL);
+    dae_data.thread = g_thread_create(dae_play_loop, playback, TRUE, NULL);
 }
 
 static void
@@ -1002,7 +1003,7 @@
 
     cdda_playing.playing = TRUE;
     if (drive->dae)
-        dae_play();
+        dae_play(playback);
     else
         seek(playback, 0);
     return;
@@ -1091,7 +1092,7 @@
 }
 
 static void
-stop(InputPlayback * data)
+stop(InputPlayback * playback)
 {
     struct timeout *to_info;
     if (cdda_playing.fd < 0)
@@ -1101,7 +1102,7 @@
 
     if (cdda_playing.drive.dae) {
         g_thread_join(dae_data.thread);
-        cdda_ip.output->close_audio();
+        playback->output->close_audio();
     }
     else
         ioctl(cdda_playing.fd, XMMS_PAUSE, 0);
@@ -1119,14 +1120,14 @@
 }
 
 static void
-cdda_pause(InputPlayback *data, short p)
+cdda_pause(InputPlayback *playback, short p)
 {
     if (cdda_playing.drive.dae) {
-        cdda_ip.output->pause(p);
+        playback->output->pause(p);
         return;
     }
     if (p) {
-        pause_time = get_time(data);
+        pause_time = get_time(playback);
         ioctl(cdda_playing.fd, XMMS_PAUSE, 0);
     }
     else {
@@ -1193,14 +1194,14 @@
 }
 
 static int
-get_time_dae(void)
+get_time_dae(InputPlayback *playback)
 {
     if (dae_data.audio_error)
         return -2;
     if (!cdda_playing.playing ||
-        (dae_data.eof && !cdda_ip.output->buffer_playing()))
+        (dae_data.eof && !playback->output->buffer_playing()))
         return -1;
-    return cdda_ip.output->output_time();
+    return playback->output->output_time();
 }
 
 static int
@@ -1210,7 +1211,7 @@
         return -1;
 
     if (cdda_playing.drive.dae)
-        return get_time_dae();
+        return get_time_dae(playback);
     else
         return get_time_analog();
 }
@@ -1324,24 +1325,26 @@
 #endif
 
 
-static void
+static gint
 get_volume(int *l, int *r)
 {
     if (cdda_playing.drive.dae)
-        cdda_ip.output->get_volume(l, r);
+        return 0;
     else if (cdda_playing.drive.mixer == CDDA_MIXER_OSS)
         oss_get_volume(l, r, cdda_playing.drive.oss_mixer);
     else if (cdda_playing.drive.mixer == CDDA_MIXER_DRIVE)
         drive_get_volume(l, r);
+    return 1;
 }
 
-static void
+static gint
 set_volume(int l, int r)
 {
     if (cdda_playing.drive.dae)
-        cdda_ip.output->set_volume(l, r);
+        return 0;
     else if (cdda_playing.drive.mixer == CDDA_MIXER_OSS)
         oss_set_volume(l, r, cdda_playing.drive.oss_mixer);
     else if (cdda_playing.drive.mixer == CDDA_MIXER_DRIVE)
         drive_set_volume(l, r);
+    return 1;
 }
--- a/src/console/Audacious_Driver.cxx	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/console/Audacious_Driver.cxx	Sun Jan 28 21:09:12 2007 -0800
@@ -254,8 +254,9 @@
 
 // Playback
 
-static void* play_loop_track( gpointer )
+static void* play_loop_track( gpointer arg )
 {
+        InputPlayback *playback = (InputPlayback *) arg;
 	g_static_mutex_lock( &playback_mutex );
 	
 	while ( console_ip_is_going && !emu->track_ended() )
@@ -265,7 +266,7 @@
 		pending_seek = -1; // TODO: use atomic swap
 		if ( s >= 0 )
 		{
-			console_ip.output->flush( s * 1000 );
+			playback->output->flush( s * 1000 );
 			emu->seek( s * 1000 );
 		}
 		
@@ -275,14 +276,14 @@
 		Music_Emu::sample_t buf [buf_size];
 		emu->play( buf_size, buf );
 		
-		produce_audio( console_ip.output->written_time(), 
+		produce_audio( playback->output->written_time(), 
 			FMT_S16_NE, 1, sizeof buf, buf, 
 			&console_ip_is_going );
 	}
 	
 	// stop playing
 	unload_file();
-	console_ip.output->close_audio();
+	playback->output->close_audio();
 	console_ip_is_going = 0;
 	g_static_mutex_unlock( &playback_mutex );
 	// TODO: should decode_thread be cleared here?
@@ -290,9 +291,9 @@
 	return NULL;
 }
 
-static void play_file( InputPlayback *data )
+static void play_file( InputPlayback *playback )
 {
-        char* path = data->filename;
+        char* path = playback->filename;
 	unload_file();
 	
 	// identify file
@@ -355,7 +356,7 @@
 	if ( log_err( fh.emu->start_track( fh.track ) ) )
 		return;
 	log_warning( fh.emu );
-	if ( !console_ip.output->open_audio( FMT_S16_NE, sample_rate, 2 ) )
+	if ( !playback->output->open_audio( FMT_S16_NE, sample_rate, 2 ) )
 		return;
 	
 	// set fade time
@@ -380,7 +381,7 @@
 	pending_seek = time;
 }
 
-static void console_stop(InputPlayback *data)
+static void console_stop(InputPlayback *playback)
 {
 	console_ip_is_going = 0;
 	if ( decode_thread )
@@ -388,18 +389,18 @@
 		g_thread_join( decode_thread );
 		decode_thread = NULL;
 	}
-	console_ip.output->close_audio();
+	playback->output->close_audio();
 	unload_file();
 }
 
-static void console_pause(InputPlayback * data, gshort p)
+static void console_pause(InputPlayback * playback, gshort p)
 {
-	console_ip.output->pause(p);
+	playback->output->pause(p);
 }
 
-static int get_time(InputPlayback *data)
+static int get_time(InputPlayback *playback)
 {
-	return console_ip_is_going ? console_ip.output->output_time() : -1;
+	return console_ip_is_going ? playback->output->output_time() : -1;
 }
 
 static gint is_our_file_from_vfs( gchar* path, VFSFile* fd )
--- a/src/flac112/plugin.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/flac112/plugin.c	Sun Jan 28 21:09:12 2007 -0800
@@ -93,11 +93,11 @@
 static void FLAC_XMMS__init();
 static int  FLAC_XMMS__is_our_file(char *filename);
 static int  FLAC_XMMS__is_our_file_from_vfs(char *filename, VFSFile *vfsfile);
-static void FLAC_XMMS__play_file(char *filename);
-static void FLAC_XMMS__stop();
-static void FLAC_XMMS__pause(short p);
-static void FLAC_XMMS__seek(int time);
-static int  FLAC_XMMS__get_time();
+static void FLAC_XMMS__play_file(InputPlayback *playback);
+static void FLAC_XMMS__stop(InputPlayback *playback);
+static void FLAC_XMMS__pause(InputPlayback *playback, short p);
+static void FLAC_XMMS__seek(InputPlayback *playback, int time);
+static int  FLAC_XMMS__get_time(InputPlayback *playback);
 static void FLAC_XMMS__cleanup();
 static void FLAC_XMMS__get_song_info(char *filename, char **title, int *length);
 
@@ -280,8 +280,9 @@
 	return result;
 }
 
-void FLAC_XMMS__play_file(char *filename)
+void FLAC_XMMS__play_file(InputPlayback *playback)
 {
+        char *filename = playback->filename;
 	sample_buffer_first_ = sample_buffer_last_ = 0;
 	audio_error_ = false;
 	file_info_.abort_flag = false;
@@ -331,7 +332,7 @@
 	FLAC__replaygain_synthesis__init_dither_context(&file_info_.dither_context, file_info_.sample_format_bytes_per_sample * 8, flac_cfg.output.resolution.replaygain.noise_shaping);
 	file_info_.is_playing = true;
 
-	if(flac_ip.output->open_audio(file_info_.sample_format, file_info_.sample_rate, file_info_.channels) == 0) {
+	if(playback->output->open_audio(file_info_.sample_format, file_info_.sample_rate, file_info_.channels) == 0) {
 		audio_error_ = true;
 		file_decoder_safe_decoder_finish_(decoder_);
 		return;
@@ -342,10 +343,10 @@
 
 	file_info_.seek_to_in_sec = -1;
 	file_info_.play_thread_open = true;
-	decode_thread_ = g_thread_create((GThreadFunc)play_loop_, NULL, TRUE, NULL);
+	decode_thread_ = g_thread_create((GThreadFunc)play_loop_, playback, TRUE, NULL);
 }
 
-void FLAC_XMMS__stop()
+void FLAC_XMMS__stop(InputPlayback *playback)
 {
 	if(file_info_.is_playing) {
 		file_info_.is_playing = false;
@@ -353,17 +354,17 @@
 			file_info_.play_thread_open = false;
 			g_thread_join(decode_thread_);
 		}
-		flac_ip.output->close_audio();
+		playback->output->close_audio();
 		file_decoder_safe_decoder_finish_(decoder_);
 	}
 }
 
-void FLAC_XMMS__pause(short p)
+void FLAC_XMMS__pause(InputPlayback *playback, short p)
 {
-	flac_ip.output->pause(p);
+        playback->output->pause(p);
 }
 
-void FLAC_XMMS__seek(int time)
+void FLAC_XMMS__seek(InputPlayback *playback, int time)
 {
 	file_info_.seek_to_in_sec = time;
 	file_info_.eof = false;
@@ -372,14 +373,14 @@
 		xmms_usleep(10000);
 }
 
-int FLAC_XMMS__get_time()
+int FLAC_XMMS__get_time(InputPlayback *playback)
 {
 	if(audio_error_)
 		return -2;
-	if(!file_info_.is_playing || (file_info_.eof && !flac_ip.output->buffer_playing()))
+	if(!file_info_.is_playing || (file_info_.eof && !playback->output->buffer_playing()))
 		return -1;
 	else
-		return flac_ip.output->output_time();
+		return playback->output->output_time();
 }
 
 void FLAC_XMMS__cleanup()
@@ -443,11 +444,10 @@
 
 void *play_loop_(void *arg)
 {
+        InputPlayback *playback = arg;
 	unsigned written_time_last = 0, bh_index_last_w = 0, bh_index_last_o = BITRATE_HIST_SIZE, blocksize = 1;
 	FLAC__uint64 decode_position_last = 0, decode_position_frame_last = 0, decode_position_frame = 0;
 
-	(void)arg;
-
 	while(file_info_.is_playing) {
 		if(!file_info_.eof) {
 			while(sample_buffer_last_ - sample_buffer_first_ < SAMPLES_PER_WRITE) {
@@ -477,15 +477,15 @@
 				FLAC__uint64 decode_position;
 
 				sample_buffer_first_ += n;
-				while(flac_ip.output->buffer_free() < (int)bytes && file_info_.is_playing && file_info_.seek_to_in_sec == -1)
+				while(playback->output->buffer_free() < (int)bytes && file_info_.is_playing && file_info_.seek_to_in_sec == -1)
 					xmms_usleep(10000);
 				if(file_info_.is_playing && file_info_.seek_to_in_sec == -1)
-					produce_audio(flac_ip.output->written_time(), file_info_.sample_format,
+					produce_audio(playback->output->written_time(), file_info_.sample_format,
 						file_info_.channels, bytes, sample_buffer_start, NULL);
 
 				/* compute current bitrate */
 
-				written_time = flac_ip.output->written_time();
+				written_time = playback->output->written_time();
 				bh_index_w = written_time / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
 				if(bh_index_w != bh_index_last_w) {
 					bh_index_last_w = bh_index_w;
@@ -509,8 +509,8 @@
 			const double distance = (double)file_info_.seek_to_in_sec * 1000.0 / (double)file_info_.length_in_msec;
 			unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples);
 			if(FLAC__seekable_stream_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) {
-				flac_ip.output->flush(file_info_.seek_to_in_sec * 1000);
-				bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
+				playback->output->flush(file_info_.seek_to_in_sec * 1000);
+				bh_index_last_w = bh_index_last_o = playback->output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
 				if(!FLAC__seekable_stream_decoder_get_decode_position(decoder_, &decode_position_frame))
 					decode_position_frame = 0;
 				file_info_.seek_to_in_sec = -1;
@@ -521,7 +521,7 @@
 		else if ( !flac_cfg.title.disable_bitrate_update )
 		{
 			/* display the right bitrate from history */
-			unsigned bh_index_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
+			unsigned bh_index_o = playback->output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
 			if(bh_index_o != bh_index_last_o && bh_index_o != bh_index_last_w && bh_index_o != (bh_index_last_w + 1) % BITRATE_HIST_SIZE) {
 				bh_index_last_o = bh_index_o;
 				flac_ip.set_info(file_info_.title, file_info_.length_in_msec, bitrate_history_[bh_index_o], file_info_.sample_rate, file_info_.channels);
@@ -532,8 +532,8 @@
 	file_decoder_safe_decoder_finish_(decoder_);
 
 	/* are these two calls necessary? */
-	flac_ip.output->buffer_free();
-	flac_ip.output->buffer_free();
+	playback->output->buffer_free();
+	playback->output->buffer_free();
 
 	g_free(file_info_.title);
 
--- a/src/flac113/plugin.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/flac113/plugin.c	Sun Jan 28 21:09:12 2007 -0800
@@ -274,8 +274,9 @@
 	return result;
 }
 
-void FLAC_XMMS__play_file(char *filename)
+void FLAC_XMMS__play_file(InputPlayback *playback)
 {
+        char *filename = playback->filename;
 	sample_buffer_first_ = sample_buffer_last_ = 0;
 	audio_error_ = false;
 	stream_data_.abort_flag = false;
@@ -325,7 +326,7 @@
 	FLAC__replaygain_synthesis__init_dither_context(&stream_data_.dither_context, stream_data_.sample_format_bytes_per_sample * 8, flac_cfg.output.resolution.replaygain.noise_shaping);
 	stream_data_.is_playing = true;
 
-	if(flac_ip.output->open_audio(stream_data_.sample_format, stream_data_.sample_rate, stream_data_.channels) == 0) {
+	if(playback->output->open_audio(stream_data_.sample_format, stream_data_.sample_rate, stream_data_.channels) == 0) {
 		audio_error_ = true;
 		safe_decoder_finish_(decoder_);
 		return;
@@ -339,7 +340,7 @@
 	decode_thread_ = g_thread_create((GThreadFunc)play_loop_, NULL, TRUE, NULL);
 }
 
-void FLAC_XMMS__stop()
+void FLAC_XMMS__stop(InputPlayback *playback)
 {
 	if(stream_data_.is_playing) {
 		stream_data_.is_playing = false;
@@ -347,17 +348,17 @@
 			stream_data_.play_thread_open = false;
 			g_thread_join(decode_thread_);
 		}
-		flac_ip.output->close_audio();
+		playback->output->close_audio();
 		safe_decoder_finish_(decoder_);
 	}
 }
 
-void FLAC_XMMS__pause(short p)
+void FLAC_XMMS__pause(InputPlayback *playback, short p)
 {
-	flac_ip.output->pause(p);
+	playback->output->pause(p);
 }
 
-void FLAC_XMMS__seek(int time)
+void FLAC_XMMS__seek(InputPlayback *playback, int time)
 {
 	stream_data_.seek_to_in_sec = time;
 	stream_data_.eof = false;
@@ -366,14 +367,14 @@
 		xmms_usleep(10000);
 }
 
-int FLAC_XMMS__get_time()
+int FLAC_XMMS__get_time(InputPlayback *playback)
 {
 	if(audio_error_)
 		return -2;
-	if(!stream_data_.is_playing || (stream_data_.eof && !flac_ip.output->buffer_playing()))
+	if(!stream_data_.is_playing || (stream_data_.eof && !playback->output->buffer_playing()))
 		return -1;
 	else
-		return flac_ip.output->output_time();
+		return playback->output->output_time();
 }
 
 void FLAC_XMMS__cleanup()
@@ -437,11 +438,10 @@
 
 static void *play_loop_(void *arg)
 {
+        InputPlayback *playback = arg;
 	unsigned written_time_last = 0, bh_index_last_w = 0, bh_index_last_o = BITRATE_HIST_SIZE, blocksize = 1;
 	FLAC__uint64 decode_position_last = 0, decode_position_frame_last = 0, decode_position_frame = 0;
 
-	(void)arg;
-
 	while(stream_data_.is_playing) {
 		if(!stream_data_.eof) {
 			while(sample_buffer_last_ - sample_buffer_first_ < SAMPLES_PER_WRITE) {
@@ -471,15 +471,15 @@
 				FLAC__uint64 decode_position;
 
 				sample_buffer_first_ += n;
-				while(flac_ip.output->buffer_free() < (int)bytes && stream_data_.is_playing && stream_data_.seek_to_in_sec == -1)
+				while(playback->output->buffer_free() < (int)bytes && stream_data_.is_playing && stream_data_.seek_to_in_sec == -1)
 					xmms_usleep(10000);
 				if(stream_data_.is_playing && stream_data_.seek_to_in_sec == -1)
-					produce_audio(flac_ip.output->written_time(), stream_data_.sample_format,
+					produce_audio(playback->output->written_time(), stream_data_.sample_format,
 						stream_data_.channels, bytes, sample_buffer_start, NULL);
 
 				/* compute current bitrate */
 
-				written_time = flac_ip.output->written_time();
+				written_time = playback->output->written_time();
 				bh_index_w = written_time / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
 				if(bh_index_w != bh_index_last_w) {
 					bh_index_last_w = bh_index_w;
@@ -505,8 +505,8 @@
 			if(stream_data_.total_samples > 0 && target_sample >= stream_data_.total_samples)
 				target_sample = stream_data_.total_samples - 1;
 			if(FLAC__stream_decoder_seek_absolute(decoder_, target_sample)) {
-				flac_ip.output->flush(stream_data_.seek_to_in_sec * 1000);
-				bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
+				playback->output->flush(stream_data_.seek_to_in_sec * 1000);
+				bh_index_last_w = bh_index_last_o = playback->output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
 				if(!FLAC__stream_decoder_get_decode_position(decoder_, &decode_position_frame))
 					decode_position_frame = 0;
 				stream_data_.eof = false;
@@ -524,7 +524,7 @@
 		else if ( !flac_cfg.title.disable_bitrate_update )
 		{
 			/* display the right bitrate from history */
-			unsigned bh_index_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
+			unsigned bh_index_o = playback->output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE;
 			if(bh_index_o != bh_index_last_o && bh_index_o != bh_index_last_w && bh_index_o != (bh_index_last_w + 1) % BITRATE_HIST_SIZE) {
 				bh_index_last_o = bh_index_o;
 				flac_ip.set_info(stream_data_.title, stream_data_.length_in_msec, bitrate_history_[bh_index_o], stream_data_.sample_rate, stream_data_.channels);
@@ -535,8 +535,8 @@
 	safe_decoder_finish_(decoder_);
 
 	/* are these two calls necessary? */
-	flac_ip.output->buffer_free();
-	flac_ip.output->buffer_free();
+	playback->output->buffer_free();
+	playback->output->buffer_free();
 
 	g_free(stream_data_.title);
 
--- a/src/metronom/metronom.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/metronom/metronom.c	Sun Jan 28 21:09:12 2007 -0800
@@ -98,7 +98,8 @@
 static void* play_loop(void *arg)
 {
 	gint16 data[BUF_SAMPLES];
-	metronom_t *pmetronom=(metronom_t *)arg;
+	InputPlayback *playback = arg;
+	metronom_t *pmetronom=(metronom_t *)playback->data;
 	gint i;
 	
 	gint16 t = 0,tact;
@@ -140,21 +141,21 @@
 			datagoal=(datamiddle+7*datagoal)/8;
 			t++;
 		}
-		while(metronom_ip.output->buffer_free() < BUF_BYTES && going)
+		while(playback->output->buffer_free() < BUF_BYTES && going)
 			xmms_usleep(30000);
 		if (going)
-			produce_audio(metronom_ip.output->written_time(), FMT_S16_LE, 1, BUF_BYTES, data, &going);
+			produce_audio(playback->output->written_time(), FMT_S16_LE, 1, BUF_BYTES, data, &going);
 	}
 	/* Make sure the output plugin stops prebuffering */
 	free(arg);
-	metronom_ip.output->buffer_free();
-	metronom_ip.output->buffer_free();
+	playback->output->buffer_free();
+	playback->output->buffer_free();
 	g_thread_exit(NULL);
 }
 
-static void metronom_play(InputPlayback *data)
+static void metronom_play(InputPlayback *playback)
 {
-        char *filename = data->filename;
+        char *filename = playback->filename;
 	gchar *name;
 	size_t count;	
 	metronom_t *pmetronom;
@@ -184,7 +185,7 @@
 	
 	going = TRUE;
 	audio_error = FALSE;
-	if (metronom_ip.output->open_audio(FMT_S16_LE, 44100, 1) == 0)
+	if (playback->output->open_audio(FMT_S16_LE, 44100, 1) == 0)
 	{
 		audio_error = TRUE;
 		going = FALSE;
@@ -197,31 +198,32 @@
 	}
 	metronom_ip.set_info(name, -1, 16 * 44100, 44100, 1);
 	g_free(name);
-	play_thread = g_thread_create((GThreadFunc)play_loop, pmetronom, TRUE, NULL);
+	playback->data = pmetronom;
+	play_thread = g_thread_create((GThreadFunc)play_loop, playback, TRUE, NULL);
 }
 
-static void metronom_stop(InputPlayback *data)
+static void metronom_stop(InputPlayback *playback)
 {
 	if (going)
 	{
 		going = FALSE;
 		g_thread_join(play_thread);
-		metronom_ip.output->close_audio();
+		playback->output->close_audio();
 	}
 }
 
-static void metronom_pause(InputPlayback *data, short paused)
+static void metronom_pause(InputPlayback *playback, short paused)
 {
-	metronom_ip.output->pause(paused);
+	playback->output->pause(paused);
 }
 
-static int metronom_get_time(InputPlayback *data)
+static int metronom_get_time(InputPlayback *playback)
 {
 	if (audio_error)
 		return -2;
-	if (!going && !metronom_ip.output->buffer_playing())
+	if (!going && !playback->output->buffer_playing())
 		return -1;
-	return metronom_ip.output->output_time();
+	return playback->output->output_time();
 }
 
 static void metronom_song_info(char *filename, char **title, int *length)
--- a/src/modplug/plugin.cxx	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/modplug/plugin.cxx	Sun Jan 28 21:09:12 2007 -0800
@@ -26,7 +26,7 @@
 static void PlayFile(InputPlayback *data)
 {
         char* aFilename = data->filename;
-	gModplugXMMS.SetOutputPlugin(*gModPlug.output);
+	gModplugXMMS.SetOutputPlugin(*data->output);
 	gModplugXMMS.PlayFile(aFilename);
 }
 
--- a/src/mpg123/layer1.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/mpg123/layer1.c	Sun Jan 28 21:09:12 2007 -0800
@@ -118,7 +118,7 @@
 }
 
 int
-mpgdec_do_layer1(struct frame *fr)
+mpgdec_do_layer1(InputPlayback *playback, struct frame *fr)
 {
     int i, stereo = fr->stereo;
     unsigned int balloc[2 * SBLIMIT];
@@ -152,7 +152,7 @@
 	psycho_process(mpgdec_pcm_sample, mpgdec_pcm_point, mpgdec_cfg.channels == 2 ? fr->stereo : 1);
 #endif
         if (mpgdec_info->output_audio && mpgdec_info->jump_to_time == -1) {
-            produce_audio(mpgdec_ip.output->written_time(),
+            produce_audio(playback->output->written_time(),
                           mpgdec_cfg.resolution ==
                           16 ? FMT_S16_NE : FMT_U8,
                           mpgdec_cfg.channels ==
--- a/src/mpg123/layer2.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/mpg123/layer2.c	Sun Jan 28 21:09:12 2007 -0800
@@ -287,7 +287,7 @@
 
 
 int
-mpgdec_do_layer2 (struct frame *fr)
+mpgdec_do_layer2 (InputPlayback *playback, struct frame *fr)
 {
   int i, j;
   int stereo = fr->stereo;
@@ -335,7 +335,7 @@
 #endif
   if (mpgdec_info->output_audio)
     {
-      produce_audio (mpgdec_ip.output->written_time (),
+      produce_audio (playback->output->written_time (),
 		     mpgdec_cfg.resolution == 16 ? FMT_S16_NE : FMT_U8,
 		     mpgdec_cfg.channels == 2 ? fr->stereo : 1,
 		     mpgdec_pcm_point, mpgdec_pcm_sample, &mpgdec_pcm_point);
--- a/src/mpg123/layer3.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/mpg123/layer3.c	Sun Jan 28 21:09:12 2007 -0800
@@ -1709,7 +1709,7 @@
     }
 }
 int
-mpgdec_do_layer3(struct frame *fr)
+mpgdec_do_layer3(InputPlayback *playback, struct frame *fr)
 {
     int gr, ch, ss;
     int scalefacs[2][39];       /* max 39 for short[13][3] mode, mixed: 38, long: 22 */
@@ -1849,7 +1849,7 @@
 #endif
 
         if (mpgdec_info->output_audio && mpgdec_info->jump_to_time == -1) {
-            produce_audio(mpgdec_ip.output->written_time(),
+            produce_audio(playback->output->written_time(),
                           mpgdec_cfg.resolution ==
                           16 ? FMT_S16_NE : FMT_U8,
                           mpgdec_cfg.channels ==
--- a/src/mpg123/mpg123.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/mpg123/mpg123.c	Sun Jan 28 21:09:12 2007 -0800
@@ -354,13 +354,13 @@
 }
 
 static void
-play_frame(struct frame *fr)
+play_frame(InputPlayback *playback, struct frame *fr)
 {
     if (fr->error_protection) {
         bsi.wordpointer += 2;
         /*  mpgdec_getbits(16); *//* skip crc */
     }
-    if (!fr->do_layer(fr)) {
+    if (!fr->do_layer(playback, fr)) {
         skip_frames = 2;
         mpgdec_info->output_audio = FALSE;
     }
@@ -626,17 +626,17 @@
 }
 
 static int
-open_output(void)
+open_output(InputPlayback *playback)
 {
     int r;
     AFormat fmt = mpgdec_cfg.resolution == 16 ? FMT_S16_NE : FMT_U8;
 /*    int freq = mpgdec_freqs[fr.sampling_frequency] >> mpgdec_cfg.downsample; */
     int freq = mpgdec_frequency;
     int channels = mpgdec_cfg.channels == 2 ? fr.stereo : 1;
-    r = mpgdec_ip.output->open_audio(fmt, freq, channels);
+    r = playback->output->open_audio(fmt, freq, channels);
 
     if (r && dopause) {
-        mpgdec_ip.output->pause(TRUE);
+        playback->output->pause(TRUE);
         dopause = FALSE;
     }
 
@@ -675,7 +675,8 @@
     static gchar *old_title = NULL;
     gboolean have_xing_header = FALSE, vbr = FALSE;
     int disp_count = 0;
-    char *filename = arg;
+    InputPlayback *playback = arg;
+    char *filename = playback->filename;
     xing_header_t xing_header;
 
     /* This is used by fileinfo on http streams */
@@ -786,12 +787,12 @@
 
         output_opened = TRUE;
 
-        if (!open_output()) {
+        if (!open_output(playback)) {
             audio_error = TRUE;
             mpgdec_info->eof = TRUE;
         }
         else
-            play_frame(&fr);
+            play_frame(playback, &fr);
     }
 
     mpgdec_info->first_frame = FALSE;
@@ -801,7 +802,7 @@
             if (have_xing_header)
                 xp = &xing_header;
             if (mpgdec_seek(&fr, xp, vbr, mpgdec_info->jump_to_time) > -1) {
-                mpgdec_ip.output->flush(mpgdec_info->jump_to_time * 1000);
+                playback->output->flush(mpgdec_info->jump_to_time * 1000);
                 mpgdec_info->eof = FALSE;
             }
             mpgdec_info->jump_to_time = -1;
@@ -841,7 +842,7 @@
                             double rel = mpgdec_relative_pos();
                             if (rel) {
                                 mpgdec_length =
-                                    mpgdec_ip.output->written_time() / rel;
+                                    playback->output->written_time() / rel;
                                 vbr = TRUE;
                             }
 
@@ -864,7 +865,7 @@
                 }
                 else
                     disp_count--;
-                play_frame(&fr);
+                play_frame(playback, &fr);
 
 		if (mpgdec_info->filesize == 0)
 	        {
@@ -896,8 +897,8 @@
 		}
             }
             else {
-                mpgdec_ip.output->buffer_free();
-                mpgdec_ip.output->buffer_free();
+                playback->output->buffer_free();
+                playback->output->buffer_free();
                 mpgdec_info->eof = TRUE;
                 g_usleep(10000);
             }
@@ -915,7 +916,7 @@
     mpgdec_title = NULL;
     mpgdec_stream_close();
     if (output_opened && !audio_error)
-        mpgdec_ip.output->close_audio();
+        playback->output->close_audio();
     g_free(mpgdec_pcm_sample);
     mpgdec_filename = NULL;
     g_free(filename);
@@ -924,9 +925,8 @@
 }
 
 static void
-play_file(InputPlayback *data)
+play_file(InputPlayback *playback)
 {
-    char *filename = data->filename;
     memset(&fr, 0, sizeof(struct frame));
     memset(&temp_fr, 0, sizeof(struct frame));
 
@@ -940,7 +940,7 @@
     output_opened = FALSE;
     dopause = FALSE;
 
-    decode_thread = g_thread_create(decode_loop, g_strdup(filename), TRUE,
+    decode_thread = g_thread_create(decode_loop, playback, TRUE,
                                     NULL);
 }
 
@@ -965,25 +965,25 @@
 }
 
 static void
-do_pause(InputPlayback * data, short p)
+do_pause(InputPlayback * playback, short p)
 {
     if (output_opened)
-        mpgdec_ip.output->pause(p);
+        playback->output->pause(p);
     else
         dopause = p;
 }
 
 static int
-get_time(InputPlayback * data)
+get_time(InputPlayback * playback)
 {
     if (audio_error)
         return -2;
     if (!mpgdec_info)
         return -1;
     if (!mpgdec_info->going
-        || (mpgdec_info->eof && !mpgdec_ip.output->buffer_playing()))
+        || (mpgdec_info->eof && !playback->output->buffer_playing()))
         return -1;
-    return mpgdec_ip.output->output_time();
+    return playback->output->output_time();
 }
 
 static void
--- a/src/mpg123/mpg123.h	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/mpg123/mpg123.h	Sun Jan 28 21:09:12 2007 -0800
@@ -163,7 +163,7 @@
     int down_sample;
     int header_change;
     int lay;
-    int (*do_layer) (struct frame * fr);
+    int (*do_layer) (InputPlayback * playback, struct frame * fr);
     int error_protection;
     int bitrate_index;
     int sampling_frequency;
@@ -291,9 +291,9 @@
                                         xing_header_t * xhead);
 int mpgdec_calc_numframes(struct frame *fr);
 
-extern int mpgdec_do_layer3(struct frame *fr);
-extern int mpgdec_do_layer2(struct frame *fr);
-extern int mpgdec_do_layer1(struct frame *fr);
+extern int mpgdec_do_layer3(InputPlayback *playback, struct frame *fr);
+extern int mpgdec_do_layer2(InputPlayback *playback, struct frame *fr);
+extern int mpgdec_do_layer1(InputPlayback *playback, struct frame *fr);
 
 extern int mpgdec_synth_1to1(mpgdec_real *, int, unsigned char *, int *);
 extern int mpgdec_synth_1to1_8bit(mpgdec_real *, int, unsigned char *, int *);
--- a/src/sexypsf/xmms.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/sexypsf/xmms.c	Sun Jan 28 21:09:12 2007 -0800
@@ -76,19 +76,21 @@
 	g_free(name);
 }
 
+static InputPlayback *playback;
+
 void sexypsf_update(unsigned char *Buffer, long count)
 {
 	int mask = ~((((16 / 8) * 2)) - 1);
 
 	while(count>0)
 	{
-		int t=sexypsf_ip.output->buffer_free() & mask;
+		int t=playback->output->buffer_free() & mask;
 		if(t>count)		
-			produce_audio(sexypsf_ip.output->written_time(), FMT_S16_NE, 2, count, Buffer, NULL);
+			produce_audio(playback->output->written_time(), FMT_S16_NE, 2, count, Buffer, NULL);
 		else
 		{
 			if(t)
-				produce_audio(sexypsf_ip.output->written_time(), FMT_S16_NE, 2, t, Buffer, NULL);
+				produce_audio(playback->output->written_time(), FMT_S16_NE, 2, t, Buffer, NULL);
 			g_usleep((count-t)*1000*5/441/2);
 		}
 		count-=t;
@@ -99,7 +101,7 @@
 		int t=(command&~(CMD_SEEK|CMD_STOP))*1000;
 
 		if(sexypsf_seek(t))
-			sexypsf_ip.output->flush(t);
+			playback->output->flush(t);
 		else	// Negative time!  Must make a C time machine.
 		{
 			sexypsf_stop();
@@ -118,25 +120,25 @@
 	sexypsf_execute();
 
 	/* We have reached the end of the song. Now what... */
-	sexypsf_ip.output->buffer_free();
-	sexypsf_ip.output->buffer_free();
+	playback->output->buffer_free();
+	playback->output->buffer_free();
 
 	while(!(command&CMD_STOP)) 
 	{
 		if(command&CMD_SEEK)
 			{
 			int t=(command&~(CMD_SEEK|CMD_STOP))*1000;
-			sexypsf_ip.output->flush(t);
+			playback->output->flush(t);
 			if(!(PSFInfo=sexypsf_load(fnsave)))
 				break;
 			sexypsf_seek(t); 
 			command&=~CMD_SEEK;
 			goto dofunky;
 			}
-		if(!sexypsf_ip.output->buffer_playing()) break;
+		if(!playback->output->buffer_playing()) break;
 			usleep(2000);
 	}
-	sexypsf_ip.output->close_audio();
+	playback->output->close_audio();
 	if(!(command&CMD_STOP)) nextsong=1;
 	g_thread_exit(NULL);
 	return(NULL);
@@ -147,9 +149,10 @@
         char *fn = data->filename;
 	if(playing)
 		return;
+	playback = data;
 	nextsong=0;
 	paused = 0;
-	if(!sexypsf_ip.output->open_audio(FMT_S16_NE, 44100, 2))
+	if(!playback->output->open_audio(FMT_S16_NE, 44100, 2))
 	{
 		puts("Error opening audio.");
 		return;
@@ -158,7 +161,7 @@
 	strcpy(fnsave,fn);
 	if(!(PSFInfo=sexypsf_load(fn)))
 	{
-		sexypsf_ip.output->close_audio();
+		playback->output->close_audio();
 		nextsong=1;
 	}
  	else
@@ -170,12 +173,12 @@
 	}
 }
 
-static void sexypsf_xmms_stop(InputPlayback * data)
+static void sexypsf_xmms_stop(InputPlayback * playback)
 {
 	if(!playing) return;
 
 	if(paused)
-		sexypsf_ip.output->pause(0);
+		playback->output->pause(0);
 	paused = 0;
 
 	command=CMD_STOP;
@@ -191,10 +194,10 @@
 	PSFInfo=NULL;
 }
 
-static void sexypsf_xmms_pause(InputPlayback * data, short p)
+static void sexypsf_xmms_pause(InputPlayback * playback, short p)
 {
 	if(!playing) return;
-	sexypsf_ip.output->pause(p);
+	playback->output->pause(p);
 	paused = p;
 }
 
@@ -204,12 +207,12 @@
 	command=CMD_SEEK|time;
 }
 
-static int sexypsf_xmms_gettime(InputPlayback *data)
+static int sexypsf_xmms_gettime(InputPlayback *playback)
 {
 	if(nextsong)
 		return(-1);
 	if(!playing) return(0);
-		return sexypsf_ip.output->output_time();
+		return playback->output->output_time();
 }
 
 static void sexypsf_xmms_getsonginfo(char *fn, char **title, int *length)
--- a/src/sid/xmms-sid.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/sid/xmms-sid.c	Sun Jan 28 21:09:12 2007 -0800
@@ -296,6 +296,7 @@
  */
 void *xs_playthread(void *argPointer)
 {
+        InputPlayback *playback = argPointer;
 	t_xs_status myStatus;
 	t_xs_tuneinfo *myTune;
 	gboolean audioOpen = FALSE, doPlay = FALSE, isFound = FALSE;
@@ -303,8 +304,6 @@
 	gint audioGot, songLength, i;
 	gchar *audioBuffer = NULL, *oversampleBuffer = NULL;
 
-	(void) argPointer;
-
 	/* Initialize */
 	XSDEBUG("entering player thread\n");
 	g_static_mutex_lock(&xs_status_mutex);
@@ -404,7 +403,7 @@
 
 
 		/* Open the audio output */
-		if (!xs_plugin_ip.output->
+		if (!playback->output->
 		    open_audio(myStatus.audioFormat, myStatus.audioFrequency, myStatus.audioChannels)) {
 			XSERR("Couldn't open XMMS audio output (fmt=%x, freq=%i, nchan=%i)!\n", myStatus.audioFormat,
 			      myStatus.audioFrequency, myStatus.audioChannels);
@@ -454,29 +453,29 @@
 				audioGot = myStatus.sidPlayer->plrFillBuffer(&myStatus, audioBuffer, XS_AUDIOBUF_SIZE);
 
 			/* I <3 visualice/haujobb */
-			produce_audio(xs_plugin_ip.output->written_time(),
+			produce_audio(playback->output->written_time(),
 				 myStatus.audioFormat, myStatus.audioChannels, audioGot, audioBuffer, NULL);
 
 			/* Wait a little */
 			while (xs_status.isPlaying &&
 			       (xs_status.currSong == myStatus.currSong) &&
-			       (xs_plugin_ip.output->buffer_free() < audioGot))
+			       (playback->output->buffer_free() < audioGot))
 				xmms_usleep(500);
 
 			/* Check if we have played enough */
 			if (xs_cfg.playMaxTimeEnable) {
 				if (xs_cfg.playMaxTimeUnknown) {
 					if ((songLength < 0) &&
-					    (xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000)))
+					    (playback->output->output_time() >= (xs_cfg.playMaxTime * 1000)))
 						myStatus.isPlaying = FALSE;
 				} else {
-					if (xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000))
+					if (playback->output->output_time() >= (xs_cfg.playMaxTime * 1000))
 						myStatus.isPlaying = FALSE;
 				}
 			}
 
 			if (songLength >= 0) {
-				if (xs_plugin_ip.output->output_time() >= (songLength * 1000))
+				if (playback->output->output_time() >= (songLength * 1000))
 					myStatus.isPlaying = FALSE;
 			}
 		}
@@ -486,7 +485,7 @@
 		/* Close audio output plugin */
 		if (audioOpen) {
 			XSDEBUG("close audio #1\n");
-			xs_plugin_ip.output->close_audio();
+			playback->output->close_audio();
 			audioOpen = FALSE;
 		}
 
@@ -499,7 +498,7 @@
 	/* Close audio output plugin */
 	if (audioOpen) {
 		XSDEBUG("close audio #2\n");
-		xs_plugin_ip.output->close_audio();
+		playback->output->close_audio();
 	}
 
 	g_free(audioBuffer);
@@ -527,8 +526,9 @@
  * Usually you would also initialize the output-plugin, but
  * this is XMMS-SID and we do it on the player thread instead.
  */
-void xs_play_file(gchar * pcFilename)
+void xs_play_file(InputPlayback *playback)
 {
+        gchar * pcFilename = playback->filename;
 	assert(xs_status.sidPlayer);
 
 	XSDEBUG("play '%s'\n", pcFilename);
@@ -552,7 +552,7 @@
 	xs_status.currSong = xs_status.tuneInfo->startTune;
 
 	/* Start the playing thread! */
-	xs_decode_thread = g_thread_create((GThreadFunc)xs_playthread, NULL, TRUE, NULL);
+	xs_decode_thread = g_thread_create((GThreadFunc)xs_playthread, playback, TRUE, NULL);
 	if (xs_decode_thread == NULL) {
 		XSERR("Couldn't start playing thread!\n");
 		xs_tuneinfo_free(xs_status.tuneInfo);
@@ -578,7 +578,7 @@
  *
  * Finally tune and other memory allocations are free'd.
  */
-void xs_stop(void)
+void xs_stop(InputPlayback *playback)
 {
 	XSDEBUG("STOP_REQ\n");
 
@@ -612,7 +612,7 @@
 /*
  * Pause/unpause the playing
  */
-void xs_pause(short pauseState)
+void xs_pause(InputPlayback *playback, short pauseState)
 {
 	g_static_mutex_lock(&xs_status_mutex);
 	/* FIXME FIX ME todo: pause should disable sub-tune controls */
@@ -620,7 +620,7 @@
 
 	xs_subctrl_close();
 	xs_fileinfo_update();
-	xs_plugin_ip.output->pause(pauseState);
+	playback->output->pause(pauseState);
 }
 
 
@@ -854,7 +854,7 @@
  * END OF SONG! Return value of -2 means error, XMMS opens an audio
  * error dialog. -1 means end of song (if one was playing currently).
  */
-gint xs_get_time(void)
+gint xs_get_time(InputPlayback *playback)
 {
 	/* If errorflag is set, return -2 to signal it to XMMS's idle callback */
 	g_static_mutex_lock(&xs_status_mutex);
@@ -878,7 +878,7 @@
 	/* Let's see what we do */
 	switch (xs_cfg.subsongControl) {
 	case XS_SSC_SEEK:
-		xs_status.lastTime = (xs_plugin_ip.output->output_time() / 1000);
+		xs_status.lastTime = (playback->output->output_time() / 1000);
 		break;
 
 #ifdef HAVE_SONG_POSITION
@@ -891,7 +891,7 @@
 	g_static_mutex_unlock(&xs_status_mutex);
 
 	/* Return output time reported by audio output plugin */
-	return xs_plugin_ip.output->output_time();
+	return playback->output->output_time();
 }
 
 
--- a/src/sid/xmms-sid.h	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/sid/xmms-sid.h	Sun Jan 28 21:09:12 2007 -0800
@@ -176,11 +176,11 @@
 void	xs_close(void);
 gint	xs_is_our_file(gchar *);
 gint	xs_is_our_file_vfs(gchar *,VFSFile *);
-void	xs_play_file(gchar *);
-void	xs_stop(void);
-void	xs_pause(short);
-void	xs_seek(gint);
-gint	xs_get_time(void);
+void	xs_play_file(InputPlayback *);
+void	xs_stop(InputPlayback *);
+void	xs_pause(InputPlayback *, short);
+void	xs_seek(InputPlayback *,gint);
+gint	xs_get_time(InputPlayback *);
 void	xs_get_song_info(gchar *, gchar **, gint *);
 void	xs_about(void);
 
--- a/src/tonegen/tonegen.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/tonegen/tonegen.c	Sun Jan 28 21:09:12 2007 -0800
@@ -72,7 +72,8 @@
 
 static void* play_loop(void *arg)
 {
-	GArray* frequencies = arg;
+        InputPlayback *playback = arg;
+	GArray* frequencies = playback->data;
 	gint16 data[BUF_SAMPLES];
 	gsize i;
 	struct {
@@ -108,17 +109,17 @@
 			data[i] = rint(((1 << 15) - 1) *
 				       (sum_sines / frequencies->len));
 		}
-		while (tone_ip.output->buffer_free() < BUF_BYTES && going)
-			xmms_usleep(30000);
-		produce_audio(tone_ip.output->written_time(), FMT_S16_NE, 1, BUF_BYTES, data, &going);
+		while (playback->output->buffer_free() < BUF_BYTES && going)
+		        xmms_usleep(30000);
+		produce_audio(playback->output->written_time(), FMT_S16_NE, 1, BUF_BYTES, data, &going);
 	}
 
 	g_array_free(frequencies, TRUE);
 	g_free(tone);
 
 	/* Make sure the output plugin stops prebuffering */
-	tone_ip.output->buffer_free();
-	tone_ip.output->buffer_free();
+	playback->output->buffer_free();
+	playback->output->buffer_free();
 
 	g_thread_exit(NULL);
 	return(NULL);
@@ -178,8 +179,9 @@
 }
 	
 
-static void tone_play(InputPlayback *playback, char *filename)
+static void tone_play(InputPlayback *playback)
 {
+        char *filename = playback->filename;
 	GArray* frequencies;
 	char *name;
 
@@ -189,7 +191,7 @@
 
  	going = TRUE;
 	audio_error = FALSE;
-	if (tone_ip.output->open_audio(FMT_S16_NE, OUTPUT_FREQ, 1) == 0)
+	if (playback->output->open_audio(FMT_S16_NE, OUTPUT_FREQ, 1) == 0)
 	{
 		audio_error = TRUE;
 		going = FALSE;
@@ -199,31 +201,32 @@
 	name = tone_title(filename);
 	tone_ip.set_info(name, -1, 16 * OUTPUT_FREQ, OUTPUT_FREQ, 1);
 	g_free(name);
-	play_thread = g_thread_create((GThreadFunc)play_loop, frequencies, TRUE, NULL);
+	playback->data = frequencies;
+	play_thread = g_thread_create((GThreadFunc)play_loop, playback, TRUE, NULL);
 }
 
-static void tone_stop(InputPlayback *data)
+static void tone_stop(InputPlayback *playback)
 {
 	if (going)
 	{
 		going = FALSE;
 		g_thread_join(play_thread);
-		tone_ip.output->close_audio();
+		playback->output->close_audio();
 	}
 }
 
-static void tone_pause(InputPlayback *data, short paused)
+static void tone_pause(InputPlayback *playback, short paused)
 {
-	tone_ip.output->pause(paused);
+	playback->output->pause(paused);
 }
 
-static int tone_get_time(InputPlayback *data)
+static int tone_get_time(InputPlayback *playback)
 {
 	if (audio_error)
 		return -2;
-	if (!going && !tone_ip.output->buffer_playing())
+	if (!going && !playback->output->buffer_playing())
 		return -1;
-	return tone_ip.output->output_time();
+	return playback->output->output_time();
 }
 
 static void tone_song_info(char *filename, char **title, int *length)
--- a/src/tta/aud-tta.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/tta/aud-tta.c	Sun Jan 28 21:09:12 2007 -0800
@@ -69,11 +69,11 @@
 static void init ();
 static void cleanup ();
 static int  is_our_file (char *filename);
-static void play_file (char *filename);
-static void tta_pause (short paused);
-static void stop (void);
-static void seek (int time);
-static int  get_time (void);
+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 get_song_info (char *filename, char **title, int *length);
 static void file_info (char *filename);
 static void about ();
@@ -202,6 +202,7 @@
 static void *
 play_loop (void *arg)
 {
+    InputPlayback *playback = arg;
     int  bufsize = PCM_BUFFER_LENGTH  * info.BSIZE * info.NCH;
 
     ////////////////////////////////////////
@@ -213,7 +214,7 @@
 	while ((read_samples = get_samples (sample_buffer)) > 0)
 	{
 
-	    while ((tta_ip.output->buffer_free () < bufsize)
+	    while ((playback->output->buffer_free () < bufsize)
 		   && seek_position == -1)
 	    {
 		if (!playing)
@@ -222,7 +223,7 @@
 	    }
 	    if (seek_position == -1)
 	    {
-		produce_audio(tta_ip.output->written_time(),
+		produce_audio(playback->output->written_time(),
 			      ((info.BPS == 8) ? FMT_U8 : FMT_S16_LE),
 			      info.NCH,
 			      read_samples * info.NCH * info.BSIZE,
@@ -232,12 +233,12 @@
 	    else
 	    {
 		set_position (seek_position);
-		tta_ip.output->flush (seek_position * SEEK_STEP);
+		playback->output->flush (seek_position * SEEK_STEP);
 		seek_position = -1;
 	    }
 	}
-	tta_ip.output->buffer_free ();
-	tta_ip.output->buffer_free ();
+	playback->output->buffer_free ();
+	playback->output->buffer_free ();
 	xmms_usleep(10000);
     }
   DONE:
@@ -484,8 +485,9 @@
 }
 
 static void
-play_file (char *filename)
+play_file (InputPlayback *playback)
 {
+    char *filename = playback->filename;
     char *title;
     long datasize, origsize, bitrate;
 
@@ -510,7 +512,7 @@
     }
 
 
-    if (tta_ip.output->open_audio ((info.BPS == 8) ? FMT_U8 : FMT_S16_LE,
+    if (playback->output->open_audio ((info.BPS == 8) ? FMT_U8 : FMT_S16_LE,
 				   info.SAMPLERATE, info.NCH) == 0)
     {
 	tta_error (OUTPUT_ERROR);
@@ -547,22 +549,22 @@
     seek_position = -1;
     read_samples = -1;
 
-    pthread_create (&decode_thread, NULL, play_loop, NULL);
+    pthread_create (&decode_thread, NULL, play_loop, playback);
 }
 
 static void
-tta_pause (short paused)
+tta_pause (InputPlayback *playback, short paused)
 {
-    tta_ip.output->pause (paused);
+    playback->output->pause (paused);
 }
 static void
-stop (void)
+stop (InputPlayback *playback)
 {
     if (playing)
     {
 	playing = FALSE;
 	pthread_join (decode_thread, NULL);
-	tta_ip.output->close_audio ();
+	playback->output->close_audio ();
 	close_tta_file (&info);
 	read_samples = 0;
     }
@@ -581,10 +583,10 @@
 }
 
 static int
-get_time (void)
+get_time (InputPlayback *playback)
 {
-    if (playing && (read_samples || tta_ip.output->buffer_playing()))
-	return tta_ip.output->output_time();
+    if (playing && (read_samples || playback->output->buffer_playing()))
+        return playback->output->output_time();
 
     return -1;
 }
--- a/src/vorbis/vorbis.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/vorbis/vorbis.c	Sun Jan 28 21:09:12 2007 -0800
@@ -305,7 +305,7 @@
 }
 
 static void
-vorbis_jump_to_time(long time)
+vorbis_jump_to_time(InputPlayback *playback, long time)
 {
     g_mutex_lock(vf_mutex);
 
@@ -317,24 +317,25 @@
     if (time == ov_time_total(&vf, -1))
         time--;
 
-    vorbis_ip.output->flush(time * 1000);
+    playback->output->flush(time * 1000);
     ov_time_seek(&vf, time);
 
     g_mutex_unlock(vf_mutex);
 }
 
 static void
-do_seek(void)
+do_seek(InputPlayback *playback)
 {
     if (seekneeded != -1 && !vorbis_is_streaming) {
-        vorbis_jump_to_time(seekneeded);
+        vorbis_jump_to_time(playback, seekneeded);
         seekneeded = -1;
         vorbis_eos = FALSE;
     }
 }
 
 static int
-vorbis_process_data(int last_section, gboolean use_rg, float rg_scale)
+vorbis_process_data(InputPlayback *playback, int last_section, 
+		    gboolean use_rg, float rg_scale)
 {
     char pcmout[4096];
     int bytes;
@@ -369,8 +370,8 @@
      */
     if (bytes <= 0 && bytes != OV_HOLE) {
         g_mutex_unlock(vf_mutex);
-        vorbis_ip.output->buffer_free();
-        vorbis_ip.output->buffer_free();
+        playback->output->buffer_free();
+        playback->output->buffer_free();
         vorbis_eos = TRUE;
         return last_section;
     }
@@ -393,17 +394,17 @@
         if (vi->rate != samplerate || vi->channels != channels) {
             samplerate = vi->rate;
             channels = vi->channels;
-            vorbis_ip.output->buffer_free();
-            vorbis_ip.output->buffer_free();
-            vorbis_ip.output->close_audio();
-            if (!vorbis_ip.output->
+            playback->output->buffer_free();
+            playback->output->buffer_free();
+            playback->output->close_audio();
+            if (!playback->output->
                 open_audio(FMT_S16_NE, vi->rate, vi->channels)) {
                 output_error = TRUE;
                 vorbis_eos = TRUE;
                 g_mutex_unlock(vf_mutex);
                 return current_section;
             }
-            vorbis_ip.output->flush(ov_time_tell(&vf) * 1000);
+            playback->output->flush(ov_time_tell(&vf) * 1000);
         }
     }
 
@@ -413,9 +414,9 @@
         return current_section;
 
     if (seekneeded != -1)
-        do_seek();
+        do_seek(playback);
 
-    produce_audio(vorbis_ip.output->written_time(),
+    produce_audio(playback->output->written_time(),
                   FMT_S16_NE, channels, bytes, pcmout, &vorbis_playing);
 
     return current_section;
@@ -424,7 +425,8 @@
 static gpointer
 vorbis_play_loop(gpointer arg)
 {
-    char *filename = (char *) arg;
+    InputPlayback *playback = arg;
+    char *filename = (char *) playback->data;
     gchar *title = NULL;
     double time;
     long timercount = 0;
@@ -491,7 +493,7 @@
     g_mutex_unlock(vf_mutex);
 
     vorbis_ip.set_info(title, time, br, samplerate, channels);
-    if (!vorbis_ip.output->open_audio(FMT_S16_NE, vi->rate, vi->channels)) {
+    if (!playback->output->open_audio(FMT_S16_NE, vi->rate, vi->channels)) {
         output_error = TRUE;
         goto play_cleanup;
     }
@@ -509,14 +511,15 @@
         int current_section;
 
         if (seekneeded != -1)
-            do_seek();
+            do_seek(playback);
 
         if (vorbis_eos) {
             xmms_usleep(20000);
             continue;
         }
 
-        current_section = vorbis_process_data(last_section, use_rg, rg_scale);
+        current_section = vorbis_process_data(playback, last_section, 
+					      use_rg, rg_scale);
 
         if (current_section != last_section) {
             /*
@@ -540,14 +543,14 @@
             g_mutex_unlock(vf_mutex);
 
             vorbis_ip.set_info(title, time, br, samplerate, channels);
-            timercount = vorbis_ip.output->output_time();
+            timercount = playback->output->output_time();
 
             last_section = current_section;
         }
 
         if (!(vi->bitrate_upper == vi->bitrate_lower && vi->bitrate_upper == vi->bitrate_nominal)
-            && (vorbis_ip.output->output_time() > timercount + 1000
-                || vorbis_ip.output->output_time() < timercount)) {
+            && (playback->output->output_time() > timercount + 1000
+                || playback->output->output_time() < timercount)) {
             /*
              * simple hack to avoid updating too
              * often
@@ -557,16 +560,15 @@
             g_mutex_unlock(vf_mutex);
             if (br > 0)
                 vorbis_ip.set_info(title, time, br, samplerate, channels);
-            timercount = vorbis_ip.output->output_time();
+            timercount = playback->output->output_time();
         }
     }
     if (!output_error)
-        vorbis_ip.output->close_audio();
+        playback->output->close_audio();
     /* fall through intentional */
 
   play_cleanup:
     g_free(title);
-    g_free(filename);
 
     /*
      * ov_clear closes the stream if its open.  Safe to call on an
@@ -580,16 +582,14 @@
 }
 
 static void
-vorbis_play(InputPlayback *data)
+vorbis_play(InputPlayback *playback)
 {
-    char *filename = data->filename;
     vorbis_playing = 1;
     vorbis_bytes_streamed = 0;
     vorbis_eos = 0;
     output_error = FALSE;
 
-    thread = g_thread_create(vorbis_play_loop, g_strdup(filename), TRUE,
-                             NULL);
+    thread = g_thread_create(vorbis_play_loop, playback, TRUE, NULL);
 }
 
 static void
@@ -602,19 +602,19 @@
 }
 
 static void
-vorbis_pause(InputPlayback *data, short p)
+vorbis_pause(InputPlayback *playback, short p)
 {
-    vorbis_ip.output->pause(p);
+    playback->output->pause(p);
 }
 
 static int
-vorbis_time(InputPlayback *data)
+vorbis_time(InputPlayback *playback)
 {
     if (output_error)
         return -2;
-    if (vorbis_eos && !vorbis_ip.output->buffer_playing())
+    if (vorbis_eos && !playback->output->buffer_playing())
         return -1;
-    return vorbis_ip.output->output_time();
+    return playback->output->output_time();
 }
 
 static void
--- a/src/wav/wav-sndfile.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/wav/wav-sndfile.c	Sun Jan 28 21:09:12 2007 -0800
@@ -125,6 +125,7 @@
 play_loop (void *arg)
 {	static short buffer [BUFFER_SIZE];
 	int samples;
+	InputPlayback *playback = arg;
 
 	g_static_mutex_lock(&decode_mutex);
 
@@ -135,10 +136,10 @@
 		samples = sf_read_short (sndfile, buffer, BUFFER_SIZE);
 
 		if (samples > 0 && decoding)
-		{	while ((wav_ip.output->buffer_free () < (samples * sizeof (short))) && decoding)
+		{	while ((playback->output->buffer_free () < (samples * sizeof (short))) && decoding)
 				xmms_usleep (10000);
 
-			produce_audio (wav_ip.output->written_time (), FMT_S16_NE, sfinfo.channels, 
+			produce_audio (playback->output->written_time (), FMT_S16_NE, sfinfo.channels, 
 				samples * sizeof (short), buffer, &decoding);
 		}
 		else
@@ -147,7 +148,7 @@
 		/* Do seek if seek_time is valid. */
 		if (seek_time > 0)
 		{	sf_seek (sndfile, seek_time * sfinfo.samplerate, SEEK_SET);
-			wav_ip.output->flush (seek_time * 1000);
+			playback->output->flush (seek_time * 1000);
 			seek_time = -1;
    			};
 
@@ -159,8 +160,9 @@
 } /* play_loop */
 
 static void
-play_start (char *filename)
+play_start (InputPlayback *playback)
 {
+        char *filename = playback->filename;
 	int pcmbitwidth;
 	gchar *song_title;
 
@@ -181,7 +183,7 @@
 	else
 		song_length = 0;
 
-	if (! wav_ip.output->open_audio (FMT_S16_NE, sfinfo.samplerate, sfinfo.channels))
+	if (! playback->output->open_audio (FMT_S16_NE, sfinfo.samplerate, sfinfo.channels))
 	{	sf_close (sndfile);
 		sndfile = NULL;
 		return;
@@ -190,13 +192,13 @@
 	wav_ip.set_info (song_title, song_length, bit_rate, sfinfo.samplerate, sfinfo.channels);
 	g_free (song_title);
 
-	decode_thread = g_thread_create ((GThreadFunc)play_loop, NULL, TRUE, NULL);
+	decode_thread = g_thread_create ((GThreadFunc)play_loop, playback, TRUE, NULL);
 
     	xmms_usleep (40000);
 } /* play_start */
 
 static void
-play_stop (void)
+play_stop (InputPlayback *playback)
 {
 	if (decode_thread == NULL)
 		return;
@@ -204,7 +206,7 @@
 	decoding = FALSE;
 
 	g_thread_join (decode_thread);
-	wav_ip.output->close_audio ();
+	playback->output->close_audio ();
 
 	sf_close (sndfile);
 	sndfile = NULL;
@@ -214,7 +216,7 @@
 } /* play_stop */
 
 static void
-file_seek (int time)
+file_seek (InputPlayback *playback, int time)
 {
 	if (! sfinfo.seekable)
 		return;
@@ -226,12 +228,12 @@
 } /* file_seek */
 
 static int
-get_time (void)
+get_time (InputPlayback *playback)
 {
-	if ( ! (wav_ip.output->buffer_playing () && decoding))
+	if ( ! (playback->output->buffer_playing () && decoding))
 		return -1;
 
-	return wav_ip.output->output_time ();
+	return playback->output->output_time ();
 } /* get_time */
 
 static void
--- a/src/wav/wav-sndfile.h	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/wav/wav-sndfile.h	Sun Jan 28 21:09:12 2007 -0800
@@ -27,10 +27,10 @@
 
 static	void 	plugin_init (void);
 static	int	is_our_file (char *filename);
-static	void 	play_start (char *filename);
-static	void 	play_stop (void);
-static	void 	file_seek (int time);
-static	int	get_time (void);
+static	void 	play_start (InputPlayback *playback)
+static	void 	play_stop (InputPlayback *playback);
+static	void 	file_seek (InputPlayback *playback, int time);
+static	int	get_time (InputPlayback *playback);
 static	void 	get_song_info (char *filename, char **title, int *length);
 static  void    wav_about (void);
 
--- a/src/wav/wav.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/wav/wav.c	Sun Jan 28 21:09:12 2007 -0800
@@ -254,6 +254,7 @@
 static gpointer
 play_loop(gpointer arg)
 {
+    InputPlayback *playback = arg;
     gchar data[2048 * 2];
     gsize bytes, blk_size, rate;
     gint actual_read;
@@ -272,12 +273,12 @@
 
                 if (actual_read == 0) {
                     wav_file->eof = 1;
-                    wav_ip.output->buffer_free();
-                    wav_ip.output->buffer_free();
+                    playback->output->buffer_free();
+                    playback->output->buffer_free();
                 }
                 else {
                     if (wav_file->seek_to == -1)
-                        produce_audio(wav_ip.output->written_time(),
+                        produce_audio(playback->output->written_time(),
                                       (wav_file->bits_per_sample ==
                                        16) ? FMT_S16_LE : FMT_U8,
                                       wav_file->channels, bytes, data,
@@ -287,8 +288,8 @@
             }
             else {
                 wav_file->eof = TRUE;
-                wav_ip.output->buffer_free();
-                wav_ip.output->buffer_free();
+                playback->output->buffer_free();
+                playback->output->buffer_free();
                 xmms_usleep(10000);
             }
         }
@@ -298,7 +299,7 @@
             wav_file->position = wav_file->seek_to * rate;
             vfs_fseek(wav_file->file,
                       wav_file->position + wav_file->data_offset, SEEK_SET);
-            wav_ip.output->flush(wav_file->seek_to * 1000);
+            playback->output->flush(wav_file->seek_to * 1000);
             wav_file->seek_to = -1;
         }
 
@@ -310,9 +311,9 @@
 }
 
 static void
-play_file(InputPlayback * data)
+play_file(InputPlayback * playback)
 {
-    gchar * filename = data->filename;
+    gchar * filename = playback->filename;
     gchar magic[4], *name;
     gulong len;
     gint rate;
@@ -405,7 +406,7 @@
         wav_file->position = 0;
         wav_file->going = 1;
 
-        if (wav_ip.output->
+        if (playback->output->
             open_audio((wav_file->bits_per_sample ==
                         16) ? FMT_S16_LE : FMT_U8,
                        wav_file->samples_per_sec, wav_file->channels) == 0) {
@@ -428,21 +429,21 @@
 }
 
 static void
-stop(InputPlayback * data)
+stop(InputPlayback * playback)
 {
     if (wav_file && wav_file->going) {
         wav_file->going = 0;
         g_thread_join(decode_thread);
-        wav_ip.output->close_audio();
+        playback->output->close_audio();
         g_free(wav_file);
         wav_file = NULL;
     }
 }
 
 static void
-wav_pause(InputPlayback * data, gshort p)
+wav_pause(InputPlayback * playback, gshort p)
 {
-    wav_ip.output->pause(p);
+    playback->output->pause(p);
 }
 
 static void
@@ -457,17 +458,17 @@
 }
 
 static int
-get_time(InputPlayback *data)
+get_time(InputPlayback *playback)
 {
     if (audio_error)
         return -2;
     if (!wav_file)
         return -1;
     if (!wav_file->going
-        || (wav_file->eof && !wav_ip.output->buffer_playing()))
+        || (wav_file->eof && !playback->output->buffer_playing()))
         return -1;
     else {
-        return wav_ip.output->output_time();
+        return playback->output->output_time();
     }
 }
 
--- a/src/wma/wma.c	Sun Jan 28 17:41:50 2007 -0800
+++ b/src/wma/wma.c	Sun Jan 28 21:09:12 2007 -0800
@@ -238,24 +238,24 @@
     return 1;
 }
 
-static void wma_do_pause(InputPlayback *data, short p)
+static void wma_do_pause(InputPlayback *playback, short p)
 {
     wma_pause = p;
-    wma_ip.output->pause(wma_pause);
+    playback->output->pause(wma_pause);
 }
 
-static void wma_seek(InputPlayback *data, int time) 
+static void wma_seek(InputPlayback *playback, int time) 
 {
     wma_seekpos = time;
-    if(wma_pause) wma_ip.output->pause(0);
+    if(wma_pause) playback->output->pause(0);
     while(wma_decode && wma_seekpos!=-1) xmms_usleep(10000);
-    if(wma_pause) wma_ip.output->pause(1);
+    if(wma_pause) playback->output->pause(1);
 }
 
-static int wma_get_time(InputPlayback *data)
+static int wma_get_time(InputPlayback *playback)
 {
-    wma_ip.output->buffer_free();
-    if(wma_decode) return wma_ip.output->output_time();
+    playback->output->buffer_free();
+    if(wma_decode) return playback->output->output_time();
     return -1;
 }
 
@@ -361,7 +361,7 @@
     (*title_real) = xmms_get_titlestring(xmms_get_gentitle_format(), tuple);
 }
 
-static void wma_playbuff(int out_size)
+static void wma_playbuff(InputPlayback *playback, int out_size)
 {
     FifoBuffer f;
     int sst_buff;
@@ -372,8 +372,8 @@
     {
         sst_buff = wma_st_buff;
 	if(wma_pause) memset(wma_s_outbuf, 0, sst_buff);	
-    	while(wma_ip.output->buffer_free() < wma_st_buff) xmms_usleep(20000);
-	produce_audio(wma_ip.output->written_time(), FMT_S16_NE,
+    	while(playback->output->buffer_free() < wma_st_buff) xmms_usleep(20000);
+	produce_audio(playback->output->written_time(), FMT_S16_NE,
     			    c->channels, sst_buff, (short *)wma_s_outbuf, NULL);
 	memset(wma_s_outbuf, 0, sst_buff);
     }
@@ -383,6 +383,7 @@
 
 static void *wma_play_loop(void *arg)
 {
+    InputPlayback *playback = arg;
     uint8_t *inbuf_ptr;
     int out_size, size, len;
     AVPacket pkt;
@@ -393,7 +394,7 @@
 	if(wma_seekpos != -1)
 	{
 	    av_seek_frame(ic, wma_idx, wma_seekpos * 1000000LL);
-	    wma_ip.output->flush(wma_seekpos * 1000);
+	    playback->output->flush(wma_seekpos * 1000);
 	    wma_seekpos = -1;
 	}
 
@@ -411,14 +412,14 @@
 	    
             if(out_size <= 0) continue;
 
-	    wma_playbuff(out_size);
+	    wma_playbuff(playback, out_size);
 
             size -= len;
             inbuf_ptr += len;
             if(pkt.data) av_free_packet(&pkt);
         }
     }
-    while(wma_decode && wma_ip.output->buffer_playing()) xmms_usleep(30000);
+    while(wma_decode && playback->output->buffer_playing()) xmms_usleep(30000);
     wma_decode = 0;
     if(wma_s_outbuf) g_free(wma_s_outbuf);
     if(wma_outbuf) g_free(wma_outbuf);
@@ -430,9 +431,9 @@
     return(NULL);
 }
 
-static void wma_play_file(InputPlayback *data)
+static void wma_play_file(InputPlayback *playback)
 {
-    char *filename = data->filename;
+    char *filename = playback->filename;
     AVCodec *codec;
     
     if(av_open_input_file(&ic, str_twenty_to_space(filename), NULL, 0, NULL) < 0) return;
@@ -453,7 +454,7 @@
     wsong_title = get_song_title(ic, filename);
     wsong_time = get_song_time(ic);
 
-    if(wma_ip.output->open_audio(FMT_S16_NE, c->sample_rate, c->channels) <= 0) return;
+    if(playback->output->open_audio(FMT_S16_NE, c->sample_rate, c->channels) <= 0) return;
 
     wma_st_buff  = ST_BUFF;
 	
@@ -465,13 +466,13 @@
 
     wma_seekpos = -1;
     wma_decode = 1;
-    wma_decode_thread = g_thread_create((GThreadFunc)wma_play_loop, NULL, TRUE, NULL);
+    wma_decode_thread = g_thread_create((GThreadFunc)wma_play_loop, playback, TRUE, NULL);
 }
 
-static void wma_stop(InputPlayback *data) 
+static void wma_stop(InputPlayback *playback) 
 {
     wma_decode = 0;
-    if(wma_pause) wma_do_pause(data, 0);
+    if(wma_pause) wma_do_pause(playback, 0);
     g_thread_join(wma_decode_thread);
-    wma_ip.output->close_audio();
+    playback->output->close_audio();
 }