📄 filter.c
字号:
#include <stdlib.h>
#include <math.h>
/**************************************************************************
FILTER.C - Source code for realtime filter functions:
fir_filter FIR filter floats sample by sample (real time)
iir_filter IIR filter floats sample by sample (real time)
gaussian Generate Gaussian noise
*************************************************************************/
/**************************************************************************
fir_filter - Perform fir filtering sample by sample on floats
Requires array of filter coefficients and pointer to history.
Returns one output sample for each input sample.
float fir_filter(float input,float *coef,int n,float *history)
float input new float input sample
float *coef pointer to filter coefficients
int n number of coefficients in filter
float *history history array pointer
Returns float value giving the current output.
*************************************************************************/
float fir_filter(float input,float *coef,int n,float *history)
{
int i;
float *hist_ptr,*hist1_ptr,*coef_ptr;
float output;
hist_ptr = history;
hist1_ptr = hist_ptr; /* use for history update */
coef_ptr = coef + n - 1; /* point to last coef */
/* form output accumulation */
output = *hist_ptr++ * (*coef_ptr--);
for(i = 2 ; i < n ; i++) {
*hist1_ptr++ = *hist_ptr; /* update history array */
output += (*hist_ptr++) * (*coef_ptr--);
}
output += input * (*coef_ptr); /* input tap */
*hist1_ptr = input; /* last history */
return(output);
}
/**************************************************************************
iir_filter - Perform IIR filtering sample by sample on floats
Implements cascaded direct form II second order sections.
Requires arrays for history and coefficients.
The length (n) of the filter specifies the number of sections.
The size of the history array is 2*n.
The size of the coefficient array is 4*n + 1 because
the first coefficient is the overall scale factor for the filter.
Returns one output sample for each input sample.
float iir_filter(float input,float *coef,int n,float *history)
float input new float input sample
float *coef pointer to filter coefficients
int n number of sections in filter
float *history history array pointer
Returns float value giving the current output.
*************************************************************************/
float iir_filter(float input,float *coef,int n,float *history)
{
int i;
float *hist1_ptr,*hist2_ptr,*coef_ptr;
float output,new_hist,history1,history2;
coef_ptr = coef; /* coefficient pointer */
hist1_ptr = history; /* first history */
hist2_ptr = hist1_ptr + 1; /* next history */
output = input * (*coef_ptr++); /* overall input scale factor */
for(i = 0 ; i < n ; i++) {
history1 = *hist1_ptr; /* history values */
history2 = *hist2_ptr;
output = output - history1 * (*coef_ptr++);
new_hist = output - history2 * (*coef_ptr++); /* poles */
output = new_hist + history1 * (*coef_ptr++);
output = output + history2 * (*coef_ptr++); /* zeros */
*hist2_ptr++ = *hist1_ptr;
*hist1_ptr++ = new_hist;
hist1_ptr++;
hist2_ptr++;
}
return(output);
}
/**************************************************************************
gaussian - generates zero mean unit variance Gaussian random numbers
Returns one zero mean unit variance Gaussian random numbers as a double.
Uses the Box-Muller transformation of two uniform random numbers to
Gaussian random numbers.
float gaussian()
*************************************************************************/
float gaussian()
{
static int ready = 0; /* flag to indicated stored value */
static float gstore; /* place to store other value */
static float rconst1 = (float)(2.0/RAND_MAX);
static float rconst2 = (float)(RAND_MAX/2.0);
float v1,v2,r,fac;
float gaus;
/* make two numbers if none stored */
if(ready == 0) {
do {
v1 = (float)rand() - rconst2;
v2 = (float)rand() - rconst2;
v1 *= rconst1;
v2 *= rconst1;
r = v1*v1 + v2*v2;
} while(r > 1.0f); /* make radius less than 1 */
/* remap v1 and v2 to two Gaussian numbers */
fac = sqrt(-2.0f*log(r)/r);
gstore = v1*fac; /* store one */
gaus = v2*fac; /* return one */
ready = 1; /* set ready flag */
}
else {
ready = 0; /* reset ready flag for next pair */
gaus = gstore; /* return the stored one */
}
return(gaus);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -