2009-02-15 05:15:39 +00:00
|
|
|
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
|
|
|
|
* Developed and maintained by the Pcsx2 Development Team.
|
2010-04-25 00:31:27 +00:00
|
|
|
*
|
2009-02-15 05:15:39 +00:00
|
|
|
* Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
|
|
|
|
*
|
2009-06-21 11:00:53 +00:00
|
|
|
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE. See the GNU Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>.
|
2009-02-15 05:15:39 +00:00
|
|
|
*/
|
|
|
|
|
2010-02-05 03:59:19 +00:00
|
|
|
#include "Global.h"
|
2016-06-21 18:15:53 +00:00
|
|
|
#include "Lowpass.h"
|
2009-02-15 05:15:39 +00:00
|
|
|
#include <math.h>
|
|
|
|
#include <float.h>
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
template< typename FloatType > __forceinline
|
2009-09-29 19:18:50 +00:00
|
|
|
LowPassFilter<FloatType>::LowPassFilter( FloatType freq, FloatType srate )
|
2009-02-15 05:15:39 +00:00
|
|
|
{
|
2009-09-29 19:18:50 +00:00
|
|
|
typedef FloatType FT;
|
|
|
|
|
|
|
|
FloatType omega = (FT)2.0 * freq / srate;
|
2010-04-25 00:31:27 +00:00
|
|
|
static const FloatType g = (FT)1.0;
|
2009-02-15 05:15:39 +00:00
|
|
|
|
|
|
|
// calculating coefficients:
|
|
|
|
|
2009-09-29 19:18:50 +00:00
|
|
|
FloatType k,p,q,a;
|
|
|
|
FloatType a0,a1,a2,a3,a4;
|
2009-02-15 05:15:39 +00:00
|
|
|
|
2009-09-29 19:18:50 +00:00
|
|
|
k = ((FT)4.0*g-(FT)3.0)/(g+(FT)1.0);
|
|
|
|
p = (FT)1.0-(FT)0.25*k;
|
|
|
|
p *= p;
|
2009-02-15 05:15:39 +00:00
|
|
|
|
|
|
|
// LP:
|
2009-09-29 19:18:50 +00:00
|
|
|
a = (FT)1.0/(tan((FT)0.5*omega)*((FT)1.0+p));
|
|
|
|
p = (FT)1.0+a;
|
|
|
|
q = (FT)1.0-a;
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2009-09-29 19:18:50 +00:00
|
|
|
a0 = (FT)1.0/(k+p*p*p*p);
|
|
|
|
a1 = (FT)4.0*(k+p*p*p*q);
|
|
|
|
a2 = (FT)6.0*(k+p*p*q*q);
|
|
|
|
a3 = (FT)4.0*(k+p*q*q*q);
|
|
|
|
a4 = (k+q*q*q*q);
|
|
|
|
p = a0*(k+(FT)1.0);
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2009-02-15 05:15:39 +00:00
|
|
|
coef[0] = p;
|
2009-09-29 19:18:50 +00:00
|
|
|
coef[1] = (FT)4.0*p;
|
|
|
|
coef[2] = (FT)6.0*p;
|
|
|
|
coef[3] = (FT)4.0*p;
|
2009-02-15 05:15:39 +00:00
|
|
|
coef[4] = p;
|
|
|
|
coef[5] = -a1*a0;
|
|
|
|
coef[6] = -a2*a0;
|
|
|
|
coef[7] = -a3*a0;
|
|
|
|
coef[8] = -a4*a0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Processes a single sample into the LPF.
|
2010-04-25 00:31:27 +00:00
|
|
|
template< typename FloatType > __forceinline
|
2009-09-29 19:18:50 +00:00
|
|
|
FloatType LowPassFilter<FloatType>::sample( FloatType inval )
|
2009-02-15 05:15:39 +00:00
|
|
|
{
|
2009-09-29 19:18:50 +00:00
|
|
|
const FloatType out = (coef[0]*inval) + d[0];
|
2009-02-15 05:15:39 +00:00
|
|
|
d[0] = (coef[1]*inval) + (coef[5]*out) + d[1];
|
|
|
|
d[1] = (coef[2]*inval) + (coef[6]*out) + d[2];
|
|
|
|
d[2] = (coef[3]*inval) + (coef[7]*out) + d[3];
|
2010-04-25 00:31:27 +00:00
|
|
|
d[3] = (coef[4]*inval) + (coef[8]*out);
|
2009-02-15 05:15:39 +00:00
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
2009-09-29 19:18:50 +00:00
|
|
|
|
|
|
|
LowPassFilter32::LowPassFilter32( float freq, float srate ) :
|
|
|
|
impl_lpf( freq, srate )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
LowPassFilter64::LowPassFilter64( double freq, double srate ) :
|
|
|
|
impl_lpf( freq, srate )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
float LowPassFilter32::sample( float inval )
|
|
|
|
{
|
|
|
|
return impl_lpf.sample( inval );
|
|
|
|
}
|
|
|
|
|
|
|
|
double LowPassFilter64::sample( double inval )
|
|
|
|
{
|
|
|
|
return impl_lpf.sample( inval );
|
|
|
|
}
|