changeset 71:2b32c75729ce

Started modularizing, separated sidplay1 things into a "wrapper" module. Removed non-generic stuff from xmms-sid.cc, removed C++ references and renamed to xmms-sid.c
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 10 Sep 2003 06:21:04 +0000
parents ec31a68bbc2c
children e3b205a6bc7e
files src/Makefile.am src/xmms-sid.c src/xmms-sid.cc src/xs_sidplay1.cc src/xs_sidplay1.h
diffstat 4 files changed, 580 insertions(+), 837 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Sun Jul 13 14:36:00 2003 +0000
+++ b/src/Makefile.am	Wed Sep 10 06:21:04 2003 +0000
@@ -10,7 +10,8 @@
 
 # Plugin sources
 libxmmssid_la_SOURCES =	\
-	xmms-sid.cc	xmms-sid.h	\
+	xmms-sid.c	xmms-sid.h	\
+	xs_sidplay1.cc	xs_sidplay1.h	\
 	xs_init.c	\
 	xs_about.c	\
 	xs_support.c	xs_support.h	\
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xmms-sid.c	Wed Sep 10 06:21:04 2003 +0000
@@ -0,0 +1,405 @@
+/*
+   XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
+
+   Main source file
+
+   Written by Matti "ccr" Hamalainen <ccr@tnsp.org>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <xmms/plugin.h>
+
+#include "xmms-sid.h"
+#include "xs_support.h"
+#include "xs_config.h"
+#include "xs_length.h"
+#include "xs_interface.h"
+#include "xs_glade.h"
+
+/*
+ * Include player engines
+ */
+#include "xs_sidplay1.h"
+#include "xs_sidplay2.h"
+
+
+/*
+ * Global variables
+ */
+static GtkWidget		*xs_ctrlwin	= NULL;
+static pthread_t		xs_decode_thread;
+static pthread_mutex_t		xs_mutex = PTHREAD_MUTEX_INITIALIZER;
+struct t_xs_cfg			xs_cfg;
+
+
+/*
+ * Create sub-song control window
+ */
+void xs_ctrlwin_open(void)
+{
+ /* Create sub-song control window */
+ if (xs_ctrlwin != NULL)
+	{
+	if (xs_cfg.alwaysRaise)
+		gdk_window_raise(xs_ctrlwin->window);
+	return;
+	}
+
+ xs_ctrlwin = create_xs_ctrlwin();
+ gtk_widget_show(xs_ctrlwin);
+}
+
+
+/*
+ * Initialize XMMS-SID
+ */
+void xs_init(void)
+{
+ XSDEBUG("xs_init()\n");
+
+ /* Initialize and get configuration */
+ memset(&xs_cfg, 0, sizeof(xs_cfg));
+
+ xs_read_configuration();
+
+ /* Initialize status */
+ memset(&xs_status, 0, sizeof(xs_status));
+ xs_status.allowNext = TRUE;	// Initialize to TRUE to allow first song
+
+ /* Try to initialize emulator engine(s) */
+ XSDEBUG("initializing emulator engine(s)...\n");
+
+
+
+
+ /* Read song-length database */
+ if (xs_cfg.songlenDBEnable && (xs_songlen_init() < 0))
+	{
+	XSERR("Error initializing song-length database!\n");
+	}
+	
+ /* Initialize STIL structures */
+
+// xs_ctrlwin_open();
+
+// FIXME FIXME FIx ME
+
+ XSDEBUG("OK\n");
+}
+
+
+/*
+ * Shut down XMMS-SID
+ */
+void xs_close(void)
+{
+ XSDEBUG("xs_close(): shutting down...\n");
+
+ /* Stop playing */
+ xs_stop();
+
+ /* Shutdown libSIDPlay(s) */
+
+
+
+
+
+
+ /* Close sub-song control window */
+
+ /* Free allocated memory */
+ xs_songlen_close();
+
+// FIXME FIXME: STIL-entries
+ XSDEBUG("shutdown finished.\n");
+}
+
+
+/*
+ * Main playing thread loop
+ */
+void *xs_play_loop(void *argPointer)
+{
+ t_xs_status myStatus;
+ t_xs_tuneinfo tuneInfo;
+ gboolean audioOpen;
+ gint audioFreq, audioChannels, songLength;
+ enum AFormat audioFmt;
+ gchar audioBuffer[XS_BUFSIZE];
+ gchar *tmpStr;
+
+
+ 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;
+#else
+ audioFmt = (xs_cfg.fmtBitsPerSample == XS_RES_16BIT) ? FMT_S16_NE : FMT_S8;
+#endif
+ audioFreq = xs_cfg.fmtFrequency;
+ audioChannels = (xs_cfg.fmtChannels == XS_CHN_MONO) ? 1 : 2;
+ audioOpen = FALSE;
+
+ /*
+  * Main player loop: while not stopped, loop here - play subtunes
+  */
+ while (xs_status.isPlaying)
+ {
+ pthread_mutex_lock(&xs_mutex);
+ myStatus.currSong = xs_status.currSong;
+ myStatus.isPlaying = TRUE;
+ pthread_mutex_unlock(&xs_mutex);
+
+ XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong);
+
+
+ /* Get song length for current subtune */
+ songLength = xs_songlen_get(myStatus.currFileName, myStatus.currSong);
+
+ /* Initialize song */
+#ifdef HAVE_SIDPLAY1
+ if ((myStatus.currTune == NULL) || !myStatus.currTune->getStatus() ||
+	!sidEmuInitializeSong(xs_emuEngine, *myStatus.currTune, myStatus.currSong))
+#endif
+#ifdef HAVE_SIDPLAY2
+ if ()
+#endif
+	{
+	XSERR("Couldn't initialize SID-tune '%s' (sub-tune #%i)!\n",
+		myStatus.currFileName, myStatus.currSong);
+	goto err_exit;
+	}
+
+ myStatus.currTune->getInfo(tuneInfo);
+
+
+ /* Set information for current sub-tune */
+ tmpStr = xs_filetitle_get(myStatus.currFileName, &tuneInfo, myStatus.currSong);
+
+ xs_plugin_ip.set_info(tmpStr, (songLength > 0) ? songLength * 1000 : -1,
+ 1000 * (tuneInfo.songSpeed ? tuneInfo.songSpeed : (tuneInfo.clockSpeed == SIDTUNE_CLOCK_NTSC) ? 60 : 50),
+ audioFreq, audioChannels);
+ g_free(tmpStr);
+
+ /* Open the audio output */
+ if (!xs_plugin_ip.output->open_audio(audioFmt, audioFreq, audioChannels))
+	{
+	XSERR("Couldn't open XMMS audio output!\n");
+	pthread_mutex_lock(&xs_mutex);
+	xs_status.isError = TRUE;
+	pthread_mutex_unlock(&xs_mutex);
+	goto err_exit;
+	}
+
+ audioOpen = TRUE;
+
+ /*
+  * Play the subtune
+  */
+ while (xs_status.isPlaying && myStatus.isPlaying && (xs_status.currSong == myStatus.currSong))
+	{
+	/* Render audio data */
+#ifdef HAVE_SIDPLAY1
+	sidEmuFillBuffer(xs_emuEngine, *myStatus.currTune, audioBuffer, XS_BUFSIZE);
+#endif
+#ifdef HAVE_SIDPLAY2
+#endif
+
+	/* I <3 visualice/haujobb */
+	xs_plugin_ip.add_vis_pcm(
+		xs_plugin_ip.output->written_time(),
+		audioFmt, audioChannels, XS_BUFSIZE, audioBuffer);
+
+	/* Wait a little */
+	while (xs_status.isPlaying &&
+		(xs_status.currSong == myStatus.currSong) &&
+		(xs_plugin_ip.output->buffer_free() < XS_BUFSIZE))
+		xmms_usleep(10000);
+
+	/* Output audio */
+	if (xs_status.isPlaying && (xs_status.currSong == myStatus.currSong))
+		xs_plugin_ip.output->write_audio(audioBuffer, XS_BUFSIZE);
+
+	/* Check if we have played enough */
+	if (xs_cfg.playMaxTimeEnable)
+		{
+		if (xs_cfg.playMaxTimeUnknown)
+			{
+			if ((songLength == -1) &&
+				(xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000)))
+				myStatus.isPlaying = FALSE;
+			} else {
+			if (xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000))
+				myStatus.isPlaying = FALSE;
+			}
+		}
+
+	if (songLength > 0)
+		{
+		if (xs_plugin_ip.output->output_time() >= (songLength * 1000))
+			myStatus.isPlaying = FALSE;
+		}
+	}
+
+ XSDEBUG("subtune ended/stopped\n");
+
+ /* Close audio */
+ if (audioOpen)
+	{
+	XSDEBUG("close audio #1\n");
+	xs_plugin_ip.output->close_audio();
+	audioOpen = FALSE;
+	}
+
+ /* Now determine if we continue by selecting other subtune or something */
+ if (!myStatus.isPlaying) xs_status.isPlaying = FALSE;
+ }
+
+ /* When exiting, delete data */
+err_exit:
+ pthread_mutex_lock(&xs_mutex);
+ xs_status.isPlaying = FALSE;
+ pthread_mutex_unlock(&xs_mutex);
+
+ if (audioOpen)
+	{
+	XSDEBUG("close audio #2\n");
+	xs_plugin_ip.output->close_audio();
+	}
+
+ if (myStatus.currTune != NULL)
+	{
+	delete myStatus.currTune;
+	myStatus.currTune = NULL;
+	}
+
+ g_free(myStatus.currFileName);
+
+ /* 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_status.allowNext = TRUE;
+ pthread_mutex_unlock(&xs_mutex);
+
+ pthread_exit(NULL);
+}
+
+
+/*
+ * Start playing the given file
+ */
+void xs_play_file(char *pcFileName)
+{
+}
+
+
+/*
+ * Stop playing
+ */
+void xs_stop(void)
+{
+ /* If playing, stop. */
+ XSDEBUG("STOP_REQ\n");
+ if (xs_status.isPlaying || !xs_status.allowNext)
+	{
+	XSDEBUG("stopping...\n");
+	pthread_mutex_lock(&xs_mutex);
+	xs_status.isPlaying = FALSE;
+	pthread_mutex_unlock(&xs_mutex);
+	pthread_join(xs_decode_thread, NULL);
+	}
+}
+
+
+/*
+ * Pause the playing
+ */
+void xs_pause(short pauseState)
+{
+ xs_plugin_ip.output->pause(pauseState);
+}
+
+
+/*
+ * Set the time-seek position
+ * (the playing thread will do the "seeking" aka song-change)
+ */
+void xs_seek(gint iTime)
+{
+ /* If we have song-position patch, check settings */
+#ifdef HAVE_SONG_POSITION
+ pthread_mutex_lock(&xs_mutex);
+
+ if ((iTime > 0) && (iTime <= xs_status.nSongs) && xs_status.isPlaying)
+	xs_status.currSong = iTime;
+
+ pthread_mutex_unlock(&xs_mutex);
+#endif
+}
+
+
+/*
+ * Return the playing "position/time"
+ */
+gint xs_get_time(void)
+{
+ /* If errorflag is set, return -2 to signal it to XMMS's idle callback */
+ if (xs_status.isError)
+	return -2;
+
+ /* If tune has ended, return -1 */
+ if (xs_status.allowNext && !xs_status.isPlaying)
+	return -1;
+
+ /* Obsolete? */
+#ifdef HAVE_SONG_POSITION
+ pthread_mutex_lock(&xs_mutex);
+ set_song_position(xs_status.currSong, 1, xs_status.nSongs);
+ pthread_mutex_unlock(&xs_mutex);
+#endif
+
+ /* Else, return output time reported by audio output plugin */
+ return xs_plugin_ip.output->output_time();
+}
+
+
--- a/src/xmms-sid.cc	Sun Jul 13 14:36:00 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,836 +0,0 @@
-/*
-   XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
-
-   Main source file
-
-   Written by Matti "ccr" Hamalainen <ccr@tnsp.org>
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-extern "C" {
-#include <xmms/plugin.h>
-#include <xmms/util.h>
-#include <xmms/titlestring.h>
-#include "xs_interface.h"
-#include "xs_glade.h"
-}
-
-#include "xmms-sid.h"
-#include "xs_support.h"
-#include "xs_config.h"
-#include "xs_length.h"
-
-
-#ifdef HAVE_SIDPLAY1
-#include <sidplay/player.h>
-#include <sidplay/myendian.h>
-#include <sidplay/fformat.h>
-#endif
-
-#ifdef HAVE_SIDPLAY2
-#include <sidplay/sidplay2.h>
-#endif
-
-
-/*
- * Global variables
- */
-#ifdef HAVE_SIDPLAY1
-typedef	sidTune			t_xs_tune;
-typedef struct sidTuneInfo	t_xs_tuneinfo;
-#endif
-
-#ifdef HAVE_SIDPLAY2
-typedef SidTune			t_xs_tune;
-typedef struct SidTuneInfo	t_xs_tuneinfo;
-#endif
-
-#ifdef HAVE_SIDPLAY1
-	struct emuConfig	xs_emuConf;
-	emuEngine		xs_emuEngine;
-#endif
-#ifdef HAVE_SIDPLAY2
-	struct sid2_config_t	xs_emuConf;
-	sidplay2		xs_emuEngine;
-#endif
-
-typedef struct {
-	gboolean	isError, isPlaying, allowNext;
-	gint		currSong, nSongs;
-	t_xs_tune	*currTune;
-	gchar		*currFileName;
-} t_xs_status;
-
-static GtkWidget		*xs_ctrlwin	= NULL;
-static pthread_t		xs_decode_thread;
-static pthread_mutex_t		xs_mutex = PTHREAD_MUTEX_INITIALIZER;
-struct t_xs_cfg			xs_cfg;
-t_xs_status			xs_status;
-
-
-gchar *xs_filetitle_get(gchar *, t_xs_tuneinfo *, gint);
-
-
-/*
- * Create sub-song control window
- */
-void xs_ctrlwin_open(void)
-{
- /* Create sub-song control window */
- if (xs_ctrlwin != NULL)
-	{
-	if (xs_cfg.alwaysRaise)
-		gdk_window_raise(xs_ctrlwin->window);
-	return;
-	}
-
- xs_ctrlwin = create_xs_ctrlwin();
- gtk_widget_show(xs_ctrlwin);
-}
-
-
-/*
- * Initialize XMMS-SID
- */
-void xs_init(void)
-{
- XSDEBUG("xs_init()\n");
-
- /* Initialize and get configuration */
- memset(&xs_cfg, 0, sizeof(xs_cfg));
-
- xs_read_configuration();
-
- /* Initialize status */
- memset(&xs_status, 0, sizeof(xs_status));
- xs_status.allowNext = TRUE;	// Initialize to TRUE to allow first song
-
- /* Try to initialize emulator engine(s) */
- XSDEBUG("initializing emulator engine(s)...\n");
-
-#ifdef HAVE_SIDPLAY1
- if (!xs_emuEngine || !xs_emuEngine.verifyEndianess())
-	{
-	XSERR("Couldn't initialize SIDPlay1 emulator engine!\n");
-	return;
-	}
-#endif
-
- /* Read song-length database */
- if (xs_cfg.songlenDBEnable && (xs_songlen_init() < 0))
-	{
-	XSERR("Error initializing song-length database!\n");
-	}
-	
- /* Initialize STIL structures */
-
-// xs_ctrlwin_open();
-
-// FIXME FIXME FIx ME
-
- XSDEBUG("OK\n");
-}
-
-
-/*
- * Shut down XMMS-SID
- */
-void xs_close(void)
-{
- XSDEBUG("xs_close(): shutting down...\n");
-
- /* Stop playing */
- xs_stop();
-
- /* Shutdown libSIDPlay(s) */
-#ifdef HAVE_SIDPLAY1
-#endif
-
-#ifdef HAVE_SIDPLAY2
-#endif
-
- /* Close sub-song control window */
-
- /* Free allocated memory */
- xs_songlen_close();
-
-// FIXME FIXME: STIL-entries
- XSDEBUG("shutdown finished.\n");
-}
-
-
-/*
- * Check whether the given file is handled by this plugin
- */
-gint xs_is_our_file(gchar *pcFileName)
-{
- char *pcExt;
- t_xs_tune *testTune;
-
- /* Check the filename */
- if (pcFileName == NULL)
-	return FALSE;
-
- /* Try to detect via libSIDPlay's detection routine, if required */
- if (xs_cfg.detectMagic)
-	{
-	testTune = new t_xs_tune(pcFileName);
-	if (testTune == NULL) return FALSE;
-	if (testTune->getStatus())
-		{
-		delete testTune;
-		return TRUE;
-		}
-
-	/* We DON'T fall back to filename extension checking ... */
-	delete testTune;
-	return FALSE;
-	}
-
- /* Detect just by checking filename extension */
- pcExt = xs_strrchr(pcFileName, '.');
- if (pcExt)
-	{
-	pcExt++;
-	if (!g_strcasecmp(pcExt, "psid")) return TRUE;
-	if (!g_strcasecmp(pcExt, "sid")) return TRUE;
-	if (!g_strcasecmp(pcExt, "dat")) return TRUE;
-	if (!g_strcasecmp(pcExt, "inf")) return TRUE;
-	if (!g_strcasecmp(pcExt, "info")) return TRUE;
-	}
-
- return FALSE;
-}
-
-
-/*
- * Main playing thread loop
- */
-void *xs_play_loop(void *argPointer)
-{
- t_xs_status myStatus;
- t_xs_tuneinfo tuneInfo;
- gboolean audioOpen;
- gint audioFreq, audioChannels, songLength;
- enum AFormat audioFmt;
- gchar audioBuffer[XS_BUFSIZE];
- gchar *tmpStr;
-
-
- 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;
-#else
- audioFmt = (xs_cfg.fmtBitsPerSample == XS_RES_16BIT) ? FMT_S16_NE : FMT_S8;
-#endif
- audioFreq = xs_cfg.fmtFrequency;
- audioChannels = (xs_cfg.fmtChannels == XS_CHN_MONO) ? 1 : 2;
- audioOpen = FALSE;
-
- /*
-  * Main player loop: while not stopped, loop here - play subtunes
-  */
- while (xs_status.isPlaying)
- {
- pthread_mutex_lock(&xs_mutex);
- myStatus.currSong = xs_status.currSong;
- myStatus.isPlaying = TRUE;
- pthread_mutex_unlock(&xs_mutex);
-
- XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong);
-
-
- /* Get song length for current subtune */
- songLength = xs_songlen_get(myStatus.currFileName, myStatus.currSong);
-
- /* Initialize song */
-#ifdef HAVE_SIDPLAY1
- if ((myStatus.currTune == NULL) || !myStatus.currTune->getStatus() ||
-	!sidEmuInitializeSong(xs_emuEngine, *myStatus.currTune, myStatus.currSong))
-#endif
-#ifdef HAVE_SIDPLAY2
- if ()
-#endif
-	{
-	XSERR("Couldn't initialize SID-tune '%s' (sub-tune #%i)!\n",
-		myStatus.currFileName, myStatus.currSong);
-	goto err_exit;
-	}
-
- myStatus.currTune->getInfo(tuneInfo);
-
-
- /* Set information for current sub-tune */
- tmpStr = xs_filetitle_get(myStatus.currFileName, &tuneInfo, myStatus.currSong);
-
- xs_plugin_ip.set_info(tmpStr, (songLength > 0) ? songLength * 1000 : -1,
- 1000 * (tuneInfo.songSpeed ? tuneInfo.songSpeed : (tuneInfo.clockSpeed == SIDTUNE_CLOCK_NTSC) ? 60 : 50),
- audioFreq, audioChannels);
- g_free(tmpStr);
-
- /* Open the audio output */
- if (!xs_plugin_ip.output->open_audio(audioFmt, audioFreq, audioChannels))
-	{
-	XSERR("Couldn't open XMMS audio output!\n");
-	pthread_mutex_lock(&xs_mutex);
-	xs_status.isError = TRUE;
-	pthread_mutex_unlock(&xs_mutex);
-	goto err_exit;
-	}
-
- audioOpen = TRUE;
-
- /*
-  * Play the subtune
-  */
- while (xs_status.isPlaying && myStatus.isPlaying && (xs_status.currSong == myStatus.currSong))
-	{
-	/* Render audio data */
-#ifdef HAVE_SIDPLAY1
-	sidEmuFillBuffer(xs_emuEngine, *myStatus.currTune, audioBuffer, XS_BUFSIZE);
-#endif
-#ifdef HAVE_SIDPLAY2
-#endif
-
-	/* I <3 visualice/haujobb */
-	xs_plugin_ip.add_vis_pcm(
-		xs_plugin_ip.output->written_time(),
-		audioFmt, audioChannels, XS_BUFSIZE, audioBuffer);
-
-	/* Wait a little */
-	while (xs_status.isPlaying &&
-		(xs_status.currSong == myStatus.currSong) &&
-		(xs_plugin_ip.output->buffer_free() < XS_BUFSIZE))
-		xmms_usleep(10000);
-
-	/* Output audio */
-	if (xs_status.isPlaying && (xs_status.currSong == myStatus.currSong))
-		xs_plugin_ip.output->write_audio(audioBuffer, XS_BUFSIZE);
-
-	/* Check if we have played enough */
-	if (xs_cfg.playMaxTimeEnable)
-		{
-		if (xs_cfg.playMaxTimeUnknown)
-			{
-			if ((songLength == -1) &&
-				(xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000)))
-				myStatus.isPlaying = FALSE;
-			} else {
-			if (xs_plugin_ip.output->output_time() >= (xs_cfg.playMaxTime * 1000))
-				myStatus.isPlaying = FALSE;
-			}
-		}
-
-	if (songLength > 0)
-		{
-		if (xs_plugin_ip.output->output_time() >= (songLength * 1000))
-			myStatus.isPlaying = FALSE;
-		}
-	}
-
- XSDEBUG("subtune ended/stopped\n");
-
- /* Close audio */
- if (audioOpen)
-	{
-	XSDEBUG("close audio #1\n");
-	xs_plugin_ip.output->close_audio();
-	audioOpen = FALSE;
-	}
-
- /* Now determine if we continue by selecting other subtune or something */
- if (!myStatus.isPlaying) xs_status.isPlaying = FALSE;
- }
-
- /* When exiting, delete data */
-err_exit:
- pthread_mutex_lock(&xs_mutex);
- xs_status.isPlaying = FALSE;
- pthread_mutex_unlock(&xs_mutex);
-
- if (audioOpen)
-	{
-	XSDEBUG("close audio #2\n");
-	xs_plugin_ip.output->close_audio();
-	}
-
- if (myStatus.currTune != NULL)
-	{
-	delete myStatus.currTune;
-	myStatus.currTune = NULL;
-	}
-
- g_free(myStatus.currFileName);
-
- /* 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_status.allowNext = TRUE;
- pthread_mutex_unlock(&xs_mutex);
-
- pthread_exit(NULL);
-}
-
-
-/*
- * Start playing the given file
- */
-void xs_play_file(char *pcFileName)
-{
- t_xs_tune *newTune;
- t_xs_tuneinfo tuneInfo;
-
- /* Can we set the next tune? */ 
- XSDEBUG("request to play '%s'\n", pcFileName);
-
- /* Try to get the tune */
- newTune = new t_xs_tune(pcFileName);
- if (newTune == NULL) return;
-
-#ifdef HAVE_SIDPLAY1
- /* Get current configuration */
- xs_emuEngine.getConfig(xs_emuConf);
-
- /* Configure channels and stuff */
- switch (xs_cfg.fmtChannels) {
-
-	case XS_CHN_AUTOPAN:
-		xs_emuConf.channels = SIDEMU_STEREO;
-		xs_emuConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING;
-		xs_emuConf.volumeControl = SIDEMU_FULLPANNING;
-		break;
-
-	case XS_CHN_STEREO:
-		xs_emuConf.channels = SIDEMU_STEREO;
-		xs_emuConf.autoPanning = SIDEMU_NONE;
-		xs_emuConf.volumeControl = SIDEMU_NONE;
-		break;
-
-	case XS_CHN_MONO:
-	default:
-		xs_emuConf.channels = SIDEMU_MONO;
-		xs_emuConf.autoPanning = SIDEMU_NONE;
-		xs_emuConf.volumeControl = SIDEMU_NONE;
-		break;
- }
-
-
- /* Memory mode settings */
- switch (xs_cfg.memoryMode) {
-	case XS_MPU_BANK_SWITCHING:
-		xs_emuConf.memoryMode = MPU_BANK_SWITCHING;
-		break;
-
-	case XS_MPU_TRANSPARENT_ROM:
-		xs_emuConf.memoryMode = MPU_TRANSPARENT_ROM;
-		break;
-
-	case XS_MPU_PLAYSID_ENVIRONMENT:
-		xs_emuConf.memoryMode = MPU_PLAYSID_ENVIRONMENT;
-		break;
-
-	default:
-		xs_emuConf.memoryMode = MPU_BANK_SWITCHING;
-		break;
- }
-
-
- /* Clockspeed settings */
- switch (xs_cfg.clockSpeed) {
-	case XS_CLOCK_NTSC:
-		xs_emuConf.clockSpeed = SIDTUNE_CLOCK_NTSC;
-		break;
-
-	case XS_CLOCK_PAL:
-	default:
-		xs_emuConf.clockSpeed = SIDTUNE_CLOCK_PAL;
-		break;
- }
-
-
- /* Configure rest of the emulation */
- xs_emuConf.bitsPerSample	= xs_cfg.fmtBitsPerSample;
- xs_emuConf.frequency		= xs_cfg.fmtFrequency;
-#ifdef HAVE_UNSIGNEDPCM
- xs_emuConf.sampleFormat	= SIDEMU_UNSIGNED_PCM;
-#else
- xs_emuConf.sampleFormat	= SIDEMU_SIGNED_PCM;
-#endif
- xs_emuConf.mos8580		= xs_cfg.mos8580;
- xs_emuConf.emulateFilter	= xs_cfg.emulateFilters;
- xs_emuConf.filterFs		= xs_cfg.filterFs;
- xs_emuConf.filterFm		= xs_cfg.filterFm;
- xs_emuConf.filterFt		= xs_cfg.filterFt;
-
- /* Now set the emulator configuration */
- xs_emuEngine.setConfig(xs_emuConf);
-#endif
-
-
-#ifdef HAVE_SIDPLAY2
- /* Get current configuration */
- xs_emuConf = xs_emuEngine.config();
-
- /* Configure channels and stuff */
- switch (xs_cfg.fmtChannels) {
-
-	case XS_CHN_AUTOPAN:
-		xs_emuConf.playback = sid2_stereo;
-		break;
-
-	case XS_CHN_STEREO:
-		xs_emuConf.playback = sid2_stereo;
-		break;
-
-	case XS_CHN_MONO:
-	default:
-		xs_emuConf.playback = sid2_mono;
-		break;
- }
-
-
- /* Memory mode settings */
- switch (xs_cfg.memoryMode) {
-	case XS_MPU_BANK_SWITCHING:
-		xs_emuConf.environment = sid2_envBS;
-		break;
-
-	case XS_MPU_TRANSPARENT_ROM:
-		xs_emuConf.environment = sid2_envTP;
-		break;
-
-	case XS_MPU_PLAYSID_ENVIRONMENT:
-		xs_emuConf.environment = sid2_envPS;
-		break;
-
-	case XS_MPU_REAL:
-	default:
-		xs_emuConf.environment = sid2_envR;
-		break;
- }
-
-
- /* Clockspeed settings */
- switch (xs_cfg.clockSpeed) {
-	case XS_CLOCK_NTSC:
-		xs_emuConf.clockSpeed = xs_emuConf.clockDefault = SID2_CLOCK_NTSC;
-		break;
-
-	case XS_CLOCK_PAL:
-	default:
-		xs_emuConf.clockSpeed = xs_emuConf.clockDefault = SID2_CLOCK_PAL;
-		break;
- }
-
-
- /* Configure rest of the emulation */
- xs_emuConf.precision		= xs_cfg.fmtBitsPerSample;
- xs_emuConf.frequency		= xs_cfg.fmtFrequency; 
- xs_emuConf.clockForced		= xs_cfg.forceSpeed;
- xs_emuConf.optimisation	= (xs_cfg.optimiseLevel) ? 1 : 0;
- xs_emuConf.sidDefault		= xs_emuConf.sidModel = (xs_cfg.mos8580) ? SID2_MOS8580 : SID2_MOS6581;
- xs_emuConf.sidSamples		= TRUE;	// FIXME FIX ME, make configurable!
-
-#ifdef HAVE_UNSIGNEDPCM
-#ifdef WORDS_BIGENDIAN
- xs_emuConf.sampleFormat	= SID2_BIG_UNSIGNED;
-#else
- xs_emuConf.sampleFormat	= SID2_LITTLE_UNSIGNED;
-#endif
-#else
-#ifdef WORDS_BIGENDIAN
- xs_emuConf.sampleFormat	= SID2_BIG_SIGNED;
-#else
- xs_emuConf.sampleFormat	= SID2_LITTLE_SIGNED;
-#endif
-#endif
-
- /* Now set the emulator configuration */
- xs_emuEngine.config(xs_emuConf);
-#endif
-
-
- /* Initialize status information */
- XSDEBUG("starting playing thread!\n");
-
- newTune->getInfo(tuneInfo);
-
- xs_status.isPlaying	= TRUE;
- xs_status.isError	= FALSE;
- xs_status.currSong	= tuneInfo.startSong;
- xs_status.nSongs	= tuneInfo.songs;
- xs_status.currTune	= newTune;
- xs_status.currFileName = g_strdup(pcFileName);
-
- /* Start the playing thread! */
- if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0)
-	{
-	XSERR("Couldn't start playing thread! Possible reason reported by system: %s\n", strerror(errno));
-	delete newTune;
-	}
-
- XSDEBUG("systems should be up?\n");
-
- /* Exit */
-}
-
-
-/*
- * Stop playing
- */
-void xs_stop(void)
-{
- /* If playing, stop. */
- XSDEBUG("STOP_REQ\n");
- if (xs_status.isPlaying || !xs_status.allowNext)
-	{
-	XSDEBUG("stopping...\n");
-	pthread_mutex_lock(&xs_mutex);
-	xs_status.isPlaying = FALSE;
-	pthread_mutex_unlock(&xs_mutex);
-	pthread_join(xs_decode_thread, NULL);
-	}
-}
-
-
-/*
- * Pause the playing
- */
-void xs_pause(short pauseState)
-{
- xs_plugin_ip.output->pause(pauseState);
-}
-
-
-/*
- * Set the time-seek position
- * (the playing thread will do the "seeking" aka song-change)
- */
-void xs_seek(gint iTime)
-{
- /* If we have song-position patch, check settings */
-#ifdef HAVE_SONG_POSITION
- pthread_mutex_lock(&xs_mutex);
-
- if ((iTime > 0) && (iTime <= xs_status.nSongs) && xs_status.isPlaying)
-	xs_status.currSong = iTime;
-
- pthread_mutex_unlock(&xs_mutex);
-#endif
-}
-
-
-/*
- * Return the playing "position/time"
- */
-gint xs_get_time(void)
-{
- /* If errorflag is set, return -2 to signal it to XMMS's idle callback */
- if (xs_status.isError)
-	return -2;
-
- /* If tune has ended, return -1 */
- if (xs_status.allowNext && !xs_status.isPlaying)
-	return -1;
-
- /* Obsolete? */
-#ifdef HAVE_SONG_POSITION
- pthread_mutex_lock(&xs_mutex);
- set_song_position(xs_status.currSong, 1, xs_status.nSongs);
- pthread_mutex_unlock(&xs_mutex);
-#endif
-
- /* Else, return output time reported by audio output plugin */
- return xs_plugin_ip.output->output_time();
-}
-
-
-/*
- * Return song information
- */
-void xs_get_song_info(gchar *songFileName, gchar **songTitle, gint *songLength)
-{
- t_xs_tuneinfo tuneInfo;
- t_xs_tune *testTune;
- gint tmpInt;
-
- /* Check if the tune exists and is readable */
- testTune = new t_xs_tune(songFileName);
- if (testTune == NULL) return;
- if (!testTune->getStatus())
-	{
-	delete testTune;
-	return;
-	}
-
- /* Get general tune information */
- testTune->getInfo(tuneInfo);
- delete testTune;
-
- /* Get titlestring */
- *songTitle = xs_filetitle_get(songFileName, &tuneInfo, tuneInfo.startSong);
-
- /* Get song length (in milliseconds), negative if no known length */
- tmpInt = xs_songlen_get(songFileName, tuneInfo.startSong);
- if (tmpInt >= 0)
-	*songLength = (tmpInt * 1000);
-	else
-	*songLength = -1;
-}
-
-
-/*
- * Create the SID-tune description string from the tune's information
- * formatted by the user-specified format-string.
- */
-gchar *xs_filetitle_get(gchar *pcFileName, t_xs_tuneinfo *pfInfo, gint iSubTune)
-{
- gint j, iLength;
- gchar *pcStr, *pcResult;
-#ifdef HAVE_XMMSEXTRA
- TitleInput *ptInput;
-#endif
-
- /* FIXME FIXME: get STIL-information */
- 
-	
- /* Check the info strings */
- if (pfInfo->numberOfInfoStrings < 3)
-	{
-	if (pfInfo->numberOfInfoStrings < 1)
-		return 0;
-
-	return g_strdup(pfInfo->infoString[0]);
-	}
-
-#ifdef HAVE_XMMSEXTRA
- /* Check if the titles are overridden or not */
- if (!xs_cfg.titleOverride)
-	{
-	/* Use generic XMMS titles */
-	/* XMMS_NEW_TITLEINPUT(ptInput);
-	 * We duplicate and add typecast to the code here due to XMMS's braindead headers
-	 */
-	ptInput = (TitleInput *) g_malloc0(sizeof(TitleInput));
-	ptInput->__size = XMMS_TITLEINPUT_SIZE;
-	ptInput->__version = XMMS_TITLEINPUT_VERSION;
-
-	/* Create the input fields */
-	ptInput->file_name	= pfInfo->dataFileName;
-	ptInput->file_ext	= g_strdup("sid");
-	ptInput->file_path	= pfInfo->path;
-
-	ptInput->track_name	= pfInfo->infoString[0];
-	ptInput->track_number	= iSubTune;
-	ptInput->album_name	= NULL;
-	ptInput->performer	= pfInfo->infoString[1];
-	ptInput->date		= g_strdup((pfInfo->sidModel == SIDTUNE_SIDMODEL_6581) ? "6581" : "8580");
-
-	ptInput->year		= 0;
-	ptInput->genre		= g_strdup("SID-tune");
-	ptInput->comment	= pfInfo->infoString[2];
-
-	/* Create the string */
-	pcResult = xmms_get_titlestring(xmms_get_gentitle_format(), ptInput);
-
-	/* Dispose all allocated memory */
-	g_free(ptInput->file_ext);
-	g_free(ptInput->date);
-	g_free(ptInput->genre);
-	g_free(ptInput);
-	}
-	else
-#endif
-	{
-	/* Estimate the length of the string */
-	pcStr = xs_cfg.titleFormat;
-	iLength = 0;
-	while (*pcStr)
-	{
-	if (*pcStr == '%')
-		{
-		switch (*(++pcStr)) {
-		case '1': iLength += strlen(pfInfo->infoString[1]); break;
-		case '2': iLength += strlen(pfInfo->infoString[0]); break;
-		case '3': iLength += strlen(pfInfo->infoString[2]); break;
-		case '4': iLength += strlen(pfInfo->formatString); break;
-		case '%': iLength++;
-		}
-		} else
-		iLength++;
-
-	pcStr++;
-	}
-
-	/* Allocate memory */
-	pcResult = (gchar *) g_malloc(iLength + 2);
-	if (pcResult == NULL)
-		return g_strdup(pfInfo->infoString[0]);
-
-	/* Create the string */
-	pcStr = xs_cfg.titleFormat;
-	j = 0;
-	while (*pcStr)
-	{
-	if (*pcStr == '%')
-		{
-		switch (*(++pcStr)) {
-		case '1': xs_strpcat(pcResult, &j, pfInfo->infoString[1]); break;
-		case '2': xs_strpcat(pcResult, &j, pfInfo->infoString[0]); break;
-		case '3': xs_strpcat(pcResult, &j, pfInfo->infoString[2]); break;
-		case '4': xs_strpcat(pcResult, &j, pfInfo->formatString); break;
-		case '%': pcResult[j++] = '%'; break;
-		}
-		} else
-		pcResult[j++] = *pcStr;
-
-	pcStr++;
-	}
-
-	pcResult[j] = 0;
-	}
-
- return pcResult;
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xs_sidplay1.cc	Wed Sep 10 06:21:04 2003 +0000
@@ -0,0 +1,173 @@
+/*
+   XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
+
+   libSIDPlay v1 support
+
+   Written by Matti "ccr" Hamalainen <ccr@tnsp.org>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifdef HAVE_SIDPLAY1
+#include "xmms-sid.h"
+
+extern "C" {
+#include <xmms/title.h>
+}
+
+#include <sidplay/player.h>
+#include <sidplay/myendian.h>
+#include <sidplay/fformat.h>
+
+
+struct xs_sidplay1 {
+	struct emuConfig	emuConf;
+	emuEngine		emuEngine;
+	gboolean	isError, isPlaying, allowNext;
+	gint		currSong, nSongs;
+	sidTune		*currTune;
+	gchar		*currFileName;
+};
+
+
+
+gboolean xs_sidplay1_initsong(struct xs_sidplay1 *myStatus)
+{
+ return sidEmuInitializeSong(myStatus->emuEngine, myStatus->currTune, myStatus->currSong);
+}
+
+
+void xs_sidplay1_fillbuffer(struct xs_sidplay1 *myStatus, gchar *audioBuffer, gint audioBufSize)
+{
+ sidEmuFillBuffer(myStatus->emuEngine, myStatus->currTune, audioBuffer, audioBufSize);
+}
+
+
+gint xs_sidplay1_inittune(gchar *pcFileName)
+{
+ sidTune *newTune;
+ sidTuneInfo tuneInfo;
+
+ /* Can we set the next tune? */ 
+ XSDEBUG("request to play '%s'\n", pcFileName);
+
+ /* Try to get the tune */
+ newTune = new sidTune(pcFileName);
+ if (newTune == NULL) return;
+
+ /* Get current configuration */
+ xs_emuEngine.getConfig(xs_emuConf);
+
+ /* Configure channels and stuff */
+ switch (xs_cfg.fmtChannels) {
+
+	case XS_CHN_AUTOPAN:
+		xs_emuConf.channels = SIDEMU_STEREO;
+		xs_emuConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING;
+		xs_emuConf.volumeControl = SIDEMU_FULLPANNING;
+		break;
+
+	case XS_CHN_STEREO:
+		xs_emuConf.channels = SIDEMU_STEREO;
+		xs_emuConf.autoPanning = SIDEMU_NONE;
+		xs_emuConf.volumeControl = SIDEMU_NONE;
+		break;
+
+	case XS_CHN_MONO:
+	default:
+		xs_emuConf.channels = SIDEMU_MONO;
+		xs_emuConf.autoPanning = SIDEMU_NONE;
+		xs_emuConf.volumeControl = SIDEMU_NONE;
+		break;
+ }
+
+
+ /* Memory mode settings */
+ switch (xs_cfg.memoryMode) {
+	case XS_MPU_BANK_SWITCHING:
+		xs_emuConf.memoryMode = MPU_BANK_SWITCHING;
+		break;
+
+	case XS_MPU_TRANSPARENT_ROM:
+		xs_emuConf.memoryMode = MPU_TRANSPARENT_ROM;
+		break;
+
+	case XS_MPU_PLAYSID_ENVIRONMENT:
+		xs_emuConf.memoryMode = MPU_PLAYSID_ENVIRONMENT;
+		break;
+
+	default:
+		xs_emuConf.memoryMode = MPU_BANK_SWITCHING;
+		break;
+ }
+
+
+ /* Clockspeed settings */
+ switch (xs_cfg.clockSpeed) {
+	case XS_CLOCK_NTSC:
+		xs_emuConf.clockSpeed = SIDTUNE_CLOCK_NTSC;
+		break;
+
+	case XS_CLOCK_PAL:
+	default:
+		xs_emuConf.clockSpeed = SIDTUNE_CLOCK_PAL;
+		break;
+ }
+
+
+ /* Configure rest of the emulation */
+ xs_emuConf.bitsPerSample	= xs_cfg.fmtBitsPerSample;
+ xs_emuConf.frequency		= xs_cfg.fmtFrequency;
+#ifdef HAVE_UNSIGNEDPCM
+ xs_emuConf.sampleFormat	= SIDEMU_UNSIGNED_PCM;
+#else
+ xs_emuConf.sampleFormat	= SIDEMU_SIGNED_PCM;
+#endif
+ xs_emuConf.mos8580		= xs_cfg.mos8580;
+ xs_emuConf.emulateFilter	= xs_cfg.emulateFilters;
+ xs_emuConf.filterFs		= xs_cfg.filterFs;
+ xs_emuConf.filterFm		= xs_cfg.filterFm;
+ xs_emuConf.filterFt		= xs_cfg.filterFt;
+
+ /* Now set the emulator configuration */
+ xs_emuEngine.setConfig(xs_emuConf);
+
+
+ /* Initialize status information */
+ XSDEBUG("starting playing thread!\n");
+
+ newTune->getInfo(tuneInfo);
+
+ xs_status->isPlaying	= TRUE;
+ xs_status->isError	= FALSE;
+ xs_status->currSong	= tuneInfo.startSong;
+ xs_status->nSongs	= tuneInfo.songs;
+ xs_status->currTune	= newTune;
+ xs_status->currFileName = g_strdup(pcFileName);
+
+ /* Start the playing thread! */
+ if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0)
+	{
+	XSERR("Couldn't start playing thread! Possible reason reported by system: %s\n", strerror(errno));
+	delete newTune;
+	}
+
+ XSDEBUG("systems should be up?\n");
+
+ /* Exit */
+}
+
+
+#endif	/* HAVE_SIDPLAY1 */
+