summaryrefslogtreecommitdiffstats
path: root/apps/plugins/sdl
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2018-01-05 17:25:03 -0500
committerFranklin Wei <git@fwei.tk>2018-01-15 19:45:28 -0500
commitcf07bb328deb71cf2dc602f435b5340b0b55a2e5 (patch)
treee90dc67756cedabb0e857ad2f44309791a92e38b /apps/plugins/sdl
parent69ff35ac497abddd0559412f82682d717888eb03 (diff)
downloadrockbox-cf07bb328deb71cf2dc602f435b5340b0b55a2e5.tar.gz
rockbox-cf07bb328deb71cf2dc602f435b5340b0b55a2e5.tar.bz2
rockbox-cf07bb328deb71cf2dc602f435b5340b0b55a2e5.zip
duke3d: further optimize audio mixing
Rather than holding intermediate results as fixed-point, this converts them directly to normal integers (in the range of the PCM sample) while mixing, instead of waiting till the end to perform a separate shifting step. Also, this precalculates some constants in the reverb code. Change-Id: Ie04e444d145bc28ce67eef9ae0ead6d328acf28a
Diffstat (limited to 'apps/plugins/sdl')
-rw-r--r--apps/plugins/sdl/progs/duke3d/Engine/src/display.c10
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.c6
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.c26
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.c74
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/config.c1
5 files changed, 65 insertions, 52 deletions
diff --git a/apps/plugins/sdl/progs/duke3d/Engine/src/display.c b/apps/plugins/sdl/progs/duke3d/Engine/src/display.c
index 3883803bce..501ffa411c 100644
--- a/apps/plugins/sdl/progs/duke3d/Engine/src/display.c
+++ b/apps/plugins/sdl/progs/duke3d/Engine/src/display.c
@@ -1368,9 +1368,13 @@ int VBE_setPalette(uint8_t *palettebuffer)
memcpy(lastPalette, palettebuffer, 768);
for (i = 0; i < 256; i++){
- sdlp->b = (Uint8) ((((float) *p++) / 63.0) * 255.0);
- sdlp->g = (Uint8) ((((float) *p++) / 63.0) * 255.0);
- sdlp->r = (Uint8) ((((float) *p++) / 63.0) * 255.0);
+ /* doesn't map perfectly */
+ sdlp->b = (Uint8) (*p << 2) | (*p >> 4);
+ p++;
+ sdlp->g = (Uint8) (*p << 2) | (*p >> 4);
+ p++;
+ sdlp->r = (Uint8) (*p << 2) | (*p >> 4);
+ p++;
sdlp->unused = *p++; /* This byte is unused in BUILD, too. */
sdlp++;
}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.c
index 7567d7314b..2c03a862f8 100644
--- a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.c
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.c
@@ -122,7 +122,7 @@ static int MV_FooMemory;
static int MV_BufferDescriptor;
static int MV_BufferEmpty[ NumberOfBuffers ];
char *MV_MixBuffer[ NumberOfBuffers + 1 ];
-/* fixed-point */
+/* raw samples in range [-2^15, 2^15-1], interleaved stereo */
long *MV_FooBuffer = NULL;
static VoiceNode *MV_Voices = NULL;
@@ -465,8 +465,8 @@ void MV_ServiceVoc
}
{
- ClearBuffer_DW( MV_FooBuffer, 0, sizeof(long) / 4 * MV_BufferSize / MV_SampleSize * MV_Channels);
- MV_BufferEmpty[ MV_MixPage ] = TRUE;
+ ClearBuffer_DW( MV_FooBuffer, 0, (sizeof(long) * MV_BufferSize / MV_SampleSize * MV_Channels) / 4);
+ MV_BufferEmpty[ MV_MixPage ] = TRUE;
}
// Play any waiting voices
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.c
index 61485a1ca0..e44e432434 100644
--- a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.c
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.c
@@ -65,7 +65,7 @@ int MV_cubic(int position)
}
*/
-static int MV_cubic16(const short *src, int position, int rate)
+static inline int MV_cubic16(const short *src, int position, int rate)
{
int temp, hpos = position >> 16;
@@ -88,7 +88,7 @@ static int MV_cubic16(const short *src, int position, int rate)
return do_cubic ? MV_cubic(position) : gval(3);
}
-static int MV_cubic8to16(const unsigned char *src, int position, int rate)
+static inline int MV_cubic8to16(const unsigned char *src, int position, int rate)
{
int temp, hpos = position >> 16;
@@ -394,15 +394,17 @@ void MV_MixFPMono8( uint32_t position,
for (i = 0; i < length; i++) {
int s = MV_cubic8to16(src, position, rate) << FRACBITS;
- long out;
+ int out;
+
+ /* output is long in range [0, 2^16) */
+ out = (s * MV_LeftScale) >> (FRACBITS * 2);
- out = (s * MV_LeftScale) >> FRACBITS;
*dest += out;
position += rate;
dest += MV_Channels;
}
-
+
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
@@ -423,8 +425,8 @@ void MV_MixFPStereo8( uint32_t position,
int s = MV_cubic8to16(src, position, rate) << FRACBITS;
long left, right;
- left = (s * MV_LeftScale) >> FRACBITS;
- right = (s * MV_RightScale) >> FRACBITS;
+ left = (s * MV_LeftScale) >> (FRACBITS * 2);
+ right = (s * MV_RightScale) >> (FRACBITS * 2);
dest[0] += left;
dest[1] += right;
@@ -452,9 +454,9 @@ void MV_MixFPMono16( uint32_t position,
for (i = 0; i < length; i++) {
int s = MV_cubic16(src, position, rate) << FRACBITS;
- long out;
+ int out;
- out = (s * MV_LeftScale) >> FRACBITS;
+ out = (s * MV_LeftScale) >> (FRACBITS * 2);
*dest += out;
position += rate;
@@ -480,10 +482,10 @@ void MV_MixFPStereo16( uint32_t position,
for (i = 0; i < length; i++) {
int s = MV_cubic16(src, position, rate) << FRACBITS;
- long left, right;
+ int left, right;
- left = (s * MV_LeftScale) >> FRACBITS;
- right = (s * MV_RightScale) >> FRACBITS;
+ left = (s * MV_LeftScale) >> (FRACBITS * 2);
+ right = (s * MV_RightScale) >> (FRACBITS * 2);
dest[0] += left;
dest[1] += right;
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.c
index 7d48d3271e..4c82f6eec0 100644
--- a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.c
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.c
@@ -18,24 +18,40 @@ static int FB_SRC_A, FB_SRC_B, IIR_DEST_A0, IIR_DEST_A1, ACC_SRC_A0, ACC_SRC_A1,
ACC_SRC_C1, ACC_SRC_D0, ACC_SRC_D1, IIR_SRC_B1, IIR_SRC_B0, MIX_DEST_A0,
MIX_DEST_A1, MIX_DEST_B0, MIX_DEST_B1;
-static long IIR_ALPHA, ACC_COEF_A, ACC_COEF_B, ACC_COEF_C, ACC_COEF_D, IIR_COEF, FB_ALPHA, FB_X,
- IN_COEF_L, IN_COEF_R;
+//static long IIR_ALPHA, ACC_COEF_A, ACC_COEF_B, ACC_COEF_C, ACC_COEF_D, IIR_COEF, FB_ALPHA, FB_X,
+// IN_COEF_L, IN_COEF_R;
-static long iRVBLeft, iRVBRight;
-static int cnv_offset(int src)
+#define fp_scale ((double)(1<<FRACBITS))
+//static const double fp_scale = (double) (1 << FRACBITS);
+
+static const long IIR_ALPHA = 0.8701171875 * fp_scale,
+ ACC_COEF_A = 0.622314453125 * fp_scale,
+ ACC_COEF_B = -0.5244140625 * fp_scale,
+ ACC_COEF_C = 0.53955078125 * fp_scale,
+ ACC_COEF_D = -0.50830078125 * fp_scale,
+ IIR_COEF = -0.69921875 * fp_scale,
+ FB_ALPHA = 0.67578125 * fp_scale,
+ FB_X = 0.646484375 * fp_scale,
+ IN_COEF_L = -2. * fp_scale,
+ IN_COEF_R = -2. * fp_scale;
+
+static long iRVBLeft, iRVBRight;
+
+static inline int cnv_offset(int src)
{
- int64_t temp = ((int64_t)src * (int64_t)MV_MixRate) / 22050;
- return (int)temp;
+ /* no need for 64-bit ints here */
+ /* src can be no greater than 2^16-1, which allows sample rates up
+ * to 65KHz */
+ int temp = (src * MV_MixRate) / 22050;
+ return temp;
}
// static char err[256];
// extern __stdcall OutputDebugStringA(char *);
-static const double fp_scale = (double) (1 << FRACBITS);
-
-static void check_buffer()
+static inline void check_buffer()
{
int new_delay = cnv_offset(MV_ReverbDelay);
@@ -64,16 +80,6 @@ static void check_buffer()
MIX_DEST_A1 = cnv_offset(0x238);
MIX_DEST_B0 = cnv_offset(0x154);
MIX_DEST_B1 = cnv_offset(0xAA);
- IIR_ALPHA = 0.8701171875 * fp_scale;
- ACC_COEF_A = 0.622314453125 * fp_scale;
- ACC_COEF_B = -0.5244140625 * fp_scale;
- ACC_COEF_C = 0.53955078125 * fp_scale;
- ACC_COEF_D = -0.50830078125 * fp_scale;
- IIR_COEF = -0.69921875 * fp_scale;
- FB_ALPHA = 0.67578125 * fp_scale;
- FB_X = 0.646484375 * fp_scale;
- IN_COEF_L = -2. * fp_scale;
- IN_COEF_R = -2. * fp_scale;
if (reverbBuffer) reverbBuffer = (long*) realloc(reverbBuffer, new_delay * sizeof(long));
else reverbBuffer = (long*) malloc(new_delay * sizeof(long));
memset(reverbBuffer, 0, new_delay * sizeof(long));
@@ -83,7 +89,7 @@ static void check_buffer()
}
-long g_buffer(int iOff, long *ptr) // get_buffer content helper: takes care about wraps
+static inline long g_buffer(int iOff, long *ptr) // get_buffer content helper: takes care about wraps
{
int correctDelay = delay;
if(!correctDelay)
@@ -104,7 +110,7 @@ long g_buffer(int iOff, long *ptr) // get_buffer conten
return (long)*(ptr+iOff);
}
-void s_buffer(int iOff,long iVal, long *ptr) // set_buffer content helper: takes care about wraps and clipping
+static inline void s_buffer(int iOff,long iVal, long *ptr) // set_buffer content helper: takes care about wraps and clipping
{
int correctDelay = delay;
if(!correctDelay)
@@ -125,7 +131,7 @@ void s_buffer(int iOff,long iVal, long *ptr) // set_buffer conten
*(ptr+iOff)=iVal;
}
-void s_buffer1(int iOff,long iVal, long *ptr) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
+static inline void s_buffer1(int iOff,long iVal, long *ptr) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
{
int correctDelay = delay;
if(!correctDelay)
@@ -146,7 +152,7 @@ void s_buffer1(int iOff,long iVal, long *ptr) // set_buffer (+1 s
*(ptr+iOff)=iVal;
}
-long MixREVERBLeft(long INPUT_SAMPLE_L, long INPUT_SAMPLE_R, long *ptr)
+static inline long MixREVERBLeft(long INPUT_SAMPLE_L, long INPUT_SAMPLE_R, long *ptr)
{
long ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
@@ -186,8 +192,8 @@ long MixREVERBLeft(long INPUT_SAMPLE_L, long INPUT_SAMPLE_R, long *ptr)
s_buffer(MIX_DEST_B0, fp_mul(FB_ALPHA , ACC0, FRACBITS) - fp_mul(FB_A0, (FB_ALPHA - one), FRACBITS) - fp_mul(FB_B0, FB_X, FRACBITS), ptr);
s_buffer(MIX_DEST_B1, fp_mul(FB_ALPHA , ACC1, FRACBITS) - fp_mul(FB_A1, (FB_ALPHA - one), FRACBITS) - fp_mul(FB_B1, FB_X, FRACBITS), ptr);
- iRVBLeft = fp_div((g_buffer(MIX_DEST_A0, ptr)+g_buffer(MIX_DEST_B0, ptr)), 3 << FRACBITS, FRACBITS);
- iRVBRight = fp_div((g_buffer(MIX_DEST_A1, ptr)+g_buffer(MIX_DEST_B1, ptr)), 3 << FRACBITS, FRACBITS);
+ iRVBLeft = (g_buffer(MIX_DEST_A0, ptr)+g_buffer(MIX_DEST_B0, ptr)) / 3;
+ iRVBRight = (g_buffer(MIX_DEST_A1, ptr)+g_buffer(MIX_DEST_B1, ptr)) / 3;
CurrAddr++;
if(CurrAddr>delay-1) CurrAddr=0;
@@ -195,7 +201,7 @@ long MixREVERBLeft(long INPUT_SAMPLE_L, long INPUT_SAMPLE_R, long *ptr)
return (long)iRVBLeft;
}
-long MixREVERBRight(void)
+static inline long MixREVERBRight(void)
{
return (long)iRVBRight;
}
@@ -227,12 +233,12 @@ void MV_FPReverb(int volume)
{
for (i = 0; i < count; i++)
{
- long temp = MV_FooBuffer[i];
+ long temp = MV_FooBuffer[i] << FRACBITS;
/* evaluation order matters */
long total = MixREVERBLeft(temp, temp, reverbBuffer);
total += MixREVERBRight();
total /= 2;
- MV_FooBuffer[i] += (scale * total) >> FRACBITS;
+ MV_FooBuffer[i] += (scale * total) >> (FRACBITS * 2);
}
}
else
@@ -240,12 +246,12 @@ void MV_FPReverb(int volume)
count /= 2;
for (i = 0; i < count; i++)
{
- long left = MV_FooBuffer[i*2];
- long right = MV_FooBuffer[i*2+1];
+ long left = MV_FooBuffer[i*2] << FRACBITS;
+ long right = MV_FooBuffer[i*2+1] << FRACBITS;
left += (scale * MixREVERBLeft(left, right, reverbBuffer)) >> FRACBITS;
right += (scale * MixREVERBRight()) >> FRACBITS;
- MV_FooBuffer[i*2] = left;
- MV_FooBuffer[i*2+1] = right;
+ MV_FooBuffer[i*2] = left >> FRACBITS;
+ MV_FooBuffer[i*2+1] = right >> FRACBITS;
}
}
@@ -275,7 +281,7 @@ void MV_16BitDownmix(char *dest, int count)
for (i = 0; i < count; i++)
{
- int out = MV_FooBuffer[i] >> FRACBITS;
+ int out = MV_FooBuffer[i];
if (out < -32768) pdest[i] = -32768;
else if (out > 32767) pdest[i] = 32767;
else pdest[i] = out;
@@ -288,7 +294,7 @@ void MV_8BitDownmix(char *dest, int count)
for (i = 0; i < count; i++)
{
- int out = MV_FooBuffer[i] >> FRACBITS;
+ int out = MV_FooBuffer[i] >> 8;
if (out < -128) dest[i] = 0;
else if (out > 127) dest[i] = 255;
else dest[i] = out + 0x80;
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/config.c b/apps/plugins/sdl/progs/duke3d/Game/src/config.c
index 038875a4e5..1649c40b07 100644
--- a/apps/plugins/sdl/progs/duke3d/Game/src/config.c
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/config.c
@@ -728,6 +728,7 @@ void CONFIG_ReadSetup( void )
NumBits = 16;
SCRIPT_GetNumber( scripthandle, "Sound Setup", "MixRate",&MixRate);
MixRate = RB_SAMPR;
+ printf("MixRate = %d Hz", MixRate);
SCRIPT_GetNumber( scripthandle, "Sound Setup", "MidiPort",&MidiPort);
SCRIPT_GetNumber( scripthandle, "Sound Setup", "BlasterAddress",&dummy);
BlasterConfig.Address = dummy;