Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

snd_flt.cpp

Go to the documentation of this file.
00001 /*
00002  * This program is  free software; you can redistribute it  and modify it
00003  * under the terms of the GNU  General Public License as published by the
00004  * Free Software Foundation; either version 2  of the license or (at your
00005  * option) any later version.
00006  *
00007  * Authors: Olivier Lapicque <olivierl@jps.net>
00008 */
00009 
00010 #include "stdafx.h"
00011 #include "sndfile.h"
00012 
00013 // AWE32: cutoff = reg[0-255] * 31.25 + 100 -> [100Hz-8060Hz]
00014 // EMU10K1 docs: cutoff = reg[0-127]*62+100
00015 #define FILTER_PRECISION        8192
00016 
00017 #ifndef NO_FILTER
00018 
00019 #ifdef WIN32
00020 #define _ASM_MATH
00021 #endif
00022 
00023 #ifdef _ASM_MATH
00024 
00025 // pow(a,b) returns a^^b -> 2^^(b.log2(a))
00026 static float pow(float a, float b)
00027 {
00028         long tmpint;
00029         float result;
00030         _asm {
00031         fld b                           // Load b
00032         fld a                           // Load a
00033         fyl2x                           // ST(0) = b.log2(a)
00034         fist tmpint                     // Store integer exponent
00035         fisub tmpint            // ST(0) = -1 <= (b*log2(a)) <= 1
00036         f2xm1                           // ST(0) = 2^(x)-1
00037         fild tmpint                     // load integer exponent
00038         fld1                            // Load 1
00039         fscale                          // ST(0) = 2^ST(1)
00040         fstp ST(1)                      // Remove the integer from the stack
00041         fmul ST(1), ST(0)       // multiply with fractional part
00042         faddp ST(1), ST(0)      // add integer_part
00043         fstp result                     // Store the result
00044         }
00045         return result;
00046 }
00047 
00048 
00049 #else
00050 
00051 #include <math.h>
00052 
00053 #endif // _ASM_MATH
00054 
00055 
00056 DWORD CSoundFile::CutOffToFrequency(UINT nCutOff, int flt_modifier) const
00057 //-----------------------------------------------------------------------
00058 {
00059         float Fc;
00060 
00061         if (m_dwSongFlags & SONG_EXFILTERRANGE)
00062                 Fc = 110.0f * pow(2.0f, 0.25f + ((float)(nCutOff*(flt_modifier+256)))/(21.0f*512.0f));
00063         else
00064                 Fc = 110.0f * pow(2.0f, 0.25f + ((float)(nCutOff*(flt_modifier+256)))/(24.0f*512.0f));
00065         LONG freq = (LONG)Fc;
00066         if (freq < 120) return 120;
00067         if (freq > 10000) return 10000;
00068         if (freq*2 > (LONG)gdwMixingFreq) freq = gdwMixingFreq>>1;
00069         return (DWORD)freq;
00070 }
00071 
00072 
00073 // Simple 2-poles resonant filter
00074 void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier) const
00075 //----------------------------------------------------------------------------------------
00076 {
00077         float fc = (float)CutOffToFrequency(pChn->nCutOff, flt_modifier);
00078         float fs = (float)gdwMixingFreq;
00079         float fg, fb0, fb1;
00080 
00081         fc *= (float)(2.0*3.14159265358/fs);
00082         float dmpfac = pow(10.0f, -((24.0f / 128.0f)*(float)pChn->nResonance) / 20.0f);
00083         float d = (1.0f-2.0f*dmpfac)* fc;
00084         if (d>2.0) d = 2.0;
00085         d = (2.0f*dmpfac - d)/fc;
00086         float e = pow(1.0f/fc,2.0);
00087 
00088         fg=1/(1+d+e);
00089         fb0=(d+e+e)/(1+d+e);
00090         fb1=-e/(1+d+e);
00091 
00092         pChn->nFilter_A0 = (int)(fg * FILTER_PRECISION);
00093         pChn->nFilter_B0 = (int)(fb0 * FILTER_PRECISION);
00094         pChn->nFilter_B1 = (int)(fb1 * FILTER_PRECISION);
00095         
00096         if (bReset)
00097         {
00098                 pChn->nFilter_Y1 = pChn->nFilter_Y2 = 0;
00099                 pChn->nFilter_Y3 = pChn->nFilter_Y4 = 0;
00100         }
00101         pChn->dwFlags |= CHN_FILTER;
00102 }
00103 
00104 #endif // NO_FILTER

Generated on Sat Nov 5 16:15:41 2005 for OPIE by  doxygen 1.4.2