2 * This source code is public domain.
4 * Authors: Olivier Lapicque <olivierl@jps.net>
14 // AWE32: cutoff = reg[0-255] * 31.25 + 100 -> [100Hz-8060Hz]
15 // EMU10K1 docs: cutoff = reg[0-127]*62+100
16 #define FILTER_PRECISION 8192
26 // pow(a,b) returns a^^b -> 2^^(b.log2(a))
27 static float pow(float a, float b)
34 fyl2x // ST(0) = b.log2(a)
35 fist tmpint // Store integer exponent
36 fisub tmpint // ST(0) = -1 <= (b*log2(a)) <= 1
37 f2xm1 // ST(0) = 2^(x)-1
38 fild tmpint // load integer exponent
40 fscale // ST(0) = 2^ST(1)
41 fstp ST(1) // Remove the integer from the stack
42 fmul ST(1), ST(0) // multiply with fractional part
43 faddp ST(1), ST(0) // add integer_part
44 fstp result // Store the result
57 DWORD CSoundFile::CutOffToFrequency(UINT nCutOff, int flt_modifier) const
58 //-----------------------------------------------------------------------
62 if (m_dwSongFlags & SONG_EXFILTERRANGE)
63 Fc = 110.0f * pow(2.0f, 0.25f + ((float)(nCutOff*(flt_modifier+256)))/(21.0f*512.0f));
65 Fc = 110.0f * pow(2.0f, 0.25f + ((float)(nCutOff*(flt_modifier+256)))/(24.0f*512.0f));
67 if (freq < 120) return 120;
68 if (freq > 10000) return 10000;
69 if (freq*2 > (LONG)gdwMixingFreq) freq = gdwMixingFreq>>1;
74 // Simple 2-poles resonant filter
75 void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier) const
76 //----------------------------------------------------------------------------------------
78 float fc = (float)CutOffToFrequency(pChn->nCutOff, flt_modifier);
79 float fs = (float)gdwMixingFreq;
82 fc *= (float)(2.0*3.14159265358/fs);
83 float dmpfac = pow(10.0f, -((24.0f / 128.0f)*(float)pChn->nResonance) / 20.0f);
84 float d = (1.0f-2.0f*dmpfac)* fc;
86 d = (2.0f*dmpfac - d)/fc;
87 float e = pow(1.0f/fc, 2);
93 pChn->nFilter_A0 = (int)(fg * FILTER_PRECISION);
94 pChn->nFilter_B0 = (int)(fb0 * FILTER_PRECISION);
95 pChn->nFilter_B1 = (int)(fb1 * FILTER_PRECISION);
99 pChn->nFilter_Y1 = pChn->nFilter_Y2 = 0;
100 pChn->nFilter_Y3 = pChn->nFilter_Y4 = 0;
102 pChn->dwFlags |= CHN_FILTER;