1 /*
2  * lingot, a musical instrument tuner.
3  *
4  * Copyright (C) 2004-2018  Iban Cereijo.
5  * Copyright (C) 2004-2008  Jairo Chapela.
6 
7  *
8  * This file is part of lingot.
9  *
10  * lingot is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * lingot is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with lingot; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24 
25 #include <memory.h>
26 #include <math.h>
27 
28 #include "lingot-complex.h"
29 #include "lingot-filter.h"
30 
31 #define max(a,b) (((a)<(b))?(b):(a))
32 
33 // given each polynomial order and coefs, with optional initial status.
lingot_filter_new(LingotFilter * filter,unsigned int Na,unsigned int Nb,const FLT * a,const FLT * b)34 void lingot_filter_new(LingotFilter* filter, unsigned int Na, unsigned int Nb, const FLT* a,
35 		const FLT* b) {
36 	unsigned int i;
37 	filter->N = max(Na, Nb);
38 
39 	filter->a = malloc((filter->N + 1) * sizeof(FLT));
40 	filter->b = malloc((filter->N + 1) * sizeof(FLT));
41 	filter->s = malloc((filter->N + 1) * sizeof(FLT));
42 
43 	for (i = 0; i <= filter->N; i++) {
44 		filter->a[i] = 0.0;
45 		filter->b[i] = 0.0;
46 		filter->s[i] = 0.0;
47 	}
48 
49 	memcpy(filter->a, a, (Na + 1) * sizeof(FLT));
50 	memcpy(filter->b, b, (Nb + 1) * sizeof(FLT));
51 
52 	for (i = 0; i <= filter->N; i++) {
53 		filter->a[i] /= a[0]; // polynomial normalization.
54 		filter->b[i] /= a[0];
55 	}
56 }
57 
lingot_filter_reset(LingotFilter * filter)58 void lingot_filter_reset(LingotFilter* filter) {
59 	unsigned int i;
60 	for (i = 0; i <= filter->N; i++) {
61 		filter->s[i] = 0.0;
62 	}
63 }
64 
lingot_filter_destroy(LingotFilter * filter)65 void lingot_filter_destroy(LingotFilter* filter) {
66 	free(filter->a);
67 	free(filter->b);
68 	free(filter->s);
69 }
70 
71 // Digital Filter Implementation II, in & out can overlap.
lingot_filter_filter(LingotFilter * filter,unsigned int n,const FLT * in,FLT * out)72 void lingot_filter_filter(LingotFilter* filter, unsigned int n, const FLT* in,
73 		FLT* out) {
74 	FLT w, y;
75 	register unsigned int i;
76 	register int j;
77 
78 	for (i = 0; i < n; i++) {
79 
80 		w = in[i];
81 		y = 0.0;
82 
83 		for (j = filter->N - 1; j >= 0; j--) {
84 			w -= filter->a[j + 1] * filter->s[j];
85 			y += filter->b[j + 1] * filter->s[j];
86 			filter->s[j + 1] = filter->s[j];
87 		}
88 
89 		y += w * filter->b[0];
90 		filter->s[0] = w;
91 
92 		out[i] = y;
93 	}
94 }
95 
96 // single sample filtering
lingot_filter_filter_sample(LingotFilter * filter,FLT in)97 FLT lingot_filter_filter_sample(LingotFilter* filter, FLT in) {
98 	FLT result;
99 
100 	lingot_filter_filter(filter, 1, &in, &result);
101 	return result;
102 }
103 
104 // vector prod
lingot_filter_vector_product(int n,LingotComplex * vector,LingotComplex result)105 void lingot_filter_vector_product(int n, LingotComplex* vector,
106 		LingotComplex result) {
107 	register int i;
108 	LingotComplex aux1;
109 
110 	result[0] = 1.0;
111 	result[1] = 0.0;
112 
113 	for (i = 0; i < n; i++) {
114 		aux1[0] = -vector[i][0];
115 		aux1[1] = -vector[i][1];
116 		lingot_complex_mul_by(result, aux1);
117 	}
118 
119 }
120 
121 // Chebyshev filters
lingot_filter_cheby_design(LingotFilter * filter,unsigned int n,FLT Rp,FLT wc)122 void lingot_filter_cheby_design(LingotFilter* filter, unsigned int n, FLT Rp, FLT wc) {
123 	unsigned int i; // loops
124 	unsigned int k;
125 	unsigned int p;
126 
127 	FLT a[n + 1];
128 	FLT b[n + 1];
129 
130 	FLT new_a[n + 1];
131 	FLT new_b[n + 1];
132 
133 	// locate poles
134 	LingotComplex pole[n];
135 
136 	for (i = 0; i < n; i++) {
137 		pole[i][0] = 0.0;
138 		pole[i][1] = 0.0;
139 	}
140 
141 	FLT T = 2.0;
142 	// 2Hz
143 	FLT W = 2.0 / T * tan(M_PI * wc / T);
144 
145 	FLT epsilon = sqrt(pow(10.0, 0.1 * Rp) - 1);
146 	FLT v0 = asinh(1 / epsilon) / n;
147 
148 	FLT sv0 = sinh(v0);
149 	FLT cv0 = cosh(v0);
150 
151 	FLT t;
152 
153 	for (i = -(n - 1), k = 0; k < n; i += 2, k++) {
154 		t = M_PI * i / (2.0 * n);
155 		pole[k][0] = -sv0 * cos(t);
156 		pole[k][1] = cv0 * sin(t);
157 	}
158 
159 	LingotComplex gain;
160 	lingot_filter_vector_product(n, pole, gain);
161 
162 	if ((n & 1) == 0) { // even
163 		FLT f = pow(10.0, -0.05 * Rp);
164 		gain[0] *= f;
165 		gain[1] *= f;
166 	}
167 
168 	FLT f = pow(W, n);
169 	gain[0] *= f;
170 	gain[1] *= f;
171 
172 	for (i = 0; i < n; i++) {
173 		pole[i][0] *= W;
174 		pole[i][1] *= W;
175 	}
176 
177 	// bilinear transform
178 	LingotComplex sp[n];
179 
180 	for (i = 0; i < n; i++) {
181 		sp[i][0] = (2.0 - pole[i][0] * T) / T;
182 		sp[i][1] = (0.0 - pole[i][1] * T) / T;
183 	}
184 
185 	LingotComplex tmp1;
186 	LingotComplex aux2;
187 
188 	lingot_filter_vector_product(n, sp, tmp1);
189 
190 	lingot_complex_div_by(gain, tmp1);
191 
192 	for (i = 0; i < n; i++) {
193 		tmp1[0] = (2.0 + pole[i][0] * T);
194 		tmp1[1] = (0.0 + pole[i][1] * T);
195 		aux2[0] = (2.0 - pole[i][0] * T);
196 		aux2[1] = (0.0 - pole[i][1] * T);
197 		lingot_complex_div(tmp1, aux2, pole[i]);
198 	}
199 
200 	// compute filter coefficients from pole/zero values
201 	a[0] = 1.0;
202 	b[0] = 1.0;
203 	new_a[0] = 1.0;
204 	new_b[0] = 1.0;
205 
206 	for (i = 1; i <= n; i++) {
207 		a[i] = 0.0;
208 		b[i] = 0.0;
209 		new_a[i] = 0.0;
210 		new_b[i] = 0.0;
211 	}
212 
213 	if (n & 1) {  // odd
214 		// first subfilter is first order
215 		a[1] = -pole[n / 2][0];
216 		b[1] = 1.0;
217 	}
218 
219 	// iterate over the conjugate pairs
220 	for (p = 0; p < n / 2; p++) {
221 		FLT b1 = 2.0;
222 		FLT b2 = 1.0;
223 
224 		FLT a1 = -2.0 * pole[p][0];
225 		FLT a2 = pole[p][0] * pole[p][0] + pole[p][1] * pole[p][1];
226 
227 		// 2nd order subfilter per each pair
228 		new_a[1] = a[1] + a1 * a[0];
229 		new_b[1] = b[1] + b1 * b[0];
230 
231 		// poly multiplication
232 		for (i = 2; i <= n; i++) {
233 			new_a[i] = a[i] + a1 * a[i - 1] + a2 * a[i - 2];
234 			new_b[i] = b[i] + b1 * b[i - 1] + b2 * b[i - 2];
235 		}
236 		for (i = 1; i <= n; i++) {
237 			a[i] = new_a[i];
238 			b[i] = new_b[i];
239 		}
240 	}
241 
242 	gain[0] = fabs(gain[0]);
243 	for (i = 0; i <= n; i++) {
244 		b[i] *= gain[0];
245 	}
246 
247 	lingot_filter_new(filter, n, n, a, b);
248 }
249