To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at https://github.com/sonic-visualiser/sv-dependency-builds .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / src / portaudio_20161030_catalina_patch / qa / loopback / src / biquad_filter.c @ 164:9fa11135915a

History | View | Annotate | Download (3.34 KB)

1
#include <math.h>
2
#include <string.h>
3

    
4
#include "biquad_filter.h"
5

    
6
/**
7
 *        Unit_BiquadFilter implements a second order IIR filter. 
8
        Here is the equation that we use for this filter:
9
     y(n) = a0*x(n) + a1*x(n-1)  + a2*x(n-2) - b1*y(n-1)  - b2*y(n-2)
10
 *
11
 * @author (C) 2002 Phil Burk, SoftSynth.com, All Rights Reserved
12
 */
13

    
14
#define FILTER_PI  (3.141592653589793238462643)
15
/***********************************************************
16
** Calculate coefficients common to many parametric biquad filters.
17
*/
18
static void BiquadFilter_CalculateCommon( BiquadFilter *filter, double ratio, double Q )
19
{
20
        double omega;
21
        
22
        memset( filter, 0, sizeof(BiquadFilter) );
23

    
24
/* Don't let frequency get too close to Nyquist or filter will blow up. */
25
        if( ratio >= 0.499 ) ratio = 0.499; 
26
        omega = 2.0 * (double)FILTER_PI * ratio;
27

    
28
        filter->cos_omega = (double) cos( omega );
29
        filter->sin_omega = (double) sin( omega );
30
        filter->alpha = filter->sin_omega / (2.0 * Q);
31
}
32

    
33
/*********************************************************************************
34
 ** Calculate coefficients for Highpass filter.
35
 */
36
void BiquadFilter_SetupHighPass( BiquadFilter *filter, double ratio, double Q )
37
{
38
        double    scalar, opc;
39
        
40
        if( ratio  < BIQUAD_MIN_RATIO )  ratio  = BIQUAD_MIN_RATIO;
41
        if( Q < BIQUAD_MIN_Q ) Q = BIQUAD_MIN_Q;
42
        
43
        BiquadFilter_CalculateCommon( filter, ratio, Q );
44
        
45
        scalar = 1.0 / (1.0 + filter->alpha);
46
        opc = (1.0 + filter->cos_omega);
47
        
48
        filter->a0 = opc * 0.5 * scalar;
49
        filter->a1 =  - opc * scalar;
50
    filter->a2 = filter->a0;
51
        filter->b1 = -2.0 * filter->cos_omega * scalar;
52
        filter->b2 = (1.0 - filter->alpha) * scalar;
53
}
54

    
55

    
56
/*********************************************************************************
57
 ** Calculate coefficients for Notch filter.
58
 */
59
void BiquadFilter_SetupNotch( BiquadFilter *filter, double ratio, double Q )
60
{
61
        double    scalar, opc;
62
        
63
        if( ratio  < BIQUAD_MIN_RATIO )  ratio  = BIQUAD_MIN_RATIO;
64
        if( Q < BIQUAD_MIN_Q ) Q = BIQUAD_MIN_Q;
65
        
66
        BiquadFilter_CalculateCommon( filter, ratio, Q );
67
        
68
        scalar = 1.0 / (1.0 + filter->alpha);
69
        opc = (1.0 + filter->cos_omega);
70
        
71
        filter->a0 = scalar;
72
        filter->a1 =  -2.0 * filter->cos_omega * scalar;
73
    filter->a2 = filter->a0;
74
        filter->b1 = filter->a1;
75
        filter->b2 = (1.0 - filter->alpha) * scalar;
76
}
77

    
78
/*****************************************************************
79
** Perform core IIR filter calculation without permutation.
80
*/
81
void BiquadFilter_Filter( BiquadFilter *filter, float *inputs, float *outputs, int numSamples )
82
{
83
        int i;
84
    double xn, yn;
85
        // Pull values from structure to speed up the calculation.
86
        double a0 = filter->a0;
87
        double a1 = filter->a1;
88
        double a2 = filter->a2;
89
        double b1 = filter->b1;
90
        double b2 = filter->b2;
91
        double xn1 = filter->xn1;
92
        double xn2 = filter->xn2;
93
        double yn1 = filter->yn1;
94
        double yn2 = filter->yn2;
95

    
96
        for( i=0; i<numSamples; i++)
97
        {
98
                // Generate outputs by filtering inputs.
99
                xn = inputs[i];
100
                yn = (a0 * xn) + (a1 * xn1) + (a2 * xn2) - (b1 * yn1) - (b2 * yn2);
101
                outputs[i] = yn;
102

    
103
                // Delay input and output values.
104
        xn2 = xn1;
105
        xn1 = xn;
106
        yn2 = yn1;
107
        yn1 = yn;
108
                
109
                if( (i & 7) == 0 )
110
                {
111
                        // Apply a small bipolar impulse to filter to prevent arithmetic underflow.
112
                        // Underflows can cause the FPU to interrupt the CPU.
113
                        yn1 += (double) 1.0E-26;
114
                        yn2 -= (double) 1.0E-26;
115
                }
116
        }
117
        
118
        filter->xn1 = xn1;
119
        filter->xn2 = xn2;
120
        filter->yn1 = yn1;
121
        filter->yn2 = yn2;                
122
}