changeset 270:583f5651abff

Cleanups, moved engine configuration to initialization function. Audio settings "feedback" and oversampling support implemented.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 23 Dec 2004 17:02:05 +0000
parents f949b83c3f52
children eebb38debe35
files src/xs_sidplay1.cc src/xs_sidplay2.cc
diffstat 2 files changed, 252 insertions(+), 202 deletions(-) [+]
line wrap: on
line diff
--- a/src/xs_sidplay1.cc	Thu Dec 23 13:29:00 2004 +0000
+++ b/src/xs_sidplay1.cc	Thu Dec 23 17:02:05 2004 +0000
@@ -33,6 +33,8 @@
 #include <sidplay/myendian.h>
 #include <sidplay/fformat.h>
 
+/* Maximum audio frequency supported by libSIDPlay v1 */
+#define SIDPLAY1_MAX_FREQ	(48000)
 
 typedef struct {
 	emuEngine	*currEng;
@@ -41,14 +43,11 @@
 } t_xs_sidplay1;
 
 
-/*
- * We need to 'export' all this pseudo-C++ crap
- */
+/* We need to 'export' all this pseudo-C++ crap */
 extern "C" {
 
 
-/*
- * Check if we can play the given file
+/* Check if we can play the given file
  */
 gboolean xs_sidplay1_isourfile(gchar *pcFilename)
 {
@@ -66,11 +65,11 @@
 }
 
 
-/*
- * Initialize SIDPlay1
+/* Initialize SIDPlay1
  */
 gboolean xs_sidplay1_init(t_xs_status *myStatus)
 {
+ gint tmpFreq;
  t_xs_sidplay1 *myEngine;
  assert(myStatus);
 
@@ -97,87 +96,11 @@
 	}
 
  myStatus->sidEngine = myEngine;
- return TRUE;
-}
-
-
-/*
- * Close SIDPlay1
- */
-void xs_sidplay1_close(t_xs_status *myStatus)
-{
- t_xs_sidplay1 *myEngine;
- assert(myStatus);
-
- /* Free internals */
- myEngine = (t_xs_sidplay1 *) myStatus->sidEngine;
- if (myEngine->currEng)
-	{
-	delete myEngine->currEng;
-	myEngine->currEng = NULL;	
-	}
-
- g_free(myEngine);
- myStatus->sidEngine = NULL;
-}
-
-
-gboolean xs_sidplay1_initsong(t_xs_status *myStatus)
-{
- t_xs_sidplay1 *myEngine = (t_xs_sidplay1 *) myStatus->sidEngine;
-
- if (!myEngine) return FALSE;
-
- if (!myEngine->currTune)
-	{
-	XSERR("Tune was NULL\n");
-	return FALSE;
-	}
-
- if (!myEngine->currTune->getStatus())
-	{
-	XSERR("Tune status check failed\n");
-	return FALSE;
-	}
-
- return sidEmuInitializeSong(
-	*myEngine->currEng,
-	*myEngine->currTune,
-	myStatus->currSong);
-}
-
-
-guint xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, guint audioBufSize)
-{
- t_xs_sidplay1 *myEngine = (t_xs_sidplay1 *) myStatus->sidEngine;
-
- if (!myEngine) return 0;
-
- sidEmuFillBuffer(
-	*myEngine->currEng,
-	*myEngine->currTune,
-	audioBuffer,
-	audioBufSize);
-
- return audioBufSize;
-}
-
-
-gboolean xs_sidplay1_loadsid(t_xs_status *myStatus, gchar *pcFilename)
-{
- t_xs_sidplay1 *myEngine = (t_xs_sidplay1 *) myStatus->sidEngine;
- sidTune *newTune;
- assert(myStatus);
-
- /* Try to get the tune */
- if (!pcFilename) return FALSE;
- newTune = new sidTune(pcFilename);
- if (!newTune) return FALSE;
 
  /* Get current configuration */
  myEngine->currEng->getConfig(myEngine->currConfig);
 
- /* Configure channels and stuff */
+ /* Configure channel parameters */
  switch (myStatus->audioChannels) {
 
 	case XS_CHN_AUTOPAN:
@@ -197,16 +120,13 @@
 		myEngine->currConfig.channels = SIDEMU_MONO;
 		myEngine->currConfig.autoPanning = SIDEMU_NONE;
 		myEngine->currConfig.volumeControl = SIDEMU_NONE;
+		myStatus->audioChannels = XS_CHN_MONO;
 		break;
  }
 
 
  /* Memory mode settings */
  switch (xs_cfg.memoryMode) {
-	case XS_MPU_BANK_SWITCHING:
-		myEngine->currConfig.memoryMode = MPU_BANK_SWITCHING;
-		break;
-
 	case XS_MPU_TRANSPARENT_ROM:
 		myEngine->currConfig.memoryMode = MPU_TRANSPARENT_ROM;
 		break;
@@ -215,8 +135,10 @@
 		myEngine->currConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT;
 		break;
 
+	case XS_MPU_BANK_SWITCHING:
 	default:
 		myEngine->currConfig.memoryMode = MPU_BANK_SWITCHING;
+		xs_cfg.memoryMode = XS_MPU_BANK_SWITCHING;
 		break;
  }
 
@@ -230,6 +152,7 @@
 	case XS_CLOCK_PAL:
 	default:
 		myEngine->currConfig.clockSpeed = SIDTUNE_CLOCK_PAL;
+		xs_cfg.clockSpeed = XS_CLOCK_PAL;
 		break;
  }
 
@@ -241,13 +164,31 @@
  myEngine->currConfig.filterFm		= xs_cfg.filterFm;
  myEngine->currConfig.filterFt		= xs_cfg.filterFt;
 
- myEngine->currConfig.bitsPerSample	= myStatus->audioBitsPerSample;
- myEngine->currConfig.frequency		= myStatus->audioFrequency;
+
+ /* Audio parameters sanity checking and setup */
+ myEngine->currConfig.bitsPerSample = myStatus->audioBitsPerSample;
+ tmpFreq = myStatus->audioFrequency;
+
+ if (myStatus->oversampleEnable)
+	{
+	if ((tmpFreq * myStatus->oversampleFactor) > SIDPLAY1_MAX_FREQ)
+		{
+		myStatus->oversampleEnable = FALSE;
+		} else {
+		tmpFreq = (tmpFreq * myStatus->oversampleFactor);
+		}
+	} else {
+	if (tmpFreq > SIDPLAY1_MAX_FREQ)
+		tmpFreq = SIDPLAY1_MAX_FREQ;
+	}
+
+ myEngine->currConfig.frequency = tmpFreq;
 
  switch (myStatus->audioBitsPerSample) {
  case XS_RES_8BIT:
 	switch (myStatus->audioFormat) {
 	case FMT_S8:
+		myStatus->audioFormat			= FMT_S8;
 		myEngine->currConfig.sampleFormat	= SIDEMU_SIGNED_PCM;
 		break;
 
@@ -260,6 +201,7 @@
 	break;
 
  case XS_RES_16BIT:
+ default:
 	switch (myStatus->audioFormat) {
 	case FMT_U16_NE:
 	case FMT_U16_LE:
@@ -286,15 +228,103 @@
 	return FALSE;
 	}
 
- /* Initialize status information */
+ return TRUE;
+}
+
+
+/* Close SIDPlay1 engine
+ */
+void xs_sidplay1_close(t_xs_status *myStatus)
+{
+ t_xs_sidplay1 *myEngine;
+ assert(myStatus);
+
+ myEngine = (t_xs_sidplay1 *) myStatus->sidEngine;
+
+ /* Free internals */
+ if (myEngine->currEng)
+	{
+	delete myEngine->currEng;
+	myEngine->currEng = NULL;	
+	}
+
+ g_free(myEngine);
+ myStatus->sidEngine = NULL;
+}
+
+
+/* Initialize current song and sub-tune
+ */
+gboolean xs_sidplay1_initsong(t_xs_status *myStatus)
+{
+ t_xs_sidplay1 *myEngine;
+ assert(myStatus);
+
+ myEngine = (t_xs_sidplay1 *) myStatus->sidEngine;
+ if (!myEngine) return FALSE;
+
+ if (!myEngine->currTune)
+	{
+	XSERR("Tune was NULL\n");
+	return FALSE;
+	}
+
+ if (!myEngine->currTune->getStatus())
+	{
+	XSERR("Tune status check failed\n");
+	return FALSE;
+	}
+
+ return sidEmuInitializeSong(
+	*myEngine->currEng,
+	*myEngine->currTune,
+	myStatus->currSong);
+}
+
+
+/* Emulate and render audio data to given buffer
+ */
+guint xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, guint audioBufSize)
+{
+ t_xs_sidplay1 *myEngine;
+ assert(myStatus);
+
+ myEngine = (t_xs_sidplay1 *) myStatus->sidEngine;
+ if (!myEngine) return 0;
+
+ sidEmuFillBuffer(
+	*myEngine->currEng,
+	*myEngine->currTune,
+	audioBuffer,
+	audioBufSize);
+
+ return audioBufSize;
+}
+
+
+/* Load a given SID-tune file
+ */
+gboolean xs_sidplay1_loadsid(t_xs_status *myStatus, gchar *pcFilename)
+{
+ t_xs_sidplay1 *myEngine;
+ sidTune *newTune;
+ assert(myStatus);
+
+ myEngine = (t_xs_sidplay1 *) myStatus->sidEngine;
+
+ /* Try to get the tune */
+ if (!pcFilename) return FALSE;
+
+ newTune = new sidTune(pcFilename);
+ if (!newTune) return FALSE;
+
  myEngine->currTune = newTune;
 
  return TRUE;
 }
 
 
-/*
- * Delete INTERNAL information
+/* Delete INTERNAL information
  */
 void xs_sidplay1_deletesid(t_xs_status *myStatus)
 {
@@ -312,8 +342,7 @@
 }
 
 
-/*
- * Return song information
+/* Return song information
  */
 #define TFUNCTION	xs_sidplay1_getsidinfo
 #define TTUNEINFO	sidTuneInfo
--- a/src/xs_sidplay2.cc	Thu Dec 23 13:29:00 2004 +0000
+++ b/src/xs_sidplay2.cc	Thu Dec 23 17:02:05 2004 +0000
@@ -47,14 +47,11 @@
 } t_xs_sidplay2;
 
 
-/*
- * We need to 'export' all this pseudo-C++ crap
- */
+/* We need to 'export' all this pseudo-C++ crap */
 extern "C" {
 
 
-/*
- * Check if we can play the given file
+/* Check if we can play the given file
  */
 gboolean xs_sidplay2_isourfile(gchar *pcFilename)
 {
@@ -72,11 +69,12 @@
 }
 
 
-/*
- * Initialize SIDPlay2
+
+/* Initialize SIDPlay2
  */
 gboolean xs_sidplay2_init(t_xs_status *myStatus)
 {
+ gint tmpFreq;
  t_xs_sidplay2 *myEngine;
  assert(myStatus);
 
@@ -98,7 +96,7 @@
 #ifdef HAVE_RESID_BUILDER
  if (xs_cfg.sid2Builder == XS_BLD_RESID)
 	{
-	ReSIDBuilder *tmpb = new ReSIDBuilder("SIDPlay2 suxx and is made by a fag - ReSID builder");
+	ReSIDBuilder *tmpb = new ReSIDBuilder("SIDPlay2 suxx - ReSID builder");
 
 	/* Create the builder -- WHAT IS THIS MEANT FOR??? */
 	tmpb->create(myEngine->currEng->info().maxsids);
@@ -119,98 +117,8 @@
 	}
 
  XSDEBUG("%s\n", myEngine->currBuilder->credits());
-
-
- /* Create the sidtune */
- myEngine->currTune = new SidTune(0);
- if (!myEngine->currTune)
-	{
-	XSERR("Could not initialize SIDTune object.\n");
-	return FALSE;
-	}
- 
- /* OK */
  myStatus->sidEngine = myEngine;
- return TRUE;
-}
-
-
-/*
- * Close SIDPlay2
- */
-void xs_sidplay2_close(t_xs_status *myStatus)
-{
- t_xs_sidplay2 *myEngine;
- assert(myStatus);
-
- /* Free internals */
- myEngine = (t_xs_sidplay2 *) myStatus->sidEngine;
-
- if (myEngine->currBuilder)
-	{
-	delete myEngine->currBuilder;
-	myEngine->currBuilder = NULL;
-	}
-
- if (myEngine->currEng)
-	{
-	delete myEngine->currEng;
-	myEngine->currEng = NULL;
-	}
-
- if (myEngine->currTune)
-	{
-	delete myEngine->currTune;
-	myEngine->currTune = NULL;
-	}
 
- xs_sidplay2_deletesid(myStatus);
-
- g_free(myEngine);
- myStatus->sidEngine = NULL;
-}
-
-
-gboolean xs_sidplay2_initsong(t_xs_status *myStatus)
-{
- t_xs_sidplay2 *myEngine = (t_xs_sidplay2 *) myStatus->sidEngine;
-
- if (!myEngine) return FALSE;
-
- if (!myEngine->currTune->selectSong(myStatus->currSong))
-	{
-	XSERR("ENGINE selectSong() failed\n");
-	return FALSE;
-	}
-
- if (myEngine->currEng->load(myEngine->currTune) < 0)
-	{
-	XSERR("ENGINE load() failed\n");
-	return FALSE;
-	}
-
- return TRUE;
-}
-
-
-guint xs_sidplay2_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, guint audioBufSize)
-{
- t_xs_sidplay2 *myEngine = (t_xs_sidplay2 *) myStatus->sidEngine;
-
- if (!myEngine) return 0;
-
- return myEngine->currEng->play(audioBuffer, audioBufSize);
-}
-
-
-gboolean xs_sidplay2_loadsid(t_xs_status *myStatus, gchar *pcFilename)
-{
- t_xs_sidplay2 *myEngine = (t_xs_sidplay2 *) myStatus->sidEngine;
- assert(myStatus);
-
- /* Try to get the tune */
- if (!pcFilename) return FALSE;
- if (!myEngine->currTune->load(pcFilename)) return FALSE;
 
  /* Get current configuration */
  myEngine->currConfig = myEngine->currEng->config();
@@ -229,6 +137,7 @@
 	case XS_CHN_MONO:
 	default:
 		myEngine->currConfig.playback = sid2_mono;
+		myStatus->audioChannels = XS_CHN_MONO;
 		break;
  }
 
@@ -250,6 +159,7 @@
 	case XS_MPU_REAL:
 	default:
 		myEngine->currConfig.environment = sid2_envR;
+		xs_cfg.memoryMode = XS_MPU_REAL;
 		break;
  }
 
@@ -263,6 +173,7 @@
 	case XS_CLOCK_PAL:
 	default:
 		myEngine->currConfig.clockSpeed = myEngine->currConfig.clockDefault = SID2_CLOCK_PAL;
+		xs_cfg.clockSpeed = XS_CLOCK_PAL;
 		break;
  }
 
@@ -271,10 +182,23 @@
  myEngine->currConfig.sidEmulation	= myEngine->currBuilder;
  myEngine->currConfig.clockForced	= xs_cfg.forceSpeed;
  myEngine->currConfig.optimisation	= (xs_cfg.sid2OptLevel) ? 1 : 0;
- myEngine->currConfig.sidDefault	= myEngine->currConfig.sidModel = (xs_cfg.mos8580) ? SID2_MOS8580 : SID2_MOS6581;
+ if (xs_cfg.mos8580)
+	myEngine->currConfig.sidDefault = SID2_MOS8580;
+	else
+        myEngine->currConfig.sidDefault = SID2_MOS6581;
+
+ myEngine->currConfig.sidModel		= myEngine->currConfig.sidDefault;
  myEngine->currConfig.sidSamples	= TRUE;	// FIXME FIX ME, make configurable!
- myEngine->currConfig.precision		= myStatus->audioBitsPerSample;
- myEngine->currConfig.frequency		= myStatus->audioFrequency; 
+
+
+ /* Audio parameters sanity checking and setup */
+ myEngine->currConfig.precision = myStatus->audioBitsPerSample;
+ tmpFreq = myStatus->audioFrequency;
+
+ if (myStatus->oversampleEnable)
+	tmpFreq = (tmpFreq * myStatus->oversampleFactor);
+
+ myEngine->currConfig.frequency = tmpFreq;
 
  switch (myStatus->audioBitsPerSample) {
  case XS_RES_8BIT:
@@ -283,6 +207,7 @@
 	break;
 
  case XS_RES_16BIT:
+ default:
 	switch (myStatus->audioFormat) {
 	case FMT_U16_LE:
 		myEngine->currConfig.sampleFormat	= SID2_LITTLE_UNSIGNED;
@@ -293,7 +218,6 @@
 		break;
 
 	case FMT_U16_NE:
-		myStatus->audioFormat			= FMT_U16_NE;
 #ifdef WORDS_BIGENDIAN
 		myEngine->currConfig.sampleFormat	= SID2_BIG_UNSIGNED;
 #else
@@ -322,7 +246,6 @@
 	break;
  }
 
-
  /* Now set the emulator configuration */
  if (myEngine->currEng->config(myEngine->currConfig) < 0)
 	{
@@ -330,12 +253,111 @@
 	return FALSE;
 	}
 
+ /* Create the sidtune */
+ myEngine->currTune = new SidTune(0);
+ if (!myEngine->currTune)
+	{
+	XSERR("Could not initialize SIDTune object.\n");
+	return FALSE;
+	}
+ 
  return TRUE;
 }
 
 
-/*
- * Delete tune
+/* Close SIDPlay2 engine
+ */
+void xs_sidplay2_close(t_xs_status *myStatus)
+{
+ t_xs_sidplay2 *myEngine;
+ assert(myStatus);
+
+ myEngine = (t_xs_sidplay2 *) myStatus->sidEngine;
+
+ /* Free internals */
+ if (myEngine->currBuilder)
+	{
+	delete myEngine->currBuilder;
+	myEngine->currBuilder = NULL;
+	}
+
+ if (myEngine->currEng)
+	{
+	delete myEngine->currEng;
+	myEngine->currEng = NULL;
+	}
+
+ if (myEngine->currTune)
+	{
+	delete myEngine->currTune;
+	myEngine->currTune = NULL;
+	}
+
+ xs_sidplay2_deletesid(myStatus);
+
+ g_free(myEngine);
+ myStatus->sidEngine = NULL;
+}
+
+
+/* Initialize current song and sub-tune
+ */
+gboolean xs_sidplay2_initsong(t_xs_status *myStatus)
+{
+ t_xs_sidplay2 *myEngine;
+ assert(myStatus);
+
+ myEngine = (t_xs_sidplay2 *) myStatus->sidEngine;
+ if (!myEngine) return FALSE;
+
+ if (!myEngine->currTune->selectSong(myStatus->currSong))
+	{
+	XSERR("currTune->selectSong() failed\n");
+	return FALSE;
+	}
+
+ if (myEngine->currEng->load(myEngine->currTune) < 0)
+	{
+	XSERR("currEng->load() failed\n");
+	return FALSE;
+	}
+
+ return TRUE;
+}
+
+
+/* Emulate and render audio data to given buffer
+ */
+guint xs_sidplay2_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, guint audioBufSize)
+{
+ t_xs_sidplay2 *myEngine;
+ assert(myStatus);
+
+ myEngine = (t_xs_sidplay2 *) myStatus->sidEngine;
+ if (!myEngine) return 0;
+
+ return myEngine->currEng->play(audioBuffer, audioBufSize);
+}
+
+
+/* Load a given SID-tune file
+ */
+gboolean xs_sidplay2_loadsid(t_xs_status *myStatus, gchar *pcFilename)
+{
+ t_xs_sidplay2 *myEngine;
+ assert(myStatus);
+
+ myEngine = (t_xs_sidplay2 *) myStatus->sidEngine;
+
+ /* Try to get the tune */
+ if (!pcFilename) return FALSE;
+ if (!myEngine->currTune->load(pcFilename)) return FALSE;
+
+ return TRUE;
+}
+
+
+/* Delete INTERNAL information
  */
 void xs_sidplay2_deletesid(t_xs_status *myStatus)
 {
@@ -345,8 +367,7 @@
 }
 
 
-/*
- * Return song information
+/* Return song information
  */
 #define TFUNCTION	xs_sidplay2_getsidinfo
 #define TTUNEINFO	SidTuneInfo