You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.0 KiB
C++
112 lines
3.0 KiB
C++
/*=============================================================================
|
|
//
|
|
// This software has been released under the terms of the GNU Public
|
|
// license. See http://www.gnu.org/copyleft/gpl.html for details.
|
|
//
|
|
// Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
|
|
//
|
|
//=============================================================================
|
|
*/
|
|
|
|
#ifndef _FIRFILTER_H_
|
|
#define _FIRFILTER_H_
|
|
|
|
// Design and implementation of different types of digital filters
|
|
class TfirFilter
|
|
{
|
|
public:
|
|
enum class Type
|
|
{
|
|
LOWPASS = 0,
|
|
HIGHPASS = 1,
|
|
BANDPASS = 2,
|
|
BANDSTOP = 3
|
|
};
|
|
enum class Window
|
|
{
|
|
BOX = 0,
|
|
TRIANGLE = 1,
|
|
HAMMING = 2,
|
|
HANNING = 3,
|
|
BLACKMAN = 4,
|
|
FLATTOP = 5,
|
|
KAISER = 6
|
|
};
|
|
|
|
typedef float _ftype_t;
|
|
private:
|
|
static _ftype_t besselizero(_ftype_t x);
|
|
static void boxcar(int n, _ftype_t* w);
|
|
static void triang(int n, _ftype_t* w);
|
|
static void hanning(int n, _ftype_t* w);
|
|
static void hamming(int n,_ftype_t* w);
|
|
static void blackman(int n,_ftype_t* w);
|
|
static void flattop(int n,_ftype_t* w);
|
|
static void kaiser(int n, _ftype_t* w,_ftype_t b);
|
|
|
|
template<class T,class _ftype_t> static _ftype_t dotproduct(int count,const T *buf,const _ftype_t *coefficients)
|
|
{
|
|
_ftype_t sum0=0,sum1=0,sum2=0,sum3=0;
|
|
for (;count>=4;buf+=4,coefficients+=4,count-=4)
|
|
{
|
|
sum0+=buf[0]*coefficients[0];
|
|
sum1+=buf[1]*coefficients[1];
|
|
sum2+=buf[2]*coefficients[2];
|
|
sum3+=buf[3]*coefficients[3];
|
|
}
|
|
while (count--) sum0+= *buf++ * *coefficients++;
|
|
return sum0+sum1+sum2+sum3;
|
|
}
|
|
public:
|
|
// Exported functions
|
|
//static _ftype_t fir(unsigned int n, _ftype_t* w, _ftype_t* x);
|
|
static int updateq(unsigned int n, unsigned int xi, _ftype_t* xq, _ftype_t* in);
|
|
static _ftype_t* design_fir(unsigned int *n, _ftype_t* fc, Type type, Window window, _ftype_t opt);
|
|
template<class T> static T firfilter(const T *buf, int pos, int len, int count, const _ftype_t *coefficients)
|
|
{
|
|
int count1, count2;
|
|
|
|
if (pos >= count)
|
|
{
|
|
pos -= count;
|
|
count1 = count; count2 = 0;
|
|
}
|
|
else
|
|
{
|
|
count2 = pos;
|
|
count1 = count - pos;
|
|
pos = len - count1;
|
|
}
|
|
|
|
// high part of window
|
|
const T *ptr = &buf[pos];
|
|
#if 0
|
|
_ftype_t result=0.0;
|
|
while (count1--) result += *ptr++ * *coefficients++;
|
|
// wrapped part of window
|
|
while (count2--) result += *buf++ * *coefficients++;
|
|
return T(result);
|
|
#else
|
|
_ftype_t r1=dotproduct(count1,ptr,coefficients);coefficients+=count1;
|
|
_ftype_t r2=dotproduct(count2,buf,coefficients);
|
|
return T(r1+r2);
|
|
#endif
|
|
}
|
|
};
|
|
|
|
template<> inline TfirFilter::_ftype_t TfirFilter::dotproduct<float,float>(int count,const float *buf,const float *coefficients)
|
|
{
|
|
float sum0=0,sum1=0,sum2=0,sum3=0;
|
|
for (;count>=4;buf+=4,coefficients+=4,count-=4)
|
|
{
|
|
sum0+=buf[0]*coefficients[0];
|
|
sum1+=buf[1]*coefficients[1];
|
|
sum2+=buf[2]*coefficients[2];
|
|
sum3+=buf[3]*coefficients[3];
|
|
}
|
|
while (count--) sum0+= *buf++ * *coefficients++;
|
|
return sum0+sum1+sum2+sum3;
|
|
}
|
|
|
|
#endif
|