diff src/xmms-sid.cc @ 40:1788f4ce6a44

Numerous changes towards 0.8
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 19 Jun 2003 22:38:01 +0000
parents 15250dd0c326
children 0f00ebab063d
line wrap: on
line diff
--- a/src/xmms-sid.cc	Thu Jun 19 20:49:01 2003 +0000
+++ b/src/xmms-sid.cc	Thu Jun 19 22:38:01 2003 +0000
@@ -19,7 +19,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
-
+extern "C" {
 #include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
@@ -27,30 +27,44 @@
 #include <errno.h>
 #include <xmms/plugin.h>
 #include <xmms/util.h>
+#include <xmms/titlestring.h>
 #include "xmms-sid.h"
+#include "xs_support.h"
 #include "xs_config.h"
 #include "xs_length.h"
-#include "xs_title.h"
+}
 
-extern "C++" {
+#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
 static struct emuConfig	xs_emuConf;
 static emuEngine	xs_emuEngine;
+typedef	sidTune		t_xs_tune;
+#endif
+
+#ifdef HAVE_SIDPLAY2
+#endif
+
 static pthread_t	xs_decode_thread;
 struct t_xs_cfg		xs_cfg;
 
 struct {
-	int	s_error, s_playing, s_songs, s_allownext;
-	sidTune	*s_tune;
-	gchar	*s_fname;
+	gboolean	isError, isPlaying, allowNext;
+	gint		currSong, nSongs;
+	t_xs_tune	*currTune;
+	gchar		*currFilename;
 } xs_status;
 
 pthread_mutex_t xs_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -66,29 +80,31 @@
  /* Initialize and get configuration */
  memset(&xs_cfg, 0, sizeof(xs_cfg));
 
- xs_get_configure();
+ xs_read_configuration();
 
- xs_status.s_error = 0;
- xs_status.s_playing = 0;
- xs_status.s_songs = 0;
- xs_status.s_allownext = 1;	// Initialize to TRUE to allow first song
- xs_status.s_tune = NULL;
- xs_status.s_fname = NULL;
+ xs_status.isError	= FALSE;
+ xs_status.isPlaying	= FALSE;
+ xs_status.nSongs	= 0;
+ xs_status.currSong	= 0;
+ xs_status.allowNext	= TRUE;	// Initialize to TRUE to allow first song
+ xs_status.currTune	= NULL;
+ xs_status.currFilename	= NULL;
 
- /* Try to initialize libSIDPlay */
- if (!xs_emuEngine)
+
+ /* Try to initialize libSIDPlay(s) */
+#ifdef HAVE_SIDPLAY1
+ if (!xs_emuEngine || !xs_emuEngine.verifyEndianess())
 	{
-	XSERR("Couldn't start SIDPlay emulator engine!\n");
+	XSERR("Couldn't start SIDPlay1 emulator engine!\n");
 	return;
 	}
+#endif
 
- if (!xs_emuEngine.verifyEndianess())
-	{
-	XSERR("Wrong hardware endianess (SIDPlay error)!\n");
-	return;
-	}
+#ifdef HAVE_SIDPLAY2
+#endif
 
  /* Read song-length database */
+ if (xs_cfg.songlenDBEnable)
  if (xs_songlen_init() < 0)
 	{
 	XSERR("Error initializing song-length database!\n");
@@ -112,6 +128,13 @@
  /* Stop playing */
  xs_plugin_ip.stop();
 
+ /* Shutdown libSIDPlay(s) */
+#ifdef HAVE_SIDPLAY1
+#endif
+
+#ifdef HAVE_SIDPLAY2
+#endif
+
  /* Close sub-song control window */
 
  /* Free allocated memory */
@@ -135,8 +158,8 @@
  /* Try to detect via libSIDPlay's detection routine, if required */
  if (xs_cfg.detectMagic)
 	{
-	sidTune *testTune = new sidTune(fileName);
-
+#ifdef HAVE_SIDPLAY1
+	t_xs_tune *testTune = new sidTune(fileName);
 	if (!testTune) return FALSE;
 	if (!testTune->getStatus())
 		{
@@ -146,9 +169,11 @@
 
 	delete testTune;
 	return TRUE;
+#endif
+#ifdef HAVE_SIDPLAY2
+#endif
 	}
 
-
  /* Detect just by checking filename extension */
  pcExt = strrchr(fileName, '.');
  if (pcExt)
@@ -170,152 +195,15 @@
  */
 static void *xs_play_loop(void *argPointer)
 {
- guchar			plr_data[XS_BUFSIZE];
- struct sidTuneInfo	plr_sidInf;
- gchar			*plr_tune_title = NULL;
- gint			plr_fxlen;
- enum AFormat		plr_fmt;
- gint			plr_tune_num;
- gint32			plr_tune_len;
-
-
  /* Don't allow next song to be set yet */
  pthread_mutex_lock(&xs_mutex);
- xs_status.s_allownext = 0;
+ xs_status.allowNext = FALSE;
  pthread_mutex_unlock(&xs_mutex);
 
 
- /* Check tune number */
- plr_tune_num = xs_status.s_playing;
 
- if (plr_tune_num <= 0)
-	plr_tune_num = 1;
-
-XSDEBUG("xs_play_loop(%d, %d)\n", plr_tune_num, xs_status.s_playing);
-
- /* Get song information */
- xs_status.s_tune->getInfo(plr_sidInf);
- plr_tune_len = xs_songlen_get(xs_status.s_fname, plr_tune_num);
- plr_tune_title = xs_filetitle_get(&plr_sidInf, plr_tune_num);
-
-XSDEBUG("title='%s', len=%d\n", plr_tune_title, plr_tune_len);
-
-
- /* Initialize audio output */
- // FIXME FIXME: FMT_S16_XXX -- different architechtures??
- // the patch may break something ...
- plr_fmt = (xs_emuConf.bitsPerSample == 16) ? FMT_S16_NE : FMT_U8;
-
-
- if (!xs_plugin_ip.output->open_audio(plr_fmt, xs_emuConf.frequency, xs_emuConf.channels))
-	{
-	pthread_mutex_lock(&xs_mutex);
-	xs_status.s_error = 1;
-	if (plr_tune_title) g_free(plr_tune_title);
-	if (xs_status.s_tune) delete xs_status.s_tune;
-	xs_status.s_allownext = 1;
-	pthread_mutex_unlock(&xs_mutex);
-	return NULL;
-	}
-
-
- /* Initialize the SIDPlay-emulator for song */
- if (!sidEmuInitializeSong(xs_emuEngine, *xs_status.s_tune, plr_tune_num))
-	{
-	XSERR("Couldn't initialize SIDPlay emulator engine! This may be a problem with your sound settings, or possibly a bug in XMMS-SID.\n");
-	pthread_mutex_lock(&xs_mutex);
-	xs_status.s_error = 1;
-	pthread_mutex_unlock(&xs_mutex);
-	goto pl_cleanup;
-	}
-
-
- /* Set song title information */
- xs_plugin_ip.set_info(
-	plr_tune_title, 
-	(plr_tune_len * 1000),
-	(1000 * (plr_sidInf.songSpeed ? plr_sidInf.songSpeed : (plr_sidInf.clockSpeed == SIDTUNE_CLOCK_NTSC) ? 60 : 50)),
-	xs_emuConf.frequency,
-	xs_emuConf.channels);
-
-
- /* Run playing loop: loop as long as xs_playing is same as current tune number */
- while (xs_status.s_playing == plr_tune_num)
-	{
-	plr_fxlen = XS_BUFSIZE;
-
-	/* Run emulator to fill output buffer with audio data */
-	sidEmuFillBuffer(xs_emuEngine, *xs_status.s_tune, plr_data, plr_fxlen);
-
-	/* If Max Playtime option set, check playtime */
-	if (xs_cfg.playUseMaxTime)
-		{
-		if ((xs_plugin_ip.output->output_time() / 1000) >= xs_cfg.playMaxTime)
-			{
-			pthread_mutex_lock(&xs_mutex);
-			xs_status.s_playing = 0;
-			pthread_mutex_unlock(&xs_mutex);
-			}
-		}
-
-	/* Check playtime against database */
-	if (xs_cfg.playMethod == XMMS_SID_PMETHOD_DATABASE)
-		{
-		if ((xs_plugin_ip.output->output_time() / 1000) >= plr_tune_len)
-			{
-			pthread_mutex_lock(&xs_mutex);
-			xs_status.s_playing = 0;
-			pthread_mutex_unlock(&xs_mutex);
-			}
-
-		}
-#if 0
-		else
-
-	/* Check for silence */
-	if (xs_cfg.playMethod == XMMS_SID_PMETHOD_MAXSILENCE)
-		{
-		}
-
-	/* Add static noise */
-
-	/* Muffle waveform (low-pass filter) */
-
-#endif
-
-
-		/* Send audio data to visualization plugin */
-		xs_plugin_ip.add_vis_pcm(xs_plugin_ip.output->written_time(),
-					plr_fmt, xs_emuConf.channels, plr_fxlen, plr_data);
-
-		/* Wait for a while */
-		while ((xs_status.s_playing == plr_tune_num) && (xs_plugin_ip.output->buffer_free() < plr_fxlen))
-			xmms_usleep(10000);
-
-
-		/* If playing, send final audio data to output plugin */
-		if (xs_status.s_playing == plr_tune_num)
-			xs_plugin_ip.output->write_audio(plr_data, plr_fxlen);
-
-	}	/* End of playerloop */
-
-
-pl_cleanup:
-	XSDEBUG("cleaning up...\n");
-
-	/* Cleanup & shutdown */
-	xs_plugin_ip.output->close_audio();
-
-	if (plr_tune_title) g_free(plr_tune_title);
-
-	pthread_mutex_lock(&xs_mutex);
-	xs_status.s_playing = 0;
-	if (xs_status.s_tune) delete xs_status.s_tune;
-	xs_status.s_allownext = 1;
-	pthread_mutex_unlock(&xs_mutex);
-
-	XSDEBUG("exiting thread, bye.\n");
-	return NULL;
+ XSDEBUG("exiting thread, bye.\n");
+ return NULL;
 }
 
 
@@ -324,20 +212,29 @@
  */
 void xs_play_file(char *fileName)
 {
- sidTune *newTune;
+ t_xs_tune *newTune;
  struct sidTuneInfo sidInf;
 
- XSDEBUG("request to start '%s'\n", fileName);
+ XSDEBUG("request to load '%s'\n", fileName);
+
 
- /* Wait until the previous song has finished for sure */
- if (!xs_status.s_allownext)
-	pthread_join(xs_decode_thread, NULL);
+ /* Initialize audio output */
+ XSDEBUG("opening audio output plugin...\n");
+ if (!xs_plugin_ip.output->open_audio(
+	((xs_cfg.fmtBitsPerSample == 16) ? FMT_S16_NE : FMT_U8), xs_cfg.fmtFrequency,
+	((xs_cfg.fmtChannels == XS_CHN_MONO) ? 1 : 2)))
+	{
+	XSERR("Couldn't open audio output plugin!\n");
+	delete newTune;
+	return;
+	}
+
 
  /* Try to get the tune */
  newTune = new sidTune(fileName);
  if (newTune == NULL) return;
 
- XSDEBUG("tune ok, status %i\n", xs_status.s_playing);
+ XSDEBUG("tune ok, configuring SIDPlay engine\n");
 
 
  /* Get current configuration */
@@ -347,19 +244,19 @@
  /* Configure channels and stuff */
  switch (xs_cfg.fmtChannels) {
 
-	case XMMS_SID_CHN_AUTOPAN:
+	case XS_CHN_AUTOPAN:
 		xs_emuConf.channels = SIDEMU_STEREO;
 		xs_emuConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING;
 		xs_emuConf.volumeControl = SIDEMU_FULLPANNING;
 		break;
 
-	case XMMS_SID_CHN_STEREO:
+	case XS_CHN_STEREO:
 		xs_emuConf.channels = SIDEMU_STEREO;
 		xs_emuConf.autoPanning = SIDEMU_NONE;
 		xs_emuConf.volumeControl = SIDEMU_NONE;
 		break;
 
-	case XMMS_SID_CHN_MONO:
+	case XS_CHN_MONO:
 		xs_emuConf.channels = SIDEMU_MONO;
 		xs_emuConf.autoPanning = SIDEMU_NONE;
 		xs_emuConf.volumeControl = SIDEMU_NONE;
@@ -374,15 +271,15 @@
 
  /* Memory mode settings */
  switch (xs_cfg.memoryMode) {
-	case XMMS_SID_MPU_BANK_SWITCHING:
+	case XS_MPU_BANK_SWITCHING:
 		xs_emuConf.memoryMode = MPU_BANK_SWITCHING;
 		break;
 
-	case XMMS_SID_MPU_TRANSPARENT_ROM:
+	case XS_MPU_TRANSPARENT_ROM:
 		xs_emuConf.memoryMode = MPU_TRANSPARENT_ROM;
 		break;
 
-	case XMMS_SID_MPU_PLAYSID_ENVIRONMENT:
+	case XS_MPU_PLAYSID_ENVIRONMENT:
 		xs_emuConf.memoryMode = MPU_PLAYSID_ENVIRONMENT;
 		break;
 
@@ -395,11 +292,11 @@
 
  /* Clockspeed settings */
  switch (xs_cfg.clockSpeed) {
-	case XMMS_SID_CLOCK_PAL:
+	case XS_CLOCK_PAL:
 		xs_emuConf.clockSpeed = SIDTUNE_CLOCK_PAL;
 		break;
 
-	case XMMS_SID_CLOCK_NTSC:
+	case XS_CLOCK_NTSC:
 		xs_emuConf.clockSpeed = SIDTUNE_CLOCK_NTSC;
 		break;
 
@@ -415,7 +312,7 @@
  xs_emuConf.frequency		= xs_cfg.fmtFrequency;
  xs_emuConf.sampleFormat	= SIDEMU_SIGNED_PCM;
  xs_emuConf.mos8580		= xs_cfg.mos8580;
- xs_emuConf.emulateFilter	= xs_cfg.emulateFilter;
+ xs_emuConf.emulateFilter	= xs_cfg.emulateFilters;
  xs_emuConf.filterFs		= xs_cfg.filterFs;
  xs_emuConf.filterFm		= xs_cfg.filterFm;
  xs_emuConf.filterFt		= xs_cfg.filterFt;
@@ -429,14 +326,15 @@
 
 
  /* Initialize status information */
- XSDEBUG("starting thread!\n");
+ XSDEBUG("initializing and starting playing thread!\n");
 
- pthread_mutex_lock(&xs_mutex);
- xs_status.s_error = 0;
- xs_status.s_playing = sidInf.startSong;
- xs_status.s_songs = sidInf.songs;
- xs_status.s_tune = newTune;
- pthread_mutex_unlock(&xs_mutex);
+ xs_status.isError	= FALSE;
+ xs_status.isPlaying	= TRUE;
+ xs_status.allowNext	= TRUE;
+ xs_status.currSong	= sidInf.startSong;
+ xs_status.nSongs	= sidInf.songs;
+ xs_status.currTune	= newTune;
+
 
  /* Start the playing thread! */
  if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0)
@@ -455,13 +353,18 @@
 void xs_stop(void)
 {
  /* If playing, stop. */
- if (xs_status.s_playing)
+ XSDEBUG("request to stop.\n");
+
+ if (xs_status.isPlaying)
 	{
+	XSDEBUG("stopping...\n");
 	pthread_mutex_lock(&xs_mutex);
-	xs_status.s_playing = 0;
+	xs_status.isPlaying = 0;
 	pthread_mutex_unlock(&xs_mutex);
 
 	pthread_join(xs_decode_thread, NULL);
+
+	xs_plugin_ip.output->close_audio();
 	}
 }
 
@@ -482,12 +385,14 @@
 void xs_seek(int iTime)
 {
 #ifdef HAVE_SONG_POSITION
- if ((iTime > 0) && (iTime <= xs_songs))
+ pthread_mutex_lock(&xs_mutex);
+
+ if ((iTime > 0) && (iTime <= xs_status.nSongs) && xs_status.isPlaying)
 	{
-	pthread_mutex_lock(&xs_mutex);
-	xs_status.s_playing = iTime;
-	pthread_mutex_unlock(&xs_mutex);
+	xs_status.currSong = iTime;
 	}
+
+ pthread_mutex_unlock(&xs_mutex);
 #endif
 }
 
@@ -497,16 +402,19 @@
  */
 int xs_get_time(void)
 {
- if (xs_status.s_error)
+ pthread_mutex_lock(&xs_mutex);
+ if (xs_status.isError)
 	return -2;
 
- if (!xs_status.s_playing)
+ if (!xs_status.isPlaying)
 	return -1;
 
 #ifdef HAVE_SONG_POSITION
- set_song_position(xs_status.s_playing, 1, xs_status.s_songs);
+ set_song_position(xs_status.currSong, 1, xs_status.nSongs);
 #endif
 
+ pthread_mutex_unlock(&xs_mutex);
+
  return xs_plugin_ip.output->output_time();
 }
 
@@ -517,7 +425,7 @@
 void xs_get_song_info(char *songFilename, char **songTitle, int *songLength)
 {
  struct sidTuneInfo sidInf;
- sidTune *testTune = new sidTune(songFilename);
+ t_xs_tune *testTune = new sidTune(songFilename);
 
  /* Check if the tune exists and is readable */
  if (!testTune) return;
@@ -532,9 +440,108 @@
  delete testTune;
 
  /* Get titlestring */
- *songTitle = xs_filetitle_get(&sidInf, sidInf.startSong);
+ *songTitle = NULL;
 
- /* Get song length (in seconds), negative if no known length */
- *songLength = xs_songlen_get(songFilename, sidInf.startSong);
+ /* Get song length (in milliseconds), negative if no known length */
+ *songLength = xs_songlen_get(songFilename, sidInf.startSong) * 1000;
 }
 
+
+/*
+ * Create the SID-tune description string from the tune's information
+ * formatted by the user-specified format-string.
+ */
+gchar *xs_filetitle_get(gchar *pcFilename, void *pfInfo, gint iSubTune)
+{
+ gint i, j, iLength;
+ gchar *pcResult;
+ struct sidTuneInfo *finfo = (struct sidTuneInfo *) pfInfo;
+#ifdef HAVE_XMMSEXTRA
+ TitleInput *ptInput;
+#endif
+
+ // FIXME FIXME: get STIL-info
+	
+
+#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	= pcFilename;
+	ptInput->file_ext	= pcFilename;
+	ptInput->file_path	= pcFilename;
+
+	ptInput->track_name	= finfo->nameString;
+	ptInput->track_number	= iSubTune;
+	ptInput->album_name	= NULL;
+	ptInput->performer	= finfo->authorString;
+	xs_strcalloc(&ptInput->date, "");
+	ptInput->year		= 0;
+	xs_strcalloc(&ptInput->genre, "SID-tune");
+	ptInput->comment	= finfo->copyrightString;
+
+	/* Create the string */
+	pcResult = xmms_get_titlestring(xmms_get_gentitle_format(), ptInput);
+
+	/* Dispose all allocated memory */
+	g_free(ptInput->date);
+	g_free(ptInput->genre);
+	g_free(ptInput);
+	} else {
+#endif
+	/* Check the info strings */
+	if (finfo->numberOfInfoStrings != 3)
+		{
+		if (finfo->numberOfInfoStrings < 1)
+			return 0;
+
+		return g_strdup(finfo->infoString[0]);
+		}
+
+	/* Check the format-string for NULL */
+	if (xs_cfg.titleFormat == NULL)
+		return g_strdup_printf("%s - %s", finfo->nameString, finfo->authorString);
+
+	/* Construct the final result info */
+	for (j = i = 0; i < strlen(xs_cfg.titleFormat); i++)
+		{
+		if (xs_cfg.titleFormat[i] == '%')
+			{
+			switch (xs_cfg.titleFormat[++i]) {
+			case '1':
+				xs_strpcat(&pcResult, &j, finfo->authorString);
+				break;
+
+			case '2':
+				xs_strpcat(&pcResult, &j, finfo->nameString);
+				break;
+
+			case '3':
+				xs_strpcat(&pcResult, &j, finfo->copyrightString);
+				break;
+
+			case '4':
+				xs_strpcat(&pcResult, &j, finfo->formatString);
+				break;
+			} /* case */
+			} else
+			pcResult[j++] = xs_cfg.titleFormat[i];
+		}
+
+	pcResult[j] = 0;
+#ifdef HAVE_XMMSEXTRA
+	}
+#endif
+
+ return pcResult;
+}
+