diff src/xs_sidplay1.cc @ 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 e613873c3379
children dd201740a720
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