|
From: <man...@us...> - 2013-06-15 04:42:33
|
Revision: 2368
http://sourceforge.net/p/modplug/code/2368
Author: manxorist
Date: 2013-06-15 04:42:22 +0000 (Sat, 15 Jun 2013)
Log Message:
-----------
[Imp] Improve precision of polyphase 8-tap resampling filter tables by 1 bit.
[Ref] Use proper constants instead of magic values for filter coefficients table lookup.
[Ref] Avoid unneeded pointer cast in filter coefficients table lookup.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Fastmix.cpp
trunk/OpenMPT/soundlib/Resampler.h
trunk/OpenMPT/soundlib/Tables.cpp
Modified: trunk/OpenMPT/soundlib/Fastmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Fastmix.cpp 2013-06-14 11:13:43 UTC (rev 2367)
+++ trunk/OpenMPT/soundlib/Fastmix.cpp 2013-06-15 04:42:22 UTC (rev 2368)
@@ -92,19 +92,19 @@
// 8-taps polyphase
#define SNDMIX_GETMONOVOL8KAISER\
int poshi = nPos >> 16;\
- const short int *poslo = (const short int *)(sinc+(nPos&0xfff0));\
- int vol = (poslo[0]*p[poshi-3] + poslo[1]*p[poshi-2]\
+ const SINC_TYPE *poslo = sinc + ((nPos >> (16-SINC_PHASES_BITS)) & SINC_MASK) * SINC_WIDTH;\
+ int vol = ((poslo[0]*p[poshi-3] + poslo[1]*p[poshi-2]\
+ poslo[2]*p[poshi-1] + poslo[3]*p[poshi]\
+ poslo[4]*p[poshi+1] + poslo[5]*p[poshi+2]\
- + poslo[6]*p[poshi+3] + poslo[7]*p[poshi+4]) >> 6;\
+ + poslo[6]*p[poshi+3] + poslo[7]*p[poshi+4]) >> (SINC_QUANTSHIFT-8));\
#define SNDMIX_GETMONOVOL16KAISER\
int poshi = nPos >> 16;\
- const short int *poslo = (const short int *)(sinc+(nPos&0xfff0));\
- int vol = (poslo[0]*p[poshi-3] + poslo[1]*p[poshi-2]\
+ const SINC_TYPE *poslo = sinc + ((nPos >> (16-SINC_PHASES_BITS)) & SINC_MASK) * SINC_WIDTH;\
+ int vol = ((poslo[0]*p[poshi-3] + poslo[1]*p[poshi-2]\
+ poslo[2]*p[poshi-1] + poslo[3]*p[poshi]\
+ poslo[4]*p[poshi+1] + poslo[5]*p[poshi+2]\
- + poslo[6]*p[poshi+3] + poslo[7]*p[poshi+4]) >> 14;\
+ + poslo[6]*p[poshi+3] + poslo[7]*p[poshi+4]) >> SINC_QUANTSHIFT);\
// rewbs.resamplerConf
#define SNDMIX_GETMONOVOL8FIRFILTER \
int poshi = nPos >> 16;\
@@ -137,7 +137,7 @@
// end rewbs.resamplerConf
#define SNDMIX_INITSINCTABLE\
- const char * const sinc = (const char *)(((pChannel->nInc > 0x13000) || (pChannel->nInc < -0x13000)) ?\
+ const SINC_TYPE * const sinc = (((pChannel->nInc > 0x13000) || (pChannel->nInc < -0x13000)) ?\
(((pChannel->nInc > 0x18000) || (pChannel->nInc < -0x18000)) ? pResampler->gDownsample2x : pResampler->gDownsample13x) : pResampler->gKaiserSinc);
#define SNDMIX_INITFIRTABLE\
@@ -195,27 +195,27 @@
// 8-taps polyphase
#define SNDMIX_GETSTEREOVOL8KAISER\
int poshi = nPos >> 16;\
- const short int *poslo = (const short int *)(sinc+(nPos&0xfff0));\
- int vol_l = (poslo[0]*p[poshi*2-6] + poslo[1]*p[poshi*2-4]\
+ const SINC_TYPE *poslo = sinc + ((nPos >> (16-SINC_PHASES_BITS)) & SINC_MASK) * SINC_WIDTH;\
+ int vol_l = ((poslo[0]*p[poshi*2-6] + poslo[1]*p[poshi*2-4]\
+ poslo[2]*p[poshi*2-2] + poslo[3]*p[poshi*2]\
+ poslo[4]*p[poshi*2+2] + poslo[5]*p[poshi*2+4]\
- + poslo[6]*p[poshi*2+6] + poslo[7]*p[poshi*2+8]) >> 6;\
- int vol_r = (poslo[0]*p[poshi*2-5] + poslo[1]*p[poshi*2-3]\
+ + poslo[6]*p[poshi*2+6] + poslo[7]*p[poshi*2+8]) >> (SINC_QUANTSHIFT-8));\
+ int vol_r = ((poslo[0]*p[poshi*2-5] + poslo[1]*p[poshi*2-3]\
+ poslo[2]*p[poshi*2-1] + poslo[3]*p[poshi*2+1]\
+ poslo[4]*p[poshi*2+3] + poslo[5]*p[poshi*2+5]\
- + poslo[6]*p[poshi*2+7] + poslo[7]*p[poshi*2+9]) >> 6;\
+ + poslo[6]*p[poshi*2+7] + poslo[7]*p[poshi*2+9]) >> (SINC_QUANTSHIFT-8));\
#define SNDMIX_GETSTEREOVOL16KAISER\
int poshi = nPos >> 16;\
- const short int *poslo = (const short int *)(sinc+(nPos&0xfff0));\
- int vol_l = (poslo[0]*p[poshi*2-6] + poslo[1]*p[poshi*2-4]\
+ const SINC_TYPE *poslo = sinc + ((nPos >> (16-SINC_PHASES_BITS)) & SINC_MASK) * SINC_WIDTH;\
+ int vol_l = ((poslo[0]*p[poshi*2-6] + poslo[1]*p[poshi*2-4]\
+ poslo[2]*p[poshi*2-2] + poslo[3]*p[poshi*2]\
+ poslo[4]*p[poshi*2+2] + poslo[5]*p[poshi*2+4]\
- + poslo[6]*p[poshi*2+6] + poslo[7]*p[poshi*2+8]) >> 14;\
- int vol_r = (poslo[0]*p[poshi*2-5] + poslo[1]*p[poshi*2-3]\
+ + poslo[6]*p[poshi*2+6] + poslo[7]*p[poshi*2+8]) >> SINC_QUANTSHIFT);\
+ int vol_r = ((poslo[0]*p[poshi*2-5] + poslo[1]*p[poshi*2-3]\
+ poslo[2]*p[poshi*2-1] + poslo[3]*p[poshi*2+1]\
+ poslo[4]*p[poshi*2+3] + poslo[5]*p[poshi*2+5]\
- + poslo[6]*p[poshi*2+7] + poslo[7]*p[poshi*2+9]) >> 14;\
+ + poslo[6]*p[poshi*2+7] + poslo[7]*p[poshi*2+9]) >> SINC_QUANTSHIFT);\
// rewbs.resamplerConf
// fir interpolation
#define SNDMIX_GETSTEREOVOL8FIRFILTER \
Modified: trunk/OpenMPT/soundlib/Resampler.h
===================================================================
--- trunk/OpenMPT/soundlib/Resampler.h 2013-06-14 11:13:43 UTC (rev 2367)
+++ trunk/OpenMPT/soundlib/Resampler.h 2013-06-15 04:42:22 UTC (rev 2368)
@@ -14,9 +14,18 @@
#include "MixerSettings.h"
-#define SINC_PHASES 4096
+#define SINC_WIDTH 8
+#define SINC_PHASES_BITS 12
+#define SINC_PHASES (1<<SINC_PHASES_BITS)
+#define SINC_TYPE int16
+#define SINC_QUANTSHIFT 15
+
+#define SINC_MASK (SINC_PHASES-1)
+STATIC_ASSERT((SINC_MASK & 0xffff) == SINC_MASK); // exceeding fractional freq
+
+
//======================
class CResamplerSettings
//======================
@@ -48,15 +57,15 @@
CResamplerSettings m_Settings;
CWindowedFIR m_WindowedFIR;
static const int16 FastSincTable[256*4];
- int16 gKaiserSinc[SINC_PHASES*8]; // Upsampling
+ SINC_TYPE gKaiserSinc[SINC_PHASES*8]; // Upsampling
#ifdef MODPLUG_TRACKER
static bool StaticTablesInitialized;
- static int16 gDownsample13x[SINC_PHASES*8]; // Downsample 1.333x
- static int16 gDownsample2x[SINC_PHASES*8]; // Downsample 2x
+ static SINC_TYPE gDownsample13x[SINC_PHASES*8]; // Downsample 1.333x
+ static SINC_TYPE gDownsample2x[SINC_PHASES*8]; // Downsample 2x
#else
// no global data which has to be initialized by hand in the library
- int16 gDownsample13x[SINC_PHASES*8]; // Downsample 1.333x
- int16 gDownsample2x[SINC_PHASES*8]; // Downsample 2x
+ SINC_TYPE gDownsample13x[SINC_PHASES*8]; // Downsample 1.333x
+ SINC_TYPE gDownsample2x[SINC_PHASES*8]; // Downsample 2x
#endif
private:
CResamplerSettings m_OldSettings;
Modified: trunk/OpenMPT/soundlib/Tables.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Tables.cpp 2013-06-14 11:13:43 UTC (rev 2367)
+++ trunk/OpenMPT/soundlib/Tables.cpp 2013-06-15 04:42:22 UTC (rev 2368)
@@ -712,7 +712,7 @@
return s;
}
-static void getsinc(short int *psinc, double beta, double lowpass_factor)
+static void getsinc(SINC_TYPE *psinc, double beta, double lowpass_factor)
{
const double izero_beta = izero(beta);
const double kPi = 4.0*atan(1.0)*lowpass_factor;
@@ -729,8 +729,11 @@
double x = (double)(ix - (4*SINC_PHASES)) * (double)(1.0/SINC_PHASES);
fsinc = sin(x*kPi) * izero(beta*sqrt(1-x*x*(1.0/16.0))) / (izero_beta*x*kPi); // Kaiser window
}
- int n = (int)(fsinc * lowpass_factor * (16384*256));
- *psinc++ = static_cast<short>((n+0x80)>>8); // force rounding
+ double coeff = fsinc * lowpass_factor;
+ int n = (int)std::floor(coeff * (1<<SINC_QUANTSHIFT) + 0.5);
+ ASSERT(n <= int16_max);
+ ASSERT(n > int16_min);
+ *psinc++ = static_cast<SINC_TYPE>(n);
}
}
@@ -773,8 +776,8 @@
#ifdef MODPLUG_TRACKER
bool CResampler::StaticTablesInitialized = false;
-int16 CResampler::gDownsample13x[SINC_PHASES*8]; // Downsample 1.333x
-int16 CResampler::gDownsample2x[SINC_PHASES*8]; // Downsample 2x
+SINC_TYPE CResampler::gDownsample13x[SINC_PHASES*8]; // Downsample 1.333x
+SINC_TYPE CResampler::gDownsample2x[SINC_PHASES*8]; // Downsample 2x
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|