Ejemplo n.º 1
0
static void CalculateKBDWindow(float* win, float alpha, int length)
{
    int i;
    float IBeta;
    float tmp;
    float sum = 0.0;

    alpha *= PI;
    IBeta = 1.0f/Izero(alpha);

    /* calculate lower half of Kaiser Bessel window */
    for(i=0; i<(length>>1); i++) {
        tmp = 4.0f*(float)i/(float)length - 1.0f;
        win[i] = Izero(alpha*(float)sqrt(1.0f-tmp*tmp))*IBeta;
        sum += win[i];
    }

    sum = 1.0f/sum;
    tmp = 0.0f;

    /* calculate lower half of window */
    for(i=0; i<(length>>1); i++) {
        tmp += win[i];
        win[i] = (float)sqrt(tmp*sum);
    }
}
Ejemplo n.º 2
0
void LpFilter(double c[], int N, double frq, double Beta, int Num)
{
   double IBeta, temp, inm1;
   int i;

   /* Calculate ideal lowpass filter impulse response coefficients: */
   c[0] = 2.0*frq;
   for (i=1; i<N; i++) {
       temp = PI*(double)i/(double)Num;
       c[i] = sin(2.0*temp*frq)/temp; /* Analog sinc function, cutoff = frq */
   }

   /* 
    * Calculate and Apply Kaiser window to ideal lowpass filter.
    * Note: last window value is IBeta which is NOT zero.
    * You're supposed to really truncate the window here, not ramp
    * it to zero. This helps reduce the first sidelobe. 
    */
   IBeta = 1.0/Izero(Beta);
   inm1 = 1.0/((double)(N-1));
   for (i=1; i<N; i++) {
       temp = (double)i * inm1;
       c[i] *= Izero(Beta*sqrt(1.0-temp*temp)) * IBeta;
   }
}
Ejemplo n.º 3
0
void CResample::lrsLpFilter(double c[], int Nf, double frq, double Beta, int Num)
{
   double IBeta, temp, temp1, inm1;
   int i;

   /* Calculate ideal lowpass filter impulse response coefficients: */
   c[0] = 2.0*frq;
   for (i=1; i<Nf; i++) {
      temp = PI*(double)i/(double)Num;
      c[i] = sin(2.0*temp*frq)/temp; /* Analog sinc function, cutoff = frq */
   }

   /*
    * Calculate and Apply Kaiser window to ideal lowpass filter.
    * Note: last window value is IBeta which is NOT zero.
    * You're supposed to really truncate the window here, not ramp
    * it to zero. This helps reduce the first sidelobe.
    */
   IBeta = 1.0/Izero(Beta);
   inm1 = 1.0/((double)(Nf-1));
   for (i=1; i<Nf; i++) {
      temp = (double)i * inm1;
      temp1 = 1.0 - temp*temp;
      temp1 = (temp1<0? 0: temp1); /* make sure it's not negative since
                                      we're taking the square root - this
                                      happens on Pentium 4's due to tiny
                                      roundoff errors */
      c[i] *= Izero(Beta*sqrt(temp1)) * IBeta;
   }
}
Ejemplo n.º 4
0
/*
 * KaiserLowpass() creates a Kaiser-windowed lowpass filter.
 *
 * length is length of filter wing.
 * cutoff is normalized cutoff freq (-6dB down).
 * beta is the Kaiser window parameter.
 * gain is the desired dc gain.
 *
 * The Kaiser window is given by:
 * w[n] = Io(beta * sqrt(1 - (n/M)^2)) / Io(beta)	(0 <= n <= M)
 *
 * Note: sampling of the "analog" lowpass is offset by 0.5 sample,
 * so that all phases are an even length.
 */
void 
KaiserLowpass(int length, float cutoff, float beta, float gain, double *filter)
{
	double ibeta, ilength, x, w;
	int i;

	ibeta = 1.0 / Izero(beta);
	ilength = 1.0 / (length - 0.5);		/* last window value should be ibeta */

	for (i = 0; i < length; i++) {
		x = i + 0.5;

		/* Kaiser window */
		w = x * ilength;
		w = 1.0 - w * w;
		w = MAX(w, 0.0);
		w = Izero(beta * sqrt(w)) * ibeta;

		/* windowed ideal lowpass filter */
		filter[i] = w * gain * sin(cutoff * M_PI * x) / (M_PI * x);
	}
}
Ejemplo n.º 5
0
static void LpFilter(double *c, long N, double frq, double Beta, long Num)
{
   long i;

   /* Calculate filter coeffs: */
   c[0] = frq;
   for (i=1; i<N; i++) {
      double x = M_PI*(double)i/(double)(Num);
      c[i] = sin(x*frq)/x;
   }
  
   if (Beta>2) { /* Apply Kaiser window to filter coeffs: */
      double IBeta = 1.0/Izero(Beta);
      for (i=1; i<N; i++) {
         double x = (double)i / (double)(N);
         c[i] *= Izero(Beta*sqrt(1.0-x*x)) * IBeta;
      }
   } else { /* Apply Nuttall window: */
      for(i = 0; i < N; i++) {
         double x = M_PI*i / N;
         c[i] *= 0.36335819 + 0.4891775*cos(x) + 0.1365995*cos(2*x) + 0.0106411*cos(3*x);
      }
   }
}
Ejemplo n.º 6
0
////////////////////////////////////////////////////////////////////
// Create a FIR high Pass filter with scaled amplitude 'Scale'
// NumTaps if non-zero, forces filter design to be this number of taps
// Astop = Stopband Atenuation in dB (ie 40dB is 40dB stopband attenuation)
// Fpass = Highpass passband frequency in Hz
// Fstop = Highpass stopband frequency in Hz
// Fsamprate = Sample Rate in Hz
//
//  Apass              -------------
//                    /
//                   /
//                  /
//                 /
//  Astop ---------
//            Fstop   Fpass
////////////////////////////////////////////////////////////////////
int CFir::InitHPFilter(int NumTaps, TYPEREAL Scale, TYPEREAL Astop, TYPEREAL Fpass, TYPEREAL Fstop, TYPEREAL Fsamprate)
{
int n;
TYPEREAL Beta;
	//m_Mutex.lock();
	m_SampleRate = Fsamprate;
	//create normalized frequency parameters
	TYPEREAL normFpass = Fpass/Fsamprate;
	TYPEREAL normFstop = Fstop/Fsamprate;
	TYPEREAL normFcut = (normFstop + normFpass)/2.0;	//high pass filter 6dB cutoff

	//calculate Kaiser-Bessel window shape factor, Beta, from stopband attenuation
	if(Astop < 20.96)
		Beta = 0;
	else if(Astop >= 50.0)
		Beta = .1102 * (Astop - 8.71);
	else
		Beta = .5842 * pow( (Astop-20.96), 0.4) + .07886 * (Astop - 20.96);

	//Now Estimate number of filter taps required based on filter specs
	m_NumTaps = (Astop - 8.0) / (2.285*K_2PI*(normFpass - normFstop ) ) + 1;

	//clamp range of filter taps
	if(m_NumTaps>(MAX_NUMCOEF-1) )
		m_NumTaps = MAX_NUMCOEF-1;
	if(m_NumTaps < 3)
		m_NumTaps = 3;

	m_NumTaps |= 1;		//force to next odd number

	if(NumTaps)	//if need to force to to a number of taps
		m_NumTaps = NumTaps;

	TYPEREAL izb = Izero(Beta);		//precalculate denominator since is same for all points
	TYPEREAL fCenter = .5*(TYPEREAL)(m_NumTaps-1);
	for( n=0; n < m_NumTaps; n++)
	{
		TYPEREAL x = (TYPEREAL)n - (TYPEREAL)(m_NumTaps-1)/2.0;
		TYPEREAL c;
		// create ideal Sinc() HP filter with normFcut
		if( (TYPEREAL)n == fCenter )	//deal with odd size filter singularity where sin(0)/0==1
			c = 1.0 - 2.0 * normFcut;
		else
			c = (TYPEREAL) (sin(K_PI*x)/(K_PI*x) - sin(K_2PI*x*normFcut)/(K_PI*x) );

		//calculate Kaiser window and multiply to get coefficient
		x = ((TYPEREAL)n - ((TYPEREAL)m_NumTaps-1.0)/2.0 ) / (((TYPEREAL)m_NumTaps-1.0)/2.0);
		m_Coef[n] = Scale * c * Izero( Beta * sqrt(1 - (x*x) ) )  / izb;
	}

	//make a 2x length array for FIR flat calculation efficiency
	for (n = 0; n < m_NumTaps; n++)
		m_Coef[n+m_NumTaps] = m_Coef[n];

	//copy into complex coef buffers
	for (n = 0; n < m_NumTaps*2; n++)
	{
		m_ICoef[n] = m_Coef[n];
		m_QCoef[n] = m_Coef[n];
	}

	//Initialize the FIR buffers and state
	for(int i=0; i<m_NumTaps; i++)
	{
		m_rZBuf[i] = 0.0;
		m_cZBuf[i].re = 0.0;
		m_cZBuf[i].im = 0.0;
	}
	m_State = 0;

	//m_Mutex.unlock();


#if 0		//debug hack to write m_Coef to a file for analysis
	QDir::setCurrent("d:/");
	QFile File;
	File.setFileName("hpcoef.txt");
	if(File.open(QIODevice::WriteOnly))
	{
		qDebug()<<"file Opened OK";
		char Buf[256];
		for(n=0; n<m_NumTaps; n++)
		{
			sprintf( Buf, "%g\r\n", m_Coef[n]);
			File.write(Buf);
		}
	}
	else
		qDebug()<<"file Failed to Open";
	qDebug()<<"HP taps="<<m_NumTaps;
#endif
	return m_NumTaps;
}