1 /*
2 * Copyright (C) 2004-2010 NXP Software
3 * Copyright (C) 2010 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /****************************************************************************************/
19 /* */
20 /* Includes */
21 /* */
22 /****************************************************************************************/
23
24 #include "LVEQNB_Private.h"
25 #include <math.h>
26
27 /****************************************************************************************/
28 /* */
29 /* Defines */
30 /* */
31 /****************************************************************************************/
32
33 #define PI 3.14159265358979
34
35 /****************************************************************************************/
36 /* */
37 /* FUNCTION: LVEQNB_DoublePrecCoefs */
38 /* */
39 /* DESCRIPTION: */
40 /* Calculate double precision coefficients for a peaking filter */
41 /* */
42 /* PARAMETERS: */
43 /* Fs Sampling frequency index */
44 /* pFilterDefinition Pointer to the filter definition */
45 /* pCoefficients Pointer to the coefficients */
46 /* */
47 /* RETURNS: */
48 /* LVEQNB_SUCCESS Always succeeds */
49 /* */
50 /* NOTES: */
51 /* 1. The equations used are as follows: */
52 /* */
53 /* G = 10^(GaindB/20) - 1 */
54 /* t0 = 2 * Pi * Fc / Fs */
55 /* D = 1 if GaindB >= 0 */
56 /* D = 1 / (1 + G) if GaindB < 0 */
57 /* */
58 /* b2 = -0.5 * (2Q - D * t0) / (2Q + D * t0) */
59 /* b1 = (0.5 - b2) * (1 - coserr(t0)) */
60 /* a0 = (0.5 + b2) / 2 */
61 /* */
62 /* Where: */
63 /* GaindB is the gain in dBs, range -15dB to +15dB */
64 /* Fc is the centre frequency, DC to Fs/50 */
65 /* Fs is the sample frequency, 8000 to 48000 in descrete steps */
66 /* Q is the Q factor, 0.25 to 12 (represented by 25 to 1200) */
67 /* */
68 /* 2. The double precision coefficients are only used when fc is less than fs/85, so */
69 /* the cosine of t0 is always close to 1.0. Instead of calculating the cosine */
70 /* itself the difference from the value 1.0 is calculated, this can be done with */
71 /* lower precision maths. */
72 /* */
73 /* 3. The value of the B2 coefficient is only calculated as a single precision value, */
74 /* small errors in this value have a combined effect on the Q and Gain but not the */
75 /* the frequency of the filter. */
76 /* */
77 /****************************************************************************************/
78
79 /****************************************************************************************/
80 /* */
81 /* FUNCTION: LVEQNB_SinglePrecCoefs */
82 /* */
83 /* DESCRIPTION: */
84 /* Calculate single precision coefficients for a peaking filter */
85 /* */
86 /* PARAMETERS: */
87 /* Fs Sampling frequency index */
88 /* pFilterDefinition Pointer to the filter definition */
89 /* pCoefficients Pointer to the coefficients */
90 /* */
91 /* RETURNS: */
92 /* LVEQNB_SUCCESS Always succeeds */
93 /* */
94 /* NOTES: */
95 /* 1. The equations used are as follows: */
96 /* */
97 /* G = 10^(GaindB/20) - 1 */
98 /* t0 = 2 * Pi * Fc / Fs */
99 /* D = 1 if GaindB >= 0 */
100 /* D = 1 / (1 + G) if GaindB < 0 */
101 /* */
102 /* b2 = -0.5 * (2Q - D * t0) / (2Q + D * t0) */
103 /* b1 = (0.5 - b2) * cos(t0) */
104 /* a0 = (0.5 + b2) / 2 */
105 /* */
106 /* Where: */
107 /* GaindB is the gain in dBs, range -15dB to +15dB */
108 /* Fc is the centre frequency, DC to Nyquist */
109 /* Fs is the sample frequency, 8000 to 48000 in descrete steps */
110 /* Q is the Q factor, 0.25 to 12 */
111 /* */
112 /****************************************************************************************/
113
LVEQNB_SinglePrecCoefs(LVM_UINT16 Fs,LVEQNB_BandDef_t * pFilterDefinition,PK_FLOAT_Coefs_t * pCoefficients)114 LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16 Fs,
115 LVEQNB_BandDef_t *pFilterDefinition,
116 PK_FLOAT_Coefs_t *pCoefficients)
117 {
118
119 extern LVM_FLOAT LVEQNB_GainTable[];
120 extern LVM_FLOAT LVEQNB_TwoPiOnFsTable[];
121 extern LVM_FLOAT LVEQNB_DTable[];
122
123 /*
124 * Get the filter definition
125 */
126 LVM_INT16 Gain = pFilterDefinition->Gain;
127 LVM_UINT16 Frequency = pFilterDefinition->Frequency;
128 /* As mentioned in effectbundle.h */
129 LVM_FLOAT QFactor = (LVM_FLOAT)pFilterDefinition->QFactor / 100.0f;
130
131 /*
132 * Intermediate variables and temporary values
133 */
134 LVM_FLOAT T0;
135 LVM_FLOAT D;
136 LVM_FLOAT A0;
137 LVM_FLOAT B1;
138 LVM_FLOAT B2;
139
140 /*
141 * Calculating the intermediate values
142 */
143 T0 = Frequency * LVEQNB_TwoPiOnFsTable[Fs]; /* T0 = 2 * Pi * Fc / Fs */
144 if (Gain >= 0)
145 {
146 D = LVEQNB_DTable[15]; /* D = 1 if GaindB >= 0 */
147 }
148 else
149 {
150 D = LVEQNB_DTable[Gain + 15]; /* D = 1 / (1 + G) if GaindB < 0 */
151 }
152
153 /*
154 * Calculate the B2,B1,A0 coefficients
155 */
156 B2 = -0.5 * (2 * QFactor - D * T0) / (2 * QFactor + D * T0);
157 B1 = (0.5 - B2) * cos(T0);
158 A0 = (0.5 + B2) / 2.0;
159
160 /*
161 * Write coeff into the data structure
162 */
163 /* all the coefficients are multiplied with 2 to make them align with fixed point values*/
164 pCoefficients->A0 = 2 * A0;
165 pCoefficients->B1 = 2 * B1;
166 pCoefficients->B2 = 2 * B2;
167 pCoefficients->G = LVEQNB_GainTable[Gain + 15];
168
169 return(LVEQNB_SUCCESS);
170 }
171