Browse Source

Rixplayer fix & dbopl optimazation & audio buffer size configurable

louyihua 8 years ago
parent
commit
28c332e43f
10 changed files with 124 additions and 58 deletions
  1. 5 2
      adplug/dbemuopl.h
  2. 3 38
      adplug/dbopl.cpp
  3. 2 8
      adplug/dbopl.h
  4. 34 5
      adplug/rix.cpp
  5. 6 2
      adplug/rix.h
  6. 54 0
      global.c
  7. 4 0
      global.h
  8. 11 2
      rixplay.cpp
  9. 4 0
      sdlpal.cfg.example
  10. 1 1
      sound.c

+ 5 - 2
adplug/dbemuopl.h

@@ -40,9 +40,12 @@ public:
 	void init();
 
 protected:
-	DBOPL::Handler handler;
-	int rate;
+	DBOPL::Chip chip;
+	int32_t* buffer;
+	int rate, maxlen;
 	bool use16bit, stereo;
+
+	static bool _inited;
 };
 
 #endif

+ 3 - 38
adplug/dbopl.cpp

@@ -1324,9 +1324,9 @@ void Chip::Setup( Bit32u rate ) {
 }
 
 static bool doneTables = false;
-void InitTables( void ) {
+bool InitTables( void ) {
 	if ( doneTables )
-		return;
+		return true;
 	doneTables = true;
 #if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG )
 	//Exponential volume table, same as the real adlib
@@ -1477,41 +1477,6 @@ void InitTables( void ) {
 		}
 	}
 #endif
+	return true;
 }
-
-Bit32u Handler::WriteAddr( Bit32u port, Bit8u val ) {
-	return chip.WriteAddr( port, val );
-
-}
-void Handler::WriteReg( Bit32u addr, Bit8u val ) {
-	chip.WriteReg( addr, val );
-}
-
-void Handler::Generate( Bit16s* buf, Bitu samples ) {
-	while (samples > 0) {
-		Bitu n = samples > 512 ? 512 : samples;
-		if (!chip.opl3Active) {
-			chip.GenerateBlock2(n, buffer);
-		}
-		else {
-			chip.GenerateBlock3(n, buffer);
-		}
-		for (Bitu i = 0; i < n; i++) {
-			if (buffer[i] > 32767)
-				buf[i] = 32767;
-			else if (buffer[i] < -32768)
-				buf[i] = -32768;
-			else
-				buf[i] = (Bit16s)buffer[i];
-		}
-		samples -= n; buf += n;
-	}
-}
-
-void Handler::Init( Bitu rate ) {
-	InitTables();
-	chip.Setup( rate );
-}
-
-
 };		//Namespace DBOPL

+ 2 - 8
adplug/dbopl.h

@@ -279,12 +279,6 @@ namespace DBOPL {
 		Chip();
 	};
 
-	struct Handler {
-		DBOPL::Chip chip;
-		Bit32s buffer[512 * 2];
-		Bit32u WriteAddr(Bit32u port, Bit8u val);
-		void WriteReg(Bit32u addr, Bit8u val);
-		void Generate(Bit16s* buf, Bitu samples);
-		void Init(Bitu rate);
-	};
+	bool InitTables(void);
+
 };		//Namespace

+ 34 - 5
adplug/rix.cpp

@@ -64,6 +64,7 @@ uint8_t CrixPlayer::for40reg[] = {0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
 					0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F};
 const uint16_t CrixPlayer::mus_time = 0x4268;
 
+
 /*** public methods *************************************/
 
 CPlayer *CrixPlayer::factory(Copl *newopl)
@@ -73,6 +74,7 @@ CPlayer *CrixPlayer::factory(Copl *newopl)
 
 CrixPlayer::CrixPlayer(Copl *newopl)
   : CPlayer(newopl), flag_mkf(0), file_buffer(0), rix_buf(0)
+	, extra_regs(NULL), extra_vals(NULL), extra_length(0)
 {
 }
 
@@ -80,6 +82,28 @@ CrixPlayer::~CrixPlayer()
 {
   if(file_buffer)
     delete [] file_buffer;
+  if (extra_regs) delete[] extra_regs;
+  if (extra_vals) delete[] extra_vals;
+}
+
+void CrixPlayer::set_extra_init(uint32_t* regs, uint8_t* datas, int n)
+{
+	extra_length = n;
+	if (extra_regs) delete[] extra_regs;
+	if (extra_vals) delete[] extra_vals;
+
+	if (n > 0)
+	{
+		extra_regs = new uint32_t[n];
+		extra_vals = new uint8_t[n];
+		if (extra_regs) memcpy(extra_regs, regs, n * sizeof(uint32_t));
+		if (extra_vals) memcpy(extra_vals, datas, n * sizeof(uint8_t));
+	}
+	else
+	{
+		extra_regs = NULL;
+		extra_vals = NULL;
+	}
 }
 
 bool CrixPlayer::load(const std::string &filename, const CFileProvider &fp)
@@ -210,11 +234,16 @@ inline void CrixPlayer::data_initial()
       ad_a0b0l_reg_(7,0x1F,0);
 
 	  // This is required for correct attack effect, by louyihua
-	  opl->write(0xa8, 87);
-	  opl->write(0xb8, 9);
-	  opl->write(0xa7, 3);
-	  opl->write(0xb7, 10);
-    }
+	  if (extra_regs && extra_vals && extra_length > 0)
+	  {
+		  for (uint32_t i = 0; i < extra_length; i++)
+			  opl->write(extra_regs[i], extra_vals[i]);
+	  }
+	  //opl->write(0xa8, 87);
+	  //opl->write(0xb8, 9);
+	  //opl->write(0xa7, 3);
+	  //opl->write(0xb7, 10);
+  }
   bd_modify = 0;
   ad_bd_reg();
   band = 0; music_on = 1;

+ 6 - 2
adplug/rix.h

@@ -22,7 +22,7 @@
 
 #include "player.h"
 
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && _MSC_VER <= 1600
 #include <windows.h>
 #define uint8_t BYTE
 #define uint16_t WORD
@@ -48,12 +48,16 @@ class CrixPlayer: public CPlayer
   std::string gettype()
     { return std::string("Softstar RIX OPL Music Format"); };
 
+  void set_extra_init(uint32_t* regs, uint8_t* datas, int n);
+
  protected:	
   typedef struct {
     uint8_t v[14];
   } ADDT;
 
   int flag_mkf;
+  uint32_t *extra_regs;
+  uint8_t *extra_vals;
   uint8_t *file_buffer;
   uint8_t *rix_buf;  /* rix files' f_buffer */
   uint16_t f_buffer[300];//9C0h-C18h
@@ -65,7 +69,7 @@ class CrixPlayer: public CPlayer
   uint16_t insbuf[28];
   uint16_t displace[11];
   ADDT reg_bufs[18];
-  uint32_t pos,length;
+  uint32_t pos,length, extra_length;
   uint8_t index;
 
   static const uint8_t adflag[18];

+ 54 - 0
global.c

@@ -79,6 +79,7 @@ PAL_InitGlobals(
    INT       iSampleRate = 44100;		// Default for 44100 Hz
    INT       iOPLSampleRate = 49716;	// Default for 49716 Hz
    INT       iResampleQuality = RESAMPLER_QUALITY_MAX;	// Default to maximum quality
+   INT       iAudioBufferSize = 1024;	// Default for 1024 samples
    MUSICTYPE eMusicType = g_fUseMidi ? MUSIC_MIDI : MUSIC_RIX;
    MUSICTYPE eCDType = PAL_HAS_SDLCD ? MUSIC_SDLCD : MUSIC_OGG;
    OPLTYPE   eOPLType = OPL_DOSBOX;
@@ -92,6 +93,10 @@ PAL_InitGlobals(
       }
    }
 
+   gpGlobals->pExtraFMRegs = NULL;
+   gpGlobals->pExtraFMVals = NULL;
+   gpGlobals->dwExtraLength = 0;
+
    if (fp = UTIL_OpenFile("sdlpal.cfg"))
    {
 	   PAL_LARGE char buf[512];
@@ -173,6 +178,54 @@ PAL_InitGlobals(
 				   {
 					   sscanf(ptr, "%f", &flSurroundOPLOffset);
 				   }
+				   else if (SDL_strcasecmp(p, "AUDIOBUFFERSIZE") == 0)
+				   {
+					   sscanf(ptr, "%d", &iAudioBufferSize);
+					   if (iAudioBufferSize > 32768)
+						   iAudioBufferSize = 32768;
+					   else if (iAudioBufferSize < 2)
+						   iAudioBufferSize = 2;
+				   }
+				   else if (SDL_strcasecmp(p, "RIXEXTRAINIT") == 0)
+				   {
+					   int n = 1;
+					   char *p;
+					   for (p = ptr; *p < *end; p++)
+					   {
+						   if (*p == ',')
+							   n++;
+					   }
+					   n &= ~0x1;
+
+					   if (n > 0)
+					   {
+						   uint32_t *regs = malloc(sizeof(uint32_t) * (n >> 1));
+						   uint8_t *vals = malloc(sizeof(uint8_t) * (n >> 1));
+						   uint32_t d, i, v = 1;
+						   if (regs && vals)
+						   {
+							   for (p = ptr, i = 0; *p < *end; p++, i++)
+							   {
+								   if (sscanf(p, "%u", &regs[i]) == 0) { v = 0; break; }
+								   while (*p < *end && *p != ',') p++; p++;
+								   if (sscanf(p, "%u", &d) == 0) { v = 0; break; }
+								   while (*p < *end && *p != ',') p++;
+								   vals[i] = (uint8_t)d;
+							   }
+							   if (v)
+							   {
+								   gpGlobals->pExtraFMRegs = regs;
+								   gpGlobals->pExtraFMVals = vals;
+								   gpGlobals->dwExtraLength = n >> 1;
+							   }
+							   else
+							   {
+								   free(regs);
+								   free(vals);
+							   }
+						   }
+					   }
+				   }
 				   else if (SDL_strcasecmp(p, "CD") == 0)
 				   {
 					   char cd_type[32];
@@ -233,6 +286,7 @@ PAL_InitGlobals(
    gpGlobals->dwWordLength = dwWordLength;
    gpGlobals->dwExtraMagicDescLines = dwExtraMagicDescLines;
    gpGlobals->dwExtraItemDescLines = dwExtraItemDescLines;
+   gpGlobals->wAudioBufferSize = (WORD)iAudioBufferSize;
 
    //
    // Set decompress function

+ 4 - 0
global.h

@@ -611,6 +611,9 @@ typedef struct tagGLOBALVARS
    DWORD            dwFrameNum;
 
    /* Configurable options */
+   uint32_t        *pExtraFMRegs;
+   uint8_t         *pExtraFMVals;
+   uint32_t         dwExtraLength;
    CODEPAGE         iCodePage;
    DWORD            dwWordLength;
    DWORD            dwExtraMagicDescLines;
@@ -623,6 +626,7 @@ typedef struct tagGLOBALVARS
    MUSICTYPE        eMusicType;
    MUSICTYPE        eCDType;
    OPLTYPE          eOPLType;
+   WORD             wAudioBufferSize;
    BOOL             fIsWIN95;
    BOOL             fUseEmbeddedFonts;
    BOOL             fUseSurroundOPL;

+ 11 - 2
rixplay.cpp

@@ -120,6 +120,7 @@ RIX_FillBuffer(
 			if (pRixPlayer->iNextMusic > 0)
 			{
 				pRixPlayer->iCurrentMusic = pRixPlayer->iNextMusic;
+				pRixPlayer->iNextMusic = -1;
 				pRixPlayer->fLoop = pRixPlayer->fNextLoop;
 				pRixPlayer->FadeType = RIXPLAYER::FADE_IN;
 				pRixPlayer->dwStartFadeTime = t;
@@ -168,7 +169,10 @@ RIX_FillBuffer(
 					// Not loop, simply terminate the music
 					//
 					pRixPlayer->iCurrentMusic = -1;
-					pRixPlayer->FadeType = RIXPLAYER::NONE;
+					if (pRixPlayer->FadeType != RIXPLAYER::FADE_OUT && pRixPlayer->iNextMusic == -1)
+					{
+						pRixPlayer->FadeType = RIXPLAYER::NONE;
+					}
 					return;
 				}
 				pRixPlayer->rix->rewind(pRixPlayer->iCurrentMusic);
@@ -432,11 +436,16 @@ RIX_Init(
 		}
 	}
 
+	if (gpGlobals->pExtraFMRegs && gpGlobals->pExtraFMVals)
+	{
+		pRixPlayer->rix->set_extra_init(gpGlobals->pExtraFMRegs, gpGlobals->pExtraFMVals, gpGlobals->dwExtraLength);
+	}
+
 	//
 	// Success.
 	//
 	pRixPlayer->FadeType = RIXPLAYER::NONE;
-	pRixPlayer->iCurrentMusic = -1;
+	pRixPlayer->iCurrentMusic = pRixPlayer->iNextMusic = -1;
 	pRixPlayer->pos = NULL;
 	pRixPlayer->fLoop = FALSE;
 	pRixPlayer->fNextLoop = FALSE;

+ 4 - 0
sdlpal.cfg.example

@@ -75,3 +75,7 @@
 # ResampleQuality: Indicates the resample quality, valid values from 0 to 4 (default).
 #                  Larger value indicates higher quality and higher hardware requirement.
 #ResampleQuality=4
+
+# AudioBufferSize: Indicates the size of audio buffer in samples. Valid values are in 
+#                  range 2 - 32768, but should be power of 2. Default value is 1024.
+#AudioBufferSize=1024

+ 1 - 1
sound.c

@@ -608,7 +608,7 @@ SOUND_OpenAudio(
    gSndPlayer.spec.freq = gpGlobals->iSampleRate;
    gSndPlayer.spec.format = AUDIO_S16;
    gSndPlayer.spec.channels = gpGlobals->iAudioChannels;
-   gSndPlayer.spec.samples = 1024;
+   gSndPlayer.spec.samples = gpGlobals->wAudioBufferSize;
    gSndPlayer.spec.callback = SOUND_FillAudio;
 
    if (SDL_OpenAudio(&gSndPlayer.spec, &spec) < 0)