annotate src/modplug/snd_flt.cxx @ 136:6b5a52635b3b trunk

[svn] - like with so many other things, modplug is now maintained by us.
author nenolod
date Sun, 29 Oct 2006 01:04:52 -0700
parents
children 032053ca08ab 3673c7ec4ea2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
136
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
1 /*
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
2 * This source code is public domain.
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
3 *
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
4 * Authors: Olivier Lapicque <olivierl@jps.net>
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
5 */
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
6
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
7 #include "stdafx.h"
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
8 #include "sndfile.h"
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
9
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
10 // AWE32: cutoff = reg[0-255] * 31.25 + 100 -> [100Hz-8060Hz]
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
11 // EMU10K1 docs: cutoff = reg[0-127]*62+100
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
12 #define FILTER_PRECISION 8192
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
13
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
14 #ifndef NO_FILTER
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
15
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
16 #ifdef MSC_VER
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
17 #define _ASM_MATH
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
18 #endif
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
19
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
20 #ifdef _ASM_MATH
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
21
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
22 // pow(a,b) returns a^^b -> 2^^(b.log2(a))
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
23 static float pow(float a, float b)
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
24 {
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
25 long tmpint;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
26 float result;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
27 _asm {
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
28 fld b // Load b
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
29 fld a // Load a
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
30 fyl2x // ST(0) = b.log2(a)
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
31 fist tmpint // Store integer exponent
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
32 fisub tmpint // ST(0) = -1 <= (b*log2(a)) <= 1
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
33 f2xm1 // ST(0) = 2^(x)-1
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
34 fild tmpint // load integer exponent
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
35 fld1 // Load 1
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
36 fscale // ST(0) = 2^ST(1)
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
37 fstp ST(1) // Remove the integer from the stack
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
38 fmul ST(1), ST(0) // multiply with fractional part
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
39 faddp ST(1), ST(0) // add integer_part
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
40 fstp result // Store the result
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
41 }
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
42 return result;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
43 }
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
44
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
45
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
46 #else
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
47
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
48 #include <math.h>
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
49
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
50 #endif // _ASM_MATH
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
51
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
52
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
53 DWORD CSoundFile::CutOffToFrequency(UINT nCutOff, int flt_modifier) const
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
54 //-----------------------------------------------------------------------
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
55 {
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
56 float Fc;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
57
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
58 if (m_dwSongFlags & SONG_EXFILTERRANGE)
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
59 Fc = 110.0f * pow(2.0f, 0.25f + ((float)(nCutOff*(flt_modifier+256)))/(21.0f*512.0f));
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
60 else
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
61 Fc = 110.0f * pow(2.0f, 0.25f + ((float)(nCutOff*(flt_modifier+256)))/(24.0f*512.0f));
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
62 LONG freq = (LONG)Fc;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
63 if (freq < 120) return 120;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
64 if (freq > 10000) return 10000;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
65 if (freq*2 > (LONG)gdwMixingFreq) freq = gdwMixingFreq>>1;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
66 return (DWORD)freq;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
67 }
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
68
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
69
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
70 // Simple 2-poles resonant filter
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
71 void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier) const
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
72 //----------------------------------------------------------------------------------------
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
73 {
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
74 float fc = (float)CutOffToFrequency(pChn->nCutOff, flt_modifier);
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
75 float fs = (float)gdwMixingFreq;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
76 float fg, fb0, fb1;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
77
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
78 fc *= (float)(2.0*3.14159265358/fs);
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
79 float dmpfac = pow(10.0f, -((24.0f / 128.0f)*(float)pChn->nResonance) / 20.0f);
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
80 float d = (1.0f-2.0f*dmpfac)* fc;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
81 if (d>2.0) d = 2.0;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
82 d = (2.0f*dmpfac - d)/fc;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
83 float e = pow(1.0f/fc,2.0);
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
84
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
85 fg=1/(1+d+e);
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
86 fb0=(d+e+e)/(1+d+e);
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
87 fb1=-e/(1+d+e);
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
88
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
89 pChn->nFilter_A0 = (int)(fg * FILTER_PRECISION);
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
90 pChn->nFilter_B0 = (int)(fb0 * FILTER_PRECISION);
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
91 pChn->nFilter_B1 = (int)(fb1 * FILTER_PRECISION);
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
92
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
93 if (bReset)
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
94 {
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
95 pChn->nFilter_Y1 = pChn->nFilter_Y2 = 0;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
96 pChn->nFilter_Y3 = pChn->nFilter_Y4 = 0;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
97 }
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
98 pChn->dwFlags |= CHN_FILTER;
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
99 }
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
100
6b5a52635b3b [svn] - like with so many other things, modplug is now maintained by us.
nenolod
parents:
diff changeset
101 #endif // NO_FILTER