⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filterkit.c

📁 asterisk 一个模拟IPPBX的源代码
💻 C
字号:
/**********************************************************************  resamplesubs.c  Real-time library interface by Dominic Mazzoni  Based on resample-1.7:    http://www-ccrma.stanford.edu/~jos/resample/  License: LGPL - see the file LICENSE.txt for more information  This file provides Kaiser-windowed low-pass filter support,  including a function to create the filter coefficients, and  two functions to apply the filter at a particular point.**********************************************************************//* Definitions */#include "resample_defs.h"#include "filterkit.h"#include <stdlib.h>#include <string.h>#include <stdio.h>#include <math.h>/* LpFilter() * * reference: "Digital Filters, 2nd edition" *            R.W. Hamming, pp. 178-179 * * Izero() computes the 0th order modified bessel function of the first kind. *    (Needed to compute Kaiser window). * * LpFilter() computes the coeffs of a Kaiser-windowed low pass filter with *    the following characteristics: * *       c[]  = array in which to store computed coeffs *       frq  = roll-off frequency of filter *       N    = Half the window length in number of coeffs *       Beta = parameter of Kaiser window *       Num  = number of coeffs before 1/frq * * Beta trades the rejection of the lowpass filter against the transition *    width from passband to stopband.  Larger Beta means a slower *    transition and greater stopband rejection.  See Rabiner and Gold *    (Theory and Application of DSP) under Kaiser windows for more about *    Beta.  The following table from Rabiner and Gold gives some feel *    for the effect of Beta: * * All ripples in dB, width of transition band = D*N where N = window length * *               BETA    D       PB RIP   SB RIP *               2.120   1.50  +-0.27      -30 *               3.384   2.23    0.0864    -40 *               4.538   2.93    0.0274    -50 *               5.658   3.62    0.00868   -60 *               6.764   4.32    0.00275   -70 *               7.865   5.0     0.000868  -80 *               8.960   5.7     0.000275  -90 *               10.056  6.4     0.000087  -100 */#define IzeroEPSILON 1E-21               /* Max error acceptable in Izero */static double Izero(double x){   double sum, u, halfx, temp;   int n;   sum = u = n = 1;   halfx = x/2.0;   do {      temp = halfx/(double)n;      n += 1;      temp *= temp;      u *= temp;      sum += u;   } while (u >= IzeroEPSILON*sum);   return(sum);}void lrsLpFilter(double c[], int N, 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<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;      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;   }}float lrsFilterUp(float Imp[],  /* impulse response */                  float ImpD[], /* impulse response deltas */                  UWORD Nwing,  /* len of one wing of filter */                  BOOL Interp,  /* Interpolate coefs using deltas? */                  float *Xp,    /* Current sample */                  double Ph,    /* Phase */                  int Inc)    /* increment (1 for right wing or -1 for left) */{   float *Hp, *Hdp = NULL, *End;   double a = 0;   float v, t;   Ph *= Npc; /* Npc is number of values per 1/delta in impulse response */      v = 0.0; /* The output value */   Hp = &Imp[(int)Ph];   End = &Imp[Nwing];   if (Interp) {      Hdp = &ImpD[(int)Ph];      a = Ph - floor(Ph); /* fractional part of Phase */   }   if (Inc == 1)		/* If doing right wing...              */   {				      /* ...drop extra coeff, so when Ph is  */      End--;			/*    0.5, we don't do too many mult's */      if (Ph == 0)		/* If the phase is zero...           */      {			         /* ...then we've already skipped the */         Hp += Npc;		/*    first sample, so we must also  */         Hdp += Npc;		/*    skip ahead in Imp[] and ImpD[] */      }   }   if (Interp)      while (Hp < End) {         t = *Hp;		/* Get filter coeff */         t += (*Hdp)*a; /* t is now interp'd filter coeff */         Hdp += Npc;		/* Filter coeff differences step */         t *= *Xp;		/* Mult coeff by input sample */         v += t;			/* The filter output */         Hp += Npc;		/* Filter coeff step */         Xp += Inc;		/* Input signal step. NO CHECK ON BOUNDS */      }    else       while (Hp < End) {         t = *Hp;		/* Get filter coeff */         t *= *Xp;		/* Mult coeff by input sample */         v += t;			/* The filter output */         Hp += Npc;		/* Filter coeff step */         Xp += Inc;		/* Input signal step. NO CHECK ON BOUNDS */      }      return v;}float lrsFilterUD(float Imp[],  /* impulse response */                  float ImpD[], /* impulse response deltas */                  UWORD Nwing,  /* len of one wing of filter */                  BOOL Interp,  /* Interpolate coefs using deltas? */                  float *Xp,    /* Current sample */                  double Ph,    /* Phase */                  int Inc,    /* increment (1 for right wing or -1 for left) */                  double dhb) /* filter sampling period */{   float a;   float *Hp, *Hdp, *End;   float v, t;   double Ho;       v = 0.0; /* The output value */   Ho = Ph*dhb;   End = &Imp[Nwing];   if (Inc == 1)		/* If doing right wing...              */   {				      /* ...drop extra coeff, so when Ph is  */      End--;			/*    0.5, we don't do too many mult's */      if (Ph == 0)		/* If the phase is zero...           */         Ho += dhb;		/* ...then we've already skipped the */   }				         /*    first sample, so we must also  */                        /*    skip ahead in Imp[] and ImpD[] */   if (Interp)      while ((Hp = &Imp[(int)Ho]) < End) {         t = *Hp;		/* Get IR sample */         Hdp = &ImpD[(int)Ho];  /* get interp bits from diff table*/         a = Ho - floor(Ho);	  /* a is logically between 0 and 1 */         t += (*Hdp)*a; /* t is now interp'd filter coeff */         t *= *Xp;		/* Mult coeff by input sample */         v += t;			/* The filter output */         Ho += dhb;		/* IR step */         Xp += Inc;		/* Input signal step. NO CHECK ON BOUNDS */      }   else       while ((Hp = &Imp[(int)Ho]) < End) {         t = *Hp;		/* Get IR sample */         t *= *Xp;		/* Mult coeff by input sample */         v += t;			/* The filter output */         Ho += dhb;		/* IR step */         Xp += Inc;		/* Input signal step. NO CHECK ON BOUNDS */      }   return v;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -