author | llornkcor <llornkcor> | 2002-07-20 22:07:31 (UTC) |
---|---|---|
committer | llornkcor <llornkcor> | 2002-07-20 22:07:31 (UTC) |
commit | 2342d48be31847e7ead9d1cc682452e8f0122351 (patch) (side-by-side diff) | |
tree | 8329bb94e9d429c905a0ef6b881cf1c0f775bf14 /core/multimedia/opieplayer/modplug/snd_flt.cpp | |
parent | 0f24c1fb86d3bb58d8696358b824c0e01752b10d (diff) | |
download | opie-2342d48be31847e7ead9d1cc682452e8f0122351.zip opie-2342d48be31847e7ead9d1cc682452e8f0122351.tar.gz opie-2342d48be31847e7ead9d1cc682452e8f0122351.tar.bz2 |
initial commit of modplugin
Diffstat (limited to 'core/multimedia/opieplayer/modplug/snd_flt.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/modplug/snd_flt.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/modplug/snd_flt.cpp b/core/multimedia/opieplayer/modplug/snd_flt.cpp new file mode 100644 index 0000000..5ac241e --- a/dev/null +++ b/core/multimedia/opieplayer/modplug/snd_flt.cpp @@ -0,0 +1,104 @@ +/* + * This program is free software; you can redistribute it and modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the license or (at your + * option) any later version. + * + * Authors: Olivier Lapicque <olivierl@jps.net> +*/ + +#include "stdafx.h" +#include "sndfile.h" + +// 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 WIN32 +#define _ASM_MATH +#endif + +#ifdef _ASM_MATH + +// 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; +} + + +// Simple 2-poles resonant filter +void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier) const +//---------------------------------------------------------------------------------------- +{ + float fc = (float)CutOffToFrequency(pChn->nCutOff, flt_modifier); + float fs = (float)gdwMixingFreq; + float fg, fb0, fb1; + + 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); + + fg=1/(1+d+e); + fb0=(d+e+e)/(1+d+e); + fb1=-e/(1+d+e); + + pChn->nFilter_A0 = (int)(fg * FILTER_PRECISION); + pChn->nFilter_B0 = (int)(fb0 * FILTER_PRECISION); + pChn->nFilter_B1 = (int)(fb1 * FILTER_PRECISION); + + if (bReset) + { + pChn->nFilter_Y1 = pChn->nFilter_Y2 = 0; + pChn->nFilter_Y3 = pChn->nFilter_Y4 = 0; + } + pChn->dwFlags |= CHN_FILTER; +} + +#endif // NO_FILTER |