changeset 75:653c9b0d1320

SIDPlay2 support "works" now. Borked problems with threads.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 15 Sep 2003 11:10:03 +0000
parents 8cb66a3f75f7
children 741291e14080
files src/Makefile.am src/xmms-sid.c src/xs_config.c src/xs_config.h src/xs_sidplay1.cc src/xs_sidplay2.cc
diffstat 6 files changed, 233 insertions(+), 165 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Sun Sep 14 18:51:05 2003 +0000
+++ b/src/Makefile.am	Mon Sep 15 11:10:03 2003 +0000
@@ -2,11 +2,12 @@
 lib_LTLIBRARIES = libxmmssid.la
 
 # Generals
-AM_CFLAGS   = -W -Wall -D_REENTRANT @GTK_CFLAGS@ @SIDPLAY1_INCLUDES@ @SIDPLAY2_INCLUDES@
+AM_CFLAGS   = -W -Wall -D_REENTRANT @GTK_CFLAGS@ @SIDPLAY1_INCLUDES@ @SIDPLAY2_INCLUDES@ @BUILDERS_INCLUDES@
 AM_CXXFLAGS = $(AM_CFLAGS)
 
-libxmmssid_la_LDFLAGS = -module -avoid-version
-libxmmssid_la_LIBADD  = @GTK_LIBS@ @SIDPLAY1_LDADD@ @SIDPLAY2_LDADD@ -lstdc++
+libxmmssid_la_LDFLAGS = -module -avoid-version @BUILDERS_LDFLAGS@
+libxmmssid_la_LIBADD  = @GTK_LIBS@ @SIDPLAY1_LDADD@ @SIDPLAY2_LDADD@ @RESID_LDADD@ @HARDSID_LDADD@
+# -lstdc++
 
 # Plugin sources
 libxmmssid_la_SOURCES =	\
@@ -19,6 +20,7 @@
 	xs_genui.c	xs_genui.h	\
 	xs_glade.c	xs_glade.h	\
 	xs_interface.c	xs_interface.h	\
+	xs_sidplay.h	\
 	xs_sidplay1.cc	xs_sidplay1.h	\
 	xs_sidplay2.cc	xs_sidplay2.h	\
 	xmms-sid.c	xmms-sid.h
--- a/src/xmms-sid.c	Sun Sep 14 18:51:05 2003 +0000
+++ b/src/xmms-sid.c	Mon Sep 15 11:10:03 2003 +0000
@@ -136,12 +136,10 @@
  memset(&xs_cfg, 0, sizeof(xs_cfg));
  xs_read_configuration();
 
-
  /* Initialize status */
  memset(&xs_status, 0, sizeof(xs_status));
  xs_status.allowNext = TRUE;
 
-
  /* Try to initialize emulator engine */
  XSDEBUG("initializing emulator engine...\n");
 
@@ -249,30 +247,17 @@
 void *xs_play_loop(void *argPointer)
 {
  t_xs_status myStatus;
- gboolean audioOpen;
+ gboolean audioOpen, doPlay;
  gint audioFreq, audioChannels, songLength, audioFmt;
  gchar audioBuffer[XS_BUFSIZE];
 
-
+ /* Initialize */
  pthread_mutex_lock(&xs_mutex);
  XSDEBUG("entering play thread\n");
-
- /* No idea, if this is really required here, but better be
-  * careful since we're dealing with EVIL threads ...
-  */
- if (!xs_status.allowNext)
-	{
-	pthread_mutex_unlock(&xs_mutex);
-	pthread_exit(NULL);
-	}
-
- /* Don't allow next song to be set yet */
- xs_status.allowNext = FALSE;
  xs_status.isPlaying = TRUE;
  memcpy(&myStatus, &xs_status, sizeof(t_xs_status));
  pthread_mutex_unlock(&xs_mutex);
 
-
  /* Copy and check audio options here (they might change in config while running) */
 #ifdef HAVE_UNSIGNEDPCM
  audioFmt = (xs_cfg.fmtBitsPerSample == XS_RES_16BIT) ? FMT_U16_NE : FMT_U8;
@@ -286,11 +271,13 @@
  /*
   * Main player loop: while not stopped, loop here - play subtunes
   */
- while (xs_status.isPlaying)
+ doPlay = TRUE;
+ while (xs_status.isPlaying && doPlay)
  {
  pthread_mutex_lock(&xs_mutex);
  myStatus.currSong = xs_status.currSong;
  myStatus.isPlaying = TRUE;
+ xs_status.allowNext = TRUE;
  pthread_mutex_unlock(&xs_mutex);
 
  XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong);
@@ -384,33 +371,32 @@
 	}
 
  /* Now determine if we continue by selecting other subtune or something */
- if (!myStatus.isPlaying) xs_status.isPlaying = FALSE;
+ if (!myStatus.isPlaying) doPlay = FALSE;
  }
 
- /* When exiting, delete data */
 err_exit:
- pthread_mutex_lock(&xs_mutex);
- xs_status.isPlaying = FALSE;
- pthread_mutex_unlock(&xs_mutex);
-
+ /* Close audio */
  if (audioOpen)
 	{
 	XSDEBUG("close audio #2\n");
 	xs_plugin_ip.output->close_audio();
 	}
 
- xs_player->plrDeleteSID(&myStatus);
-
  /* Exit the playing thread */
  XSDEBUG("exiting thread, bye.\n");
 
- /* Last thing we do is set allowNext to TRUE to flag
-  * that we have ended all action in the thread
-  */
  pthread_mutex_lock(&xs_mutex);
+ xs_player->plrDeleteSID(&myStatus);
+
+ if (xs_status.currFileName)
+ 	{
+	g_free(xs_status.currFileName);
+	xs_status.currFileName = NULL;
+	}
+                                 
+ xs_status.isPlaying = FALSE;
  xs_status.allowNext = TRUE;
  pthread_mutex_unlock(&xs_mutex);
-
  pthread_exit(NULL);
 }
 
@@ -420,10 +406,24 @@
  */
 void xs_play_file(gchar *pcFileName)
 {
+ while (!xs_status.allowNext) usleep(5000);
+ 
+ pthread_mutex_lock(&xs_mutex);
+ xs_status.allowNext = FALSE;
+ pthread_mutex_unlock(&xs_mutex);
+
+ fprintf(stderr, "\n\n");
+ XSDEBUG("play '%s'\n", pcFileName);
+ 
  /* Initialize the tune */
  if (!xs_player->plrLoadSID(&xs_status, pcFileName))
  	return;
 
+ /* Set general status information */
+ xs_status.isPlaying	= FALSE;
+ xs_status.isError	= FALSE;
+ xs_status.currFileName	= g_strdup(pcFileName);
+
  /* Start the playing thread! */
  if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0)
 	{
@@ -442,6 +442,7 @@
 {
  /* If playing, stop. */
  XSDEBUG("STOP_REQ\n");
+
  if (xs_status.isPlaying)
 	{
 	XSDEBUG("stopping...\n");
@@ -450,6 +451,7 @@
 	pthread_mutex_unlock(&xs_mutex);
 	pthread_join(xs_decode_thread, NULL);
 	}
+
 }
 
 
@@ -490,7 +492,7 @@
 	return -2;
 
  /* If tune has ended, return -1 */
- if (xs_status.allowNext && !xs_status.isPlaying)
+ if (!xs_status.isPlaying)
 	return -1;
 
  /* Obsolete? */
--- a/src/xs_config.c	Sun Sep 14 18:51:05 2003 +0000
+++ b/src/xs_config.c	Mon Sep 15 11:10:03 2003 +0000
@@ -52,14 +52,16 @@
 	{CTYPE_INT,	&xs_cfg.memoryMode,		"memoryMode"},
 	{CTYPE_INT,	&xs_cfg.clockSpeed,		"clockSpeed"},
 	{CTYPE_BOOL,	&xs_cfg.forceSpeed,		"forceSpeed"},
+
 	{CTYPE_INT,	&xs_cfg.optimiseLevel,		"optimiseLevel"},
+
 	{CTYPE_BOOL,	&xs_cfg.oversampleEnable,	"oversampleEnable"},
 	{CTYPE_INT,	&xs_cfg.oversampleFactor,	"oversampleFactor"},
+	{CTYPE_INT,	&xs_cfg.oversampleFilter,	"oversampleFilter"},
 
 	{CTYPE_BOOL,	&xs_cfg.playMaxTimeEnable,	"playMaxTimeEnable"},
 	{CTYPE_INT,	&xs_cfg.playMaxTime,		"playMaxTime"},
 	{CTYPE_BOOL,	&xs_cfg.playMaxTimeUnknown,	"playMaxTimeUnknown"},
-
 	{CTYPE_BOOL,	&xs_cfg.songlenDBEnable,	"songlenDBEnable"},
 	{CTYPE_STR,	&xs_cfg.songlenDBPath,		"songlenDBPath"},
 
@@ -87,24 +89,26 @@
 { WTYPE_SPIN,	CTYPE_INT,	"cfg_samplerate",	&xs_cfg.fmtFrequency,		0 },
 { WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_oversample",	&xs_cfg.oversampleEnable,	0 },
 { WTYPE_SPIN,	CTYPE_INT,	"cfg_oversample_factor",&xs_cfg.oversampleFactor,	0 },
-
-{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_mos8580",	&xs_cfg.mos8580,		0 },
-{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_filters",	&xs_cfg.emulateFilters,		0 },
+{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_overfilter_average",&xs_cfg.oversampleFilter,	XS_FILTER_AVERAGE },
+{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_overfilter_sinc",	&xs_cfg.oversampleFilter,	XS_FILTER_SINC },
 
-{ WTYPE_SCALE,	CTYPE_FLOAT,	"cfg_emu_filt_fs",	&xs_cfg.filterFs,		0 },
-{ WTYPE_SCALE,	CTYPE_FLOAT,	"cfg_emu_filt_fm",	&xs_cfg.filterFm,		0 },
-{ WTYPE_SCALE,	CTYPE_FLOAT,	"cfg_emu_filt_ft",	&xs_cfg.filterFt,		0 },
-
+{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_sidplay1",	&xs_cfg.playerEngine,		XS_ENG_SIDPLAY1 },
+{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_sidplay2",	&xs_cfg.playerEngine,		XS_ENG_SIDPLAY2 },
+{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_sidplay2_opt",	&xs_cfg.optimiseLevel,		0 },
+{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_nanosid",	&xs_cfg.playerEngine,		XS_ENG_NANOSID },
+{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_mos8580",	&xs_cfg.mos8580,		0 },
 { WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_mem_real",	&xs_cfg.memoryMode,		XS_MPU_REAL },
 { WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_mem_banksw",	&xs_cfg.memoryMode,		XS_MPU_BANK_SWITCHING },
 { WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_mem_transrom",	&xs_cfg.memoryMode,		XS_MPU_TRANSPARENT_ROM },
 { WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_mem_playsid",	&xs_cfg.memoryMode,		XS_MPU_PLAYSID_ENVIRONMENT },
-
 { WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_clock_ntsc",	&xs_cfg.clockSpeed,		XS_CLOCK_NTSC },
 { WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_clock_pal",	&xs_cfg.clockSpeed,		XS_CLOCK_PAL },
 { WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_clock_force",	&xs_cfg.forceSpeed,		0 },
 
-{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_sidplay2_opt",	&xs_cfg.optimiseLevel,		0 },
+{ WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_emu_filters",	&xs_cfg.emulateFilters,		0 },
+{ WTYPE_SCALE,	CTYPE_FLOAT,	"cfg_emu_filt_fs",	&xs_cfg.filterFs,		0 },
+{ WTYPE_SCALE,	CTYPE_FLOAT,	"cfg_emu_filt_fm",	&xs_cfg.filterFm,		0 },
+{ WTYPE_SCALE,	CTYPE_FLOAT,	"cfg_emu_filt_ft",	&xs_cfg.filterFt,		0 },
 
 { WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_maxtime_enable",	&xs_cfg.playMaxTimeEnable,	0 },
 { WTYPE_SPIN,	CTYPE_INT,	"cfg_maxtime",		&xs_cfg.playMaxTime,		0 },
@@ -124,9 +128,6 @@
 { WTYPE_BUTTON,	CTYPE_BOOL,	"cfg_ftitle_override",	&xs_cfg.titleOverride,		0 },
 { WTYPE_TEXT,	CTYPE_STR,	"cfg_ftitle_format",	&xs_cfg.titleFormat,		0 },
 
-{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_sidplay1",	&xs_cfg.playerEngine,	XS_ENG_SIDPLAY1 },
-{ WTYPE_BGROUP,	CTYPE_INT,	"cfg_emu_sidplay2",	&xs_cfg.playerEngine,	XS_ENG_SIDPLAY2 },
-
 };
 
 const gint xs_widtable_max = (sizeof(xs_widtable) / sizeof(t_xs_wid_item));
@@ -174,9 +175,12 @@
 
  xs_cfg.clockSpeed		= XS_CLOCK_PAL;
  xs_cfg.forceSpeed		= FALSE;
+
  xs_cfg.optimiseLevel		= FALSE;
+
  xs_cfg.oversampleEnable	= FALSE;
  xs_cfg.oversampleFactor	= XS_MIN_OVERSAMPLE;
+ xs_cfg.oversampleFilter	= XS_FILTER_AVERAGE;
 
  xs_cfg.playMaxTimeEnable	= FALSE;
  xs_cfg.playMaxTime		= 150;
@@ -512,15 +516,11 @@
  xs_configwin = create_xs_configwin();
 
  /* Based on selected emulation library, disable options */
-#ifdef HAVE_SIDPLAY1
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(LUW("cfg_emu_sidplay1")), TRUE);
-#else
+#ifndef HAVE_SIDPLAY1
  gtk_widget_set_sensitive(LUW("cfg_emu_sidplay1"), FALSE);
 #endif
 
 #ifdef HAVE_SIDPLAY2
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(LUW("cfg_emu_sidplay2")), TRUE);
-#else
  gtk_widget_set_sensitive(LUW("cfg_emu_sidplay2"), FALSE);
  gtk_widget_set_sensitive(LUW("cfg_emu_sidplay2_opt"), FALSE);
 
@@ -529,6 +529,13 @@
  gtk_widget_set_sensitive(LUW("cfg_oversample_grp"), FALSE);
  gtk_widget_set_sensitive(LUW("cfg_oversample"), FALSE);
  gtk_widget_set_sensitive(LUW("cfg_oversample_factor"), FALSE);
+
+ gtk_widget_set_sensitive(LUW("cfg_overfilter_average"), FALSE);
+ gtk_widget_set_sensitive(LUW("cfg_overfilter_sinc"), FALSE);
+#endif
+
+#ifndef HAVE_NANOSID
+ gtk_widget_set_sensitive(LUW("cfg_emu_nanosid"), FALSE);
 #endif
 
 #ifndef HAVE_XMMSEXTRA
--- a/src/xs_config.h	Sun Sep 14 18:51:05 2003 +0000
+++ b/src/xs_config.h	Mon Sep 15 11:10:03 2003 +0000
@@ -10,20 +10,20 @@
 /*
  * Configuration structure
  */
-enum XS_ENG {
+enum XS_EMUENGINE {
 	XS_ENG_SIDPLAY1,
 	XS_ENG_SIDPLAY2,
 	XS_ENG_NANOSID	
 };
 
 
-enum XS_RES {
+enum XS_RESOLUTION {
 	XS_RES_8BIT = 8,
 	XS_RES_16BIT = 16,
 	XS_RES_24BIT = 24
 };
 
-enum XS_CHN {
+enum XS_CHANNELS {
 	XS_CHN_MONO = 1,
 	XS_CHN_STEREO = 2,
 	XS_CHN_AUTOPAN = 3
@@ -36,12 +36,6 @@
 };
 
 
-enum XS_EMUENGINE {
-	XS_SIDPLAY1 = 1,
-	XS_SIDPLAY2
-};
-
-
 enum XS_MPU {
 	XS_MPU_BANK_SWITCHING = 1,
 	XS_MPU_TRANSPARENT_ROM,
@@ -50,6 +44,12 @@
 };
 
 
+enum XS_FILTER {
+	XS_FILTER_AVERAGE = 1,
+	XS_FILTER_SINC
+};
+
+
 extern struct t_xs_cfg {
 	/* General audio settings */
 	gint		fmtBitsPerSample;
@@ -65,9 +65,12 @@
 	gint		memoryMode;		/* See XS_MPU-constants */
 	gint		clockSpeed;		/* PAL (50Hz) or NTSC (60Hz) */
 	gboolean	forceSpeed;		/* TRUE = force to given clockspeed */
+
 	gboolean	optimiseLevel;		/* SIDPlay2 emulation optimization */
+
 	gboolean	oversampleEnable;
 	gint		oversampleFactor;	/* Factor of oversampling */
+	gint		oversampleFilter;	/* Oversampling filter type */
 
 	/* Playing settings */
 	gboolean	playMaxTimeEnable;
--- a/src/xs_sidplay1.cc	Sun Sep 14 18:51:05 2003 +0000
+++ b/src/xs_sidplay1.cc	Mon Sep 15 11:10:03 2003 +0000
@@ -49,9 +49,12 @@
  */
 extern "C" {
 
+
+/*
+ * Check if we can play the given file
+ */
 gboolean xs_sidplay1_isourfile(gchar *pcFileName)
 {
- /* Try to detect via libSIDPlay's detection routine, if required */
  sidTune *testTune = new sidTune(pcFileName);
 
  if (!testTune) return FALSE;
@@ -66,35 +69,13 @@
 }
 
 
-void xs_sidplay1_close(t_xs_status *myStatus)
-{
- t_xs_sidplay1 *myPlayer;
-
- /* Check pointer */
- if (!myStatus) return;
-
- /* Free internals */
- xs_sidplay1_deletesid(myStatus);
-
- myPlayer = (t_xs_sidplay1 *) myStatus->player;
-
- if (myPlayer->currEng) delete myPlayer->currEng;
-
- free(myPlayer);
- myStatus->player = NULL;
-
- /* Miscellaneous */
- free(myStatus->currFileName);
- myStatus->currFileName = NULL;
-}
-
-
+/*
+ * Initialize SIDPlay1
+ */
 gboolean xs_sidplay1_init(t_xs_status *myStatus)
 {
  t_xs_sidplay1 *myPlayer;
-
- /* Check pointer */
- if (!myStatus) return FALSE;
+ assert(myStatus);
 
  /* Allocate internal structures */
  myPlayer = (t_xs_sidplay1 *) g_malloc0(sizeof(t_xs_sidplay1));
@@ -122,13 +103,43 @@
 }
 
 
+/*
+ * Close SIDPlay1
+ */
+void xs_sidplay1_close(t_xs_status *myStatus)
+{
+ t_xs_sidplay1 *myPlayer;
+ assert(myStatus);
+
+ /* Free internals */
+ xs_sidplay1_deletesid(myStatus);
+
+ myPlayer = (t_xs_sidplay1 *) myStatus->player;
+
+ if (myPlayer->currEng) delete myPlayer->currEng;
+
+ free(myPlayer);
+ myStatus->player = NULL;
+}
+
+
 gboolean xs_sidplay1_initsong(t_xs_status *myStatus)
 {
  t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player;
 
  if (!myPlayer) return FALSE;
 
- if ((!myPlayer->currTune) || (!myPlayer->currTune->getStatus())) return FALSE;
+ if (!myPlayer->currTune)
+	{
+	XSERR("Tune was NULL\n");
+	return FALSE;
+	}
+
+ if (!myPlayer->currTune->getStatus())
+	{
+	XSERR("Tune status check failed\n");
+	return FALSE;
+	}
 
  return sidEmuInitializeSong(
 	*myPlayer->currEng,
@@ -158,6 +169,7 @@
  t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player;
  sidTune *newTune;
  sidTuneInfo tuneInfo;
+ assert(myStatus);
 
  /* Try to get the tune */
  if (!pcFileName) return FALSE;
@@ -239,17 +251,17 @@
  myPlayer->currConfig.filterFt		= xs_cfg.filterFt;
 
  /* Now set the emulator configuration */
- myPlayer->currEng->setConfig(myPlayer->currConfig);
+ if (!myPlayer->currEng->setConfig(myPlayer->currConfig))
+	{
+	XSERR("Emulator engine configuration failed!\n");
+	return FALSE;
+	}
 
  /* Initialize status information */
  newTune->getInfo(tuneInfo);
-
- myStatus->isPlaying	= TRUE;
- myStatus->isError	= FALSE;
+ myPlayer->currTune	= newTune;
  myStatus->currSong	= tuneInfo.startSong;
  myStatus->nSongs	= tuneInfo.songs;
- myPlayer->currTune	= newTune;
- myStatus->currFileName = g_strdup(pcFileName);
 
  return TRUE;
 }
@@ -261,14 +273,7 @@
 void xs_sidplay1_deletesid(t_xs_status *myStatus)
 {
  t_xs_sidplay1 *myPlayer;
-
- if (!myStatus) return;
-
- if (myStatus->currFileName)
-	{
-	g_free(myStatus->currFileName);
-	myStatus->currFileName = NULL;
-	}
+ assert(myStatus);
 
  myPlayer = (t_xs_sidplay1 *) myStatus->player;
  if (!myPlayer) return;
@@ -286,10 +291,11 @@
  return 0;
 }
 
+
 /*
  * Return song information
  */
-#include "xs_sidplay_info.h"
+#include "xs_sidplay.h"	// Include common function
 
 void xs_sidplay1_getsidinfo(gchar *songFileName, gchar **songTitle, gint *songLength)
 {
--- a/src/xs_sidplay2.cc	Sun Sep 14 18:51:05 2003 +0000
+++ b/src/xs_sidplay2.cc	Mon Sep 15 11:10:03 2003 +0000
@@ -37,12 +37,13 @@
 #include <sidplay/builders/resid.h>
 #endif
 #ifdef HAVE_HARDSID_BUILDER
-/* Dummy now */
+#include <sidplay/builders/hardsid.h>
 #endif
 
 
 typedef struct {
 	sidplay2	*currEng;
+	sidbuilder	*currBuilder;
 	sid2_config_t	currConfig;
 	SidTune		*currTune;
 } t_xs_sidplay2;
@@ -53,9 +54,12 @@
  */
 extern "C" {
 
+
+/*
+ * Check if we can play the given file
+ */
 gboolean xs_sidplay2_isourfile(gchar *pcFileName)
 {
- /* Try to detect via libSIDPlay's detection routine, if required */
  SidTune *testTune = new SidTune(pcFileName);
 
  if (!testTune) return FALSE;
@@ -70,68 +74,120 @@
 }
 
 
-void xs_sidplay2_close(t_xs_status *myStatus)
-{
- t_xs_sidplay2 *myPlayer;
- sidbuilder *myBuilder;
-
- /* Check pointer */
- if (!myStatus) return;
-
- /* Free internals */
- myPlayer = (t_xs_sidplay2 *) myStatus->player;
-
- myBuilder = myPlayer->currConfig.sidEmulation;
- myPlayer->currEng->config(myPlayer->currConfig);
-
- delete myBuilder;
- delete myPlayer->currEng;
-
- xs_sidplay2_deletesid(myStatus);
-
- free(myPlayer);
- myStatus->player = NULL;
-
- /* Miscellaneous */
- free(myStatus->currFileName);
- myStatus->currFileName = NULL;
-}
-
-
+/*
+ * Initialize SIDPlay2
+ */
 gboolean xs_sidplay2_init(t_xs_status *myStatus)
 {
  t_xs_sidplay2 *myPlayer;
-
- /* Check pointer */
- if (!myStatus) return FALSE;
+ assert(myStatus);
 
  /* Allocate internal structures */
  myPlayer = (t_xs_sidplay2 *) g_malloc0(sizeof(t_xs_sidplay2));
  if (!myPlayer) return FALSE;
 
- /* Initialize engine */
+
+ /* Initialize the engine */
  myPlayer->currEng = new sidplay2;
  if (!myPlayer->currEng)
 	{
 	XSERR("Could not initialize libSIDPlay2 emulation engine\n");
-	free(myPlayer);
+	return FALSE;
+	}
+
+ /* Initialize builder object */
+ /*
+	FIXME! we need to select builder by configuration!
+ */
+#ifdef HAVE_RESID_BUILDER
+ ReSIDBuilder *tmpb = new ReSIDBuilder("SIDPlay2 suxx and is made by a fag - ReSID builder");
+
+ /* Create the builder -- WHAT IS THIS MEANT FOR??? */
+ tmpb->create(myPlayer->currEng->info().maxsids);
+
+ myPlayer->currBuilder = (sidbuilder *) tmpb;
+#endif
+#ifdef HAVE_HARDSID_BUILDER
+#endif
+
+ if (!myPlayer->currBuilder)
+	{
+	XSERR("Could not initialize SIDBuilder object.\n");
 	return FALSE;
 	}
 
+ XSDEBUG("%s\n", myPlayer->currBuilder->credits());
+
+
+ /* Create the sidtune */
+ myPlayer->currTune = new SidTune(0);
+ if (!myPlayer->currTune)
+	{
+	XSERR("Could not initialize SIDTune object.\n");
+	return FALSE;
+	}
+ 
+ /* OK */
  myStatus->player = myPlayer;
  return TRUE;
 }
 
 
+/*
+ * Close SIDPlay2
+ */
+void xs_sidplay2_close(t_xs_status *myStatus)
+{
+ t_xs_sidplay2 *myPlayer;
+ assert(myStatus);
+
+ /* Free internals */
+ myPlayer = (t_xs_sidplay2 *) myStatus->player;
+
+ if (myPlayer->currBuilder)
+	{
+	delete myPlayer->currBuilder;
+	myPlayer->currBuilder = NULL;
+	}
+
+ if (myPlayer->currEng)
+	{
+	delete myPlayer->currEng;
+	myPlayer->currEng = NULL;
+	}
+
+ if (myPlayer->currTune)
+	{
+	delete myPlayer->currTune;
+	myPlayer->currTune = NULL;
+	}
+
+ xs_sidplay2_deletesid(myStatus);
+
+ g_free(myPlayer);
+ myStatus->player = NULL;
+}
+
+
 gboolean xs_sidplay2_initsong(t_xs_status *myStatus)
 {
  t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player;
 
- if (!myPlayer || !myPlayer->currTune) return FALSE;
+ if (!myPlayer) return FALSE;
+
+ if (!myPlayer->currTune->selectSong(myStatus->currSong))
+	{
+	XSERR("ENGINE selectSong() failed\n");
+	return FALSE;
+	}
 
- myPlayer->currTune->selectSong(myStatus->currSong);
+ if (myPlayer->currEng->load(myPlayer->currTune) < 0)
+	{
+	XSERR("ENGINE load() failed\n");
+	return FALSE;
+	}
 
- return myPlayer->currEng->load(myPlayer->currTune);
+ return TRUE;
 }
 
 
@@ -139,8 +195,6 @@
 {
  t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player;
 
- if (!myPlayer) return FALSE;
-
  return (myPlayer->currEng->play(audioBuffer, audioBufSize) == audioBufSize);
 }
 
@@ -148,13 +202,12 @@
 gboolean xs_sidplay2_loadsid(t_xs_status *myStatus, gchar *pcFileName)
 {
  t_xs_sidplay2 *myPlayer = (t_xs_sidplay2 *) myStatus->player;
- SidTune *newTune;
  SidTuneInfo tuneInfo;
+ assert(myStatus);
 
  /* Try to get the tune */
  if (!pcFileName) return FALSE;
- newTune = new SidTune(pcFileName);
- if (!newTune) return FALSE;
+ if (!myPlayer->currTune->load(pcFileName)) return FALSE;
 
  /* Get current configuration */
  myPlayer->currConfig = myPlayer->currEng->config();
@@ -212,12 +265,13 @@
 
 
  /* Configure rest of the emulation */
+ myPlayer->currConfig.sidEmulation	= myPlayer->currBuilder;
  myPlayer->currConfig.precision		= xs_cfg.fmtBitsPerSample;
  myPlayer->currConfig.frequency		= xs_cfg.fmtFrequency; 
- myPlayer->currConfig.clockForced		= xs_cfg.forceSpeed;
+ myPlayer->currConfig.clockForced	= xs_cfg.forceSpeed;
  myPlayer->currConfig.optimisation	= (xs_cfg.optimiseLevel) ? 1 : 0;
- myPlayer->currConfig.sidDefault		= myPlayer->currConfig.sidModel = (xs_cfg.mos8580) ? SID2_MOS8580 : SID2_MOS6581;
- myPlayer->currConfig.sidSamples		= TRUE;	// FIXME FIX ME, make configurable!
+ myPlayer->currConfig.sidDefault	= myPlayer->currConfig.sidModel = (xs_cfg.mos8580) ? SID2_MOS8580 : SID2_MOS6581;
+ myPlayer->currConfig.sidSamples	= TRUE;	// FIXME FIX ME, make configurable!
 
 #ifdef HAVE_UNSIGNEDPCM
 #ifdef WORDS_BIGENDIAN
@@ -234,17 +288,16 @@
 #endif
 
  /* Now set the emulator configuration */
- myPlayer->currEng->config(myPlayer->currConfig);
+ if (myPlayer->currEng->config(myPlayer->currConfig) < 0)
+	{
+	XSERR("Emulator engine configuration failed!\n");
+	return FALSE;
+	}
 
  /* Initialize status information */
- newTune->getInfo(tuneInfo);
-
- myStatus->isPlaying	= TRUE;
- myStatus->isError	= FALSE;
+ myPlayer->currTune->getInfo(tuneInfo);
  myStatus->currSong	= tuneInfo.startSong;
  myStatus->nSongs	= tuneInfo.songs;
- myPlayer->currTune	= newTune;
- myStatus->currFileName = g_strdup(pcFileName);
 
  return TRUE;
 }
@@ -256,15 +309,9 @@
 void xs_sidplay2_deletesid(t_xs_status *myStatus)
 {
  t_xs_sidplay2 *myPlayer;
-
- if (!myStatus) return;
+ assert(myStatus);
 
- if (myStatus->currFileName)
-	{
-	g_free(myStatus->currFileName);
-	myStatus->currFileName = NULL;
-	}
-
+/*
  myPlayer = (t_xs_sidplay2 *) myStatus->player;
  if (!myPlayer) return;
 
@@ -273,6 +320,7 @@
 	delete myPlayer->currTune;
 	myPlayer->currTune = NULL;
 	}
+*/
 }