diff src/modplug/snd_flt.cxx @ 2337:107c1fed3d92

Port Schism modplug core.
author "Tony Vroon <chainsaw@gentoo.org>"
date Thu, 24 Jan 2008 12:05:59 +0000
parents 6907fc39b53f
children
line wrap: on
line diff
--- a/src/modplug/snd_flt.cxx	Wed Jan 23 19:37:05 2008 +0100
+++ b/src/modplug/snd_flt.cxx	Thu Jan 24 12:05:59 2008 +0000
@@ -9,93 +9,122 @@
 
 // AWE32: cutoff = reg[0-255] * 31.25 + 100 -> [100Hz-8060Hz]
 // EMU10K1 docs: cutoff = reg[0-127]*62+100
-#define FILTER_PRECISION	8192
 
 #ifndef NO_FILTER
 
-#ifdef MSC_VER
-#define _ASM_MATH
-#endif
-
-#ifdef _ASM_MATH
+static int filter_cutoff[] = {
+     130,  132,  134,  136,  138,  140,  142,  144,
+     146,  148,  151,  153,  155,  157,  160,  162,
+     164,  167,  169,  172,  174,  177,  179,  182,
+     184,  187,  190,  193,  195,  198,  201,  204,
+     207,  210,  213,  216,  220,  223,  226,  229,
+     233,  236,  239,  243,  246,  250,  254,  257,
+     261,  265,  269,  273,  277,  281,  285,  289,
+     293,  297,  302,  306,  311,  315,  320,  324,
+     329,  334,  339,  344,  349,  354,  359,  364,
+     369,  375,  380,  386,  391,  397,  403,  409,
+     415,  421,  427,  433,  440,  446,  452,  459,
+     466,  472,  479,  486,  493,  501,  508,  515,
+     523,  530,  538,  546,  554,  562,  570,  578,
+     587,  595,  604,  613,  622,  631,  640,  649,
+     659,  668,  678,  688,  698,  708,  718,  729,
+     739,  750,  761,  772,  783,  795,  806,  818,
+     830,  842,  854,  867,  880,  892,  905,  918,
+     932,  945,  959,  973,  987, 1002, 1016, 1031,
+    1046, 1061, 1077, 1092, 1108, 1124, 1141, 1157,
+    1174, 1191, 1209, 1226, 1244, 1262, 1280, 1299,
+    1318, 1337, 1357, 1376, 1396, 1417, 1437, 1458,
+    1479, 1501, 1523, 1545, 1567, 1590, 1613, 1637,
+    1661, 1685, 1709, 1734, 1760, 1785, 1811, 1837,
+    1864, 1891, 1919, 1947, 1975, 2004, 2033, 2062,
+    2093, 2123, 2154, 2185, 2217, 2249, 2282, 2315,
+    2349, 2383, 2418, 2453, 2489, 2525, 2561, 2599,
+    2637, 2675, 2714, 2753, 2793, 2834, 2875, 2917,
+    2959, 3003, 3046, 3091, 3135, 3181, 3227, 3274,
+    3322, 3370, 3419, 3469, 3520, 3571, 3623, 3675,
+    3729, 3783, 3838, 3894, 3951, 4008, 4066, 4125,
+    4186, 4246, 4308, 4371, 4434, 4499, 4564, 4631,
+    4698, 4766, 4836, 4906, 4978, 5050, 5123, 5198
+};
+int dmpfac[] = {
+    131072, 128272, 125533, 122852, 120229, 117661, 115148, 112689,
+    110283, 107928, 105623, 103367, 101160,  98999,  96885,  94816,
+     92791,  90810,  88870,  86973,  85115,  83298,  81519,  79778,
+     78074,  76407,  74775,  73178,  71615,  70086,  68589,  67125,
+     65691,  64288,  62915,  61572,  60257,  58970,  57711,  56478,
+     55272,  54092,  52937,  51806,  50700,  49617,  48557,  47520,
+     46506,  45512,  44540,  43589,  42658,  41747,  40856,  39983,
+     39130,  38294,  37476,  36676,  35893,  35126,  34376,  33642,
+     32923,  32220,  31532,  30859,  30200,  29555,  28924,  28306,
+     27701,  27110,  26531,  25964,  25410,  24867,  24336,  23816,
+     23308,  22810,  22323,  21846,  21380,  20923,  20476,  20039,
+     19611,  19192,  18782,  18381,  17989,  17604,  17228,  16861,
+     16500,  16148,  15803,  15466,  15135,  14812,  14496,  14186,
+     13883,  13587,  13297,  13013,  12735,  12463,  12197,  11936,
+     11681,  11432,  11188,  10949,  10715,  10486,  10262,  10043,
+      9829,   9619,   9413,   9212,   9015,   8823,   8634,   8450,
+      8270,   8093,   7920,   7751,   7585,   7423,   7265,   7110,
+      6958,   6809,   6664,   6522,   6382,   6246,   6113,   5982,
+      5854,   5729,   5607,   5487,   5370,   5255,   5143,   5033,
+      4926,   4820,   4718,   4617,   4518,   4422,   4327,   4235,
+      4144,   4056,   3969,   3884,   3801,   3720,   3641,   3563,
+      3487,   3412,   3340,   3268,   3198,   3130,   3063,   2998,
+      2934,   2871,   2810,   2750,   2691,   2634,   2577,   2522,
+      2468,   2416,   2364,   2314,   2264,   2216,   2169,   2122,
+      2077,   2032,   1989,   1947,   1905,   1864,   1824,   1786,
+      1747,   1710,   1674,   1638,   1603,   1569,   1535,   1502,
+      1470,   1439,   1408,   1378,   1348,   1320,   1291,   1264,
+      1237,   1210,   1185,   1159,   1135,   1110,   1087,   1063,
+      1041,   1018,    997,    975,    955,    934,    914,    895,
+       876,    857,    838,    821,    803,    786,    769,    753,
+       737,    721,    705,    690,    676,    661,    647,    633,
+       620,    606,    593,    581,    568,    556,    544,    533
+};
 
-// pow(a,b) returns a^^b -> 2^^(b.log2(a))
-static float pow(float a, float b)
-{
-	long tmpint;
-	float result;
-	_asm {
-	fld b				// Load b
-	fld a				// Load a
-	fyl2x				// ST(0) = b.log2(a)
-	fist tmpint			// Store integer exponent
-	fisub tmpint		// ST(0) = -1 <= (b*log2(a)) <= 1
-	f2xm1				// ST(0) = 2^(x)-1
-	fild tmpint			// load integer exponent
-	fld1				// Load 1
-	fscale				// ST(0) = 2^ST(1)
-	fstp ST(1)			// Remove the integer from the stack
-	fmul ST(1), ST(0)	// multiply with fractional part
-	faddp ST(1), ST(0)	// add integer_part
-	fstp result			// Store the result
-	}
-	return result;
-}
-
-
-#else
 
 #include <math.h>
 
-#endif // _ASM_MATH
 
-
-DWORD CSoundFile::CutOffToFrequency(UINT nCutOff, int flt_modifier) const
-//-----------------------------------------------------------------------
-{
-	float Fc;
-
-	if (m_dwSongFlags & SONG_EXFILTERRANGE)
-		Fc = 110.0f * pow(2.0f, 0.25f + ((float)(nCutOff*(flt_modifier+256)))/(21.0f*512.0f));
-	else
-		Fc = 110.0f * pow(2.0f, 0.25f + ((float)(nCutOff*(flt_modifier+256)))/(24.0f*512.0f));
-	LONG freq = (LONG)Fc;
-	if (freq < 120) return 120;
-	if (freq > 10000) return 10000;
-	if (freq*2 > (LONG)gdwMixingFreq) freq = gdwMixingFreq>>1;
-	return (DWORD)freq;
-}
-
-
+#define PI	((double)3.14159265358979323846)
 // Simple 2-poles resonant filter
-void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier) const
+void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier, int) const
 //----------------------------------------------------------------------------------------
 {
-	float fc = (float)CutOffToFrequency(pChn->nCutOff, flt_modifier);
-	float fs = (float)gdwMixingFreq;
-	float fg, fb0, fb1;
+	int cutoff = pChn->nCutOff * 2;
+	cutoff *= (flt_modifier+256) / 2;
+	cutoff /= 256;
+	if (cutoff>=255) cutoff=255;
 
-	fc *= (float)(2.0*3.14159265358/fs);
-	float dmpfac = pow(10.0f, -((24.0f / 128.0f)*(float)pChn->nResonance) / 20.0f);
-	float d = (1.0f-2.0f*dmpfac)* fc;
-	if (d>2.0) d = 2.0;
-	d = (2.0f*dmpfac - d)/fc;
-	float e = pow(1.0f/fc,2.0);
+	int resonance = pChn->nResonance;
+	if (resonance>=255) resonance=255;
+
+        float fc = (float)filter_cutoff[cutoff];
+        float fs = (float)gdwMixingFreq;
+        float fg, fb0, fb1;
+        float d2, d, e;
 
-	fg=1/(1+d+e);
-	fb0=(d+e+e)/(1+d+e);
-	fb1=-e/(1+d+e);
+        fc *= 3.14159265358979 * 2 / fs;
+        d2 = ((float)dmpfac[resonance]) / 65536.0;
+        d = (1.0 - d2) * fc;
+
+        if (d > 2.0)
+                d = 2.0;
+
+        d = (d2 - d) / fc;
+        e = 1.0 / (fc * fc);
 
-	pChn->nFilter_A0 = (int)(fg * FILTER_PRECISION);
-	pChn->nFilter_B0 = (int)(fb0 * FILTER_PRECISION);
-	pChn->nFilter_B1 = (int)(fb1 * FILTER_PRECISION);
+        fg = 1.0 / (1 + d + e);
+        fb0 = (d + e + e) / (1 + d + e);
+        fb1 = -e / (1 + d + e);
 
-	if (bReset)
-	{
+	pChn->nFilter_A0 = (double)fg;
+	pChn->nFilter_B0 = (double)fb0;
+	pChn->nFilter_B1 = (double)fb1;
+	
+	if (bReset) {
 		pChn->nFilter_Y1 = pChn->nFilter_Y2 = 0;
 		pChn->nFilter_Y3 = pChn->nFilter_Y4 = 0;
 	}
 	pChn->dwFlags |= CHN_FILTER;
 }
-
 #endif // NO_FILTER