Browse Source

More configurable options (opl sample rate & surround opl offset)

louyihua 8 years ago
parent
commit
8868771f8b
6 changed files with 50 additions and 31 deletions
  1. 4 6
      adplug/surroundopl.cpp
  2. 6 5
      adplug/surroundopl.h
  3. 19 7
      global.c
  4. 2 0
      global.h
  5. 10 12
      rixplay.cpp
  6. 9 1
      sdlpal.cfg.example

+ 4 - 6
adplug/surroundopl.cpp

@@ -27,10 +27,8 @@
 #include "surroundopl.h"
 //#include "debug.h"
 
-CSurroundopl::CSurroundopl(Copl *a, Copl *b, bool use16bit)
-	: use16bit(use16bit),
-		bufsize(4096),
-		a(a), b(b)
+CSurroundopl::CSurroundopl(Copl *a, Copl *b, bool use16bit, double opl_freq, double freq_offset)
+	: use16bit(use16bit), bufsize(4096), a(a), b(b), opl_freq(opl_freq), freq_offset(freq_offset)
 {
 	currType = TYPE_OPL2;
 	this->lbuf = new short[this->bufsize];
@@ -98,7 +96,7 @@ void CSurroundopl::write(int reg, int val)
 		unsigned char iBlock = (this->iFMReg[0xB0 + iChannel] >> 2) & 0x07;
 		unsigned short iFNum = ((this->iFMReg[0xB0 + iChannel] & 0x03) << 8) | this->iFMReg[0xA0 + iChannel];
 		//double dbOriginalFreq = 50000.0 * (double)iFNum * pow(2, iBlock - 20);
-		double dbOriginalFreq = 49716.0 * (double)iFNum * pow(2.0, iBlock - 20);
+		double dbOriginalFreq = opl_freq * (double)iFNum * pow(2.0, iBlock - 20);
 
 		unsigned char iNewBlock = iBlock;
 		unsigned short iNewFNum;
@@ -106,7 +104,7 @@ void CSurroundopl::write(int reg, int val)
 		// Adjust the frequency and calculate the new FNum
 		//double dbNewFNum = (dbOriginalFreq+(dbOriginalFreq/FREQ_OFFSET)) / (50000.0 * pow(2.0, iNewBlock - 20));
 		//#define calcFNum() ((dbOriginalFreq+(dbOriginalFreq/FREQ_OFFSET)) / (50000.0 * pow(2.0, iNewBlock - 20)))
-		#define calcFNum() ((dbOriginalFreq+(dbOriginalFreq/FREQ_OFFSET)) / (49716.0 * pow(2.0, iNewBlock - 20)))
+		#define calcFNum() ((dbOriginalFreq + (dbOriginalFreq / freq_offset)) / (opl_freq * pow(2.0, iNewBlock - 20)))
 		double dbNewFNum = calcFNum();
 
 		// Make sure it's in range for the OPL chip

+ 6 - 5
adplug/surroundopl.h

@@ -33,7 +33,7 @@
 // The right value should not noticeably change the pitch, but it should provide
 // a nice stereo harmonic effect.
 // This value should be well tuned to get best sound quality.
-// Currently, 384.0 is the best choice. (**sdlpal_tune**)
+// Currently, 384.0 is the best choice. (**sdlpal_tune, not used now**)
 #define FREQ_OFFSET 384.0//128.0//96.0
 
 // Number of FNums away from the upper/lower limit before switching to the next
@@ -47,18 +47,19 @@
 class CSurroundopl: public Copl
 {
 	private:
-		bool use16bit;
-		short bufsize;
-		short *lbuf, *rbuf;
 		Copl *a, *b;
+		short *lbuf, *rbuf;
+		double freq_offset, opl_freq;
 		unsigned char iFMReg[256];
 		unsigned char iTweakedFMReg[256];
 		unsigned char iCurrentTweakedBlock[9]; // Current value of the Block in the tweaked OPL chip
 		unsigned char iCurrentFNum[9];         // Current value of the FNum in the tweaked OPL chip
+		short bufsize;
+		bool use16bit;
 
 	public:
 
-		CSurroundopl(Copl *a, Copl *b, bool use16bit);
+		CSurroundopl(Copl *a, Copl *b, bool use16bit, double opl_freq, double freq_offset);
 		~CSurroundopl();
 
 		void update(short *buf, int samples);

+ 19 - 7
global.c

@@ -74,7 +74,9 @@ PAL_InitGlobals(
    DWORD     dwUseEmbeddedFonts = 1;	// Default for using embedded fonts in DOS version
    DWORD     dwUseSurroundOPL = 1;		// Default for using surround opl
    DWORD     dwUseStereo = 1;			// Default for stereo audio
-   INT       iSampleRate = 44100;		// Default for 44KHz
+   float     flSurroundOPLOffset = 384.0f;// Default for 384.0
+   INT       iSampleRate = 44100;		// Default for 44100 Hz
+   INT       iOPLSampleRate = 49716;	// Default for 49716 Hz
    MUSICTYPE eMusicType = g_fUseMidi ? MUSIC_MIDI : MUSIC_RIX;
    MUSICTYPE eCDType = PAL_HAS_SDLCD ? MUSIC_SDLCD : MUSIC_OGG;
    OPLTYPE   eOPLType = OPL_DOSBOX;
@@ -157,6 +159,14 @@ PAL_InitGlobals(
 					   sscanf(ptr, "%d", &iSampleRate);
 					   if (iSampleRate > PAL_MAX_SAMPLERATE) iSampleRate = PAL_MAX_SAMPLERATE;
 				   }
+				   else if (SDL_strcasecmp(p, "OPLSAMPLERATE") == 0)
+				   {
+					   sscanf(ptr, "%d", &iOPLSampleRate);
+				   }
+				   else if (SDL_strcasecmp(p, "SURROUNDOPLOFFSET") == 0)
+				   {
+					   sscanf(ptr, "%f", &flSurroundOPLOffset);
+				   }
 				   else if (SDL_strcasecmp(p, "CD") == 0)
 				   {
 					   char cd_type[32];
@@ -239,15 +249,22 @@ PAL_InitGlobals(
 	   }
    }
 
-   // Choose version
+   //
+   // Set configurable global options
    gpGlobals->fIsWIN95 = dwIsDOS ? FALSE : TRUE;
    gpGlobals->fUseEmbeddedFonts = dwIsDOS && dwUseEmbeddedFonts ? TRUE : FALSE;
    gpGlobals->fUseSurroundOPL = dwUseStereo && dwUseSurroundOPL ? TRUE : FALSE;
    gpGlobals->iAudioChannels = dwUseStereo ? 2 : 1;
    gpGlobals->iSampleRate = iSampleRate;
+   gpGlobals->iOPLSampleRate = iOPLSampleRate;
+   gpGlobals->dSurroundOPLOffset = flSurroundOPLOffset;
    gpGlobals->eMusicType = eMusicType;
    gpGlobals->eCDType = eCDType;
    gpGlobals->eOPLType = eOPLType;
+   gpGlobals->iCodePage = iCodePage;
+   gpGlobals->dwWordLength = dwWordLength;
+   gpGlobals->dwExtraMagicDescLines = dwExtraMagicDescLines;
+   gpGlobals->dwExtraItemDescLines = dwExtraItemDescLines;
 
    // Set decompress function
    Decompress = gpGlobals->fIsWIN95 ? YJ2_Decompress : YJ1_Decompress;
@@ -267,11 +284,6 @@ PAL_InitGlobals(
    gpGlobals->lpObjectDesc = gpGlobals->fIsWIN95 ? NULL : PAL_LoadObjectDesc(va("%s%s", PAL_PREFIX, "desc.dat"));
    gpGlobals->bCurrentSaveSlot = 1;
 
-   gpGlobals->iCodePage = iCodePage;
-   gpGlobals->dwWordLength = dwWordLength;
-   gpGlobals->dwExtraMagicDescLines = dwExtraMagicDescLines;
-   gpGlobals->dwExtraItemDescLines = dwExtraItemDescLines;
-
    return 0;
 }
 

+ 2 - 0
global.h

@@ -614,8 +614,10 @@ typedef struct tagGLOBALVARS
    DWORD            dwWordLength;
    DWORD            dwExtraMagicDescLines;
    DWORD            dwExtraItemDescLines;
+   double           dSurroundOPLOffset;
    INT              iAudioChannels;
    INT              iSampleRate;
+   INT              iOPLSampleRate;
    MUSICTYPE        eMusicType;
    MUSICTYPE        eCDType;
    OPLTYPE          eOPLType;

+ 10 - 12
rixplay.cpp

@@ -21,8 +21,6 @@
 #include "players.h"
 #include "sound.h"
 
-#define OPL_SAMPLERATE       49716
-
 #include "resampler.h"
 #include "adplug/opl.h"
 #include "adplug/demuopl.h"
@@ -363,15 +361,15 @@ RIX_Init(
 		{
 		case OPL_DOSBOX:
 			pRixPlayer->opl = new CSurroundopl(
-				new CDemuopl(OPL_SAMPLERATE, true, false),
-				new CDemuopl(OPL_SAMPLERATE, true, false),
-				true);
+				new CDemuopl(gpGlobals->iOPLSampleRate, true, false),
+				new CDemuopl(gpGlobals->iOPLSampleRate, true, false),
+				true, gpGlobals->iOPLSampleRate, gpGlobals->dSurroundOPLOffset);
 			break;
 		case OPL_MAME:
 			pRixPlayer->opl = new CSurroundopl(
-				new CEmuopl(OPL_SAMPLERATE, true, false),
-				new CEmuopl(OPL_SAMPLERATE, true, false),
-				true);
+				new CEmuopl(gpGlobals->iOPLSampleRate, true, false),
+				new CEmuopl(gpGlobals->iOPLSampleRate, true, false),
+				true, gpGlobals->iOPLSampleRate, gpGlobals->dSurroundOPLOffset);
 			break;
 		}
 	}
@@ -380,10 +378,10 @@ RIX_Init(
 		switch (gpGlobals->eOPLType)
 		{
 		case OPL_DOSBOX:
-			pRixPlayer->opl = new CDemuopl(OPL_SAMPLERATE, true, gpGlobals->iAudioChannels == 2);
+			pRixPlayer->opl = new CDemuopl(gpGlobals->iOPLSampleRate, true, gpGlobals->iAudioChannels == 2);
 			break;
 		case OPL_MAME:
-			pRixPlayer->opl = new CEmuopl(OPL_SAMPLERATE, true, gpGlobals->iAudioChannels == 2);
+			pRixPlayer->opl = new CEmuopl(gpGlobals->iOPLSampleRate, true, gpGlobals->iAudioChannels == 2);
 			break;
 		}
 	}
@@ -414,13 +412,13 @@ RIX_Init(
 		return NULL;
 	}
 
-	if (OPL_SAMPLERATE != gpGlobals->iSampleRate)
+	if (gpGlobals->iOPLSampleRate != gpGlobals->iSampleRate)
 	{
 		for (int i = 0; i < gpGlobals->iAudioChannels; i++)
 		{
 			pRixPlayer->resampler[i] = resampler_create();
 			resampler_set_quality(pRixPlayer->resampler[i], RESAMPLER_QUALITY_MAX);
-			resampler_set_rate(pRixPlayer->resampler[i], OPL_SAMPLERATE / (double)gpGlobals->iSampleRate);
+			resampler_set_rate(pRixPlayer->resampler[i], (double)gpGlobals->iOPLSampleRate / (double)gpGlobals->iSampleRate);
 		}
 	}
 

+ 9 - 1
sdlpal.cfg.example

@@ -61,5 +61,13 @@
 #UseSurroundOPL=1
 
 # SampleRate: Indicates which sample rate to use, valid values include 44100 (default),
-#             22050, and some other rates.
+#             and 22050. Other values (<=48000) are supported but not recommended.
 #SampleRate=44100
+
+# OPLSampleRate: Indicates which sample rate to use for opl emulator. Suggested value
+#                is 49716, but other values may also be used.
+#OPLSampleRate=49716
+
+# SurroundOPLOffset: Indicates the frequency offset of surround opl. The default and
+#                    recommended value is 384.0, but other values may also be used.
+#SurroundOPLOffset=384.0