Deleted Added
full compact
feeder_rate_mkfilter.awk (195283) feeder_rate_mkfilter.awk (195378)
1#!/usr/bin/awk -f
2#
3# Copyright (c) 2007-2009 Ariff Abdullah <ariff@FreeBSD.org>
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
1#!/usr/bin/awk -f
2#
3# Copyright (c) 2007-2009 Ariff Abdullah <ariff@FreeBSD.org>
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD: head/sys/tools/sound/feeder_rate_mkfilter.awk 195283 2009-07-02 10:02:10Z ariff $
27# $FreeBSD: head/sys/tools/sound/feeder_rate_mkfilter.awk 195378 2009-07-05 18:15:06Z ariff $
28#
29
30#
31# FIR filter design by windowing method. This might become one of the
32# funniest joke I've ever written due to too many tricks being applied to
33# ensure maximum precision (well, in fact this is already have the same
34# precision granularity compared to its C counterpart). Nevertheless, it's
35# working, precise, dynamically tunable based on "presets".
36#
37# XXX EXPECT TOTAL REWRITE! DON'T ARGUE!
38#
39# TODO: Using ultraspherical window might be a good idea.
40#
41# Based on:
42#
43# "Digital Audio Resampling" by Julius O. Smith III
44#
45# - http://ccrma.stanford.edu/~jos/resample/
46#
47
48#
49# Some basic Math functions.
50#
51function abs(x)
52{
53 return (((x < 0) ? -x : x) + 0);
54}
55
56function fabs(x)
57{
58 return (((x < 0.0) ? -x : x) + 0.0);
59}
60
61function ceil(x, r)
62{
63 r = int(x);
64 if (r < x)
65 r++;
66 return (r + 0);
67}
68
69function floor(x, r)
70{
71 r = int(x);
72 if (r > x)
73 r--;
74 return (r + 0);
75}
76
77function pow(x, y)
78{
79 return (exp(1.0 * y * log(1.0 * x)));
80}
81
82#
83# What the hell...
84#
85function shl(x, y)
86{
87 while (y > 0) {
88 x *= 2;
89 y--;
90 }
91 return (x);
92}
93
94function shr(x, y)
95{
96 while (y > 0 && x != 0) {
97 x = floor(x / 2);
98 y--;
99 }
100 return (x);
101}
102
103function fx_floor(v, o, r)
104{
105 if (fabs(v) < fabs(smallest))
106 smallest = v;
107 if (fabs(v) > fabs(largest))
108 largest = v;
109
110 r = floor((v * o) + 0.5);
111 if (r < INT32_MIN || r > INT32_MAX)
112 printf("\n#error overflow v=%f, please reduce %d\n", v, o);
113
114 return (r);
115}
116
117#
118# Kaiser linear piecewise functions.
119#
120function kaiserAttn2Beta(attn, beta)
121{
122 if (attn < 0.0)
123 return (Z_KAISER_BETA_DEFAULT);
124
125 if (attn > 50.0)
126 beta = 0.1102 * ((1.0 * attn) - 8.7);
127 else if (attn > 21.0)
128 beta = (0.5842 * pow((1.0 * attn) - 21.0, 0.4)) + \
129 (0.07886 * ((1.0 * attn) - 21.0));
130 else
131 beta = 0.0;
132
133 return (beta);
134}
135
136function kaiserBeta2Attn(beta, x, y, i, attn, xbeta)
137{
138 if (beta < Z_WINDOW_KAISER)
139 return (Z_KAISER_ATTN_DEFAULT);
140
141 if (beta > kaiserAttn2Beta(50.0))
142 attn = ((1.0 * beta) / 0.1102) + 8.7;
143 else {
144 x = 21.0;
145 y = 50.0;
146 attn = 0.5 * (x + y);
147 for (i = 0; i < 128; i++) {
148 xbeta = kaiserAttn2Beta(attn)
149 if (beta == xbeta || \
150 (i > 63 && \
151 fabs(beta - xbeta) < Z_KAISER_EPSILON))
152 break;
153 if (beta > xbeta)
154 x = attn;
155 else
156 y = attn;
157 attn = 0.5 * (x + y);
158 }
159 }
160
161 return (attn);
162}
163
164function kaiserRolloff(len, attn)
165{
166 return (1.0 - (((1.0 * attn) - 7.95) / (((1.0 * len) - 1.0) * 14.36)));
167}
168
169#
170# 0th order modified Bessel function of the first kind.
171#
172function I0(x, s, u, n, h, t)
173{
174 s = n = u = 1.0;
175 h = x * 0.5;
176
177 do {
178 t = h / n;
179 n += 1.0;
180 t *= t;
181 u *= t;
182 s += u;
183 } while (u >= (I0_EPSILON * s));
184
185 return (s);
186}
187
188function wname(beta)
189{
190 if (beta >= Z_WINDOW_KAISER)
191 return ("Kaiser");
192 else if (beta == Z_WINDOW_BLACKMAN_NUTTALL)
193 return ("Blackman - Nuttall");
194 else if (beta == Z_WINDOW_NUTTALL)
195 return ("Nuttall");
196 else if (beta == Z_WINDOW_BLACKMAN_HARRIS)
197 return ("Blackman - Harris");
198 else if (beta == Z_WINDOW_BLACKMAN)
199 return ("Blackman");
200 else if (beta == Z_WINDOW_HAMMING)
201 return ("Hamming");
202 else if (beta == Z_WINDOW_HANN)
203 return ("Hann");
204 else
205 return ("What The Hell !?!?");
206}
207
208function rolloff_round(x)
209{
210 if (x < 0.67)
211 x = 0.67;
212 else if (x > 1.0)
213 x = 1.0;
214
215 return (x);
216}
217
218function tap_round(x, y)
219{
220 y = floor(x + 3);
221 y -= y % 4;
222 return (y);
223}
224
225function lpf(imp, n, rolloff, beta, num, i, j, x, nm, ibeta, w)
226{
227 rolloff = rolloff_round(rolloff + (Z_NYQUIST_HOVER * (1.0 - rolloff)));
228 imp[0] = rolloff;
229
230 #
231 # Generate ideal sinc impulses, locate the last zero-crossing and pad
232 # the remaining with 0.
233 #
234 # Note that there are other (faster) ways of calculating this without
235 # the misery of traversing the entire sinc given the fact that the
236 # distance between each zero crossings is actually the bandwidth of
237 # the impulses, but it seems having 0.0001% chances of failure due to
238 # limited precision.
239 #
240 j = n;
241 for (i = 1; i < n; i++) {
242 x = (M_PI * i) / (1.0 * num);
243 imp[i] = sin(x * rolloff) / x;
244 if (i != 1 && (imp[i] * imp[i - 1]) <= 0.0)
245 j = i;
246 }
247
248 for (i = j; i < n; i++)
249 imp[i] = 0.0;
250
251 nm = 1.0 * (j - 1);
252
253 if (beta >= Z_WINDOW_KAISER)
254 ibeta = I0(beta);
255
256 for (i = 1; i < j; i++) {
257 if (beta >= Z_WINDOW_KAISER) {
258 # Kaiser window...
259 x = (1.0 * i) / nm;
260 w = I0(beta * sqrt(1.0 - (x * x))) / ibeta;
261 } else {
262 # Cosined windows...
263 x = (M_PI * i) / nm;
264 if (beta == Z_WINDOW_BLACKMAN_NUTTALL) {
265 # Blackman - Nuttall
266 w = 0.36335819 + (0.4891775 * cos(x)) + \
267 (0.1365995 * cos(2 * x)) + \
268 (0.0106411 * cos(3 * x));
269 } else if (beta == Z_WINDOW_NUTTALL) {
270 # Nuttall
271 w = 0.355768 + (0.487396 * cos(x)) + \
272 (0.144232 * cos(2 * x)) + \
273 (0.012604 * cos(3 * x));
274 } else if (beta == Z_WINDOW_BLACKMAN_HARRIS) {
275 # Blackman - Harris
276 w = 0.422323 + (0.49755 * cos(x)) + \
277 (0.07922 * cos(2 * x));
278 } else if (beta == Z_WINDOW_BLACKMAN) {
279 # Blackman
280 w = 0.42 + (0.50 * cos(x)) + \
281 (0.08 * cos(2 * x));
282 } else if (beta == Z_WINDOW_HAMMING) {
283 # Hamming
284 w = 0.54 + (0.46 * cos(x));
285 } else if (beta == Z_WINDOW_HANN) {
286 # Hann
287 w = 0.50 + (0.50 * cos(x));
288 } else {
289 # What The Hell !?!?
290 w = 0.0;
291 }
292 }
293 imp[i] *= w;
294 }
295
296 imp["impulse_length"] = j;
297 imp["rolloff"] = rolloff;
298}
299
300function mkfilter(imp, nmult, rolloff, beta, num, \
301 nwing, mwing, nrolloff, i, dcgain, v, quality)
302{
303 nwing = floor((nmult * num) / 2) + 1;
304
305 lpf(imp, nwing, rolloff, beta, num);
306
307 mwing = imp["impulse_length"];
308 nrolloff = imp["rolloff"];
309 quality = imp["quality"];
310
311 dcgain = 0.0;
312 for (i = num; i < mwing; i += num)
313 dcgain += imp[i];
314 dcgain *= 2.0;
315 dcgain += imp[0];
316
317 for (i = 0; i < nwing; i++)
318 imp[i] /= dcgain;
319
320 if (quality > 2)
321 printf("\n");
322 printf("/*\n");
323 printf(" * quality = %d\n", quality);
324 printf(" * window = %s\n", wname(beta));
325 if (beta >= Z_WINDOW_KAISER) {
326 printf(" * beta: %.2f\n", beta);
327 printf(" * stop: -%.2f dB\n", \
328 kaiserBeta2Attn(beta));
329 }
330 printf(" * length = %d\n", nmult);
331 printf(" * bandwidth = %.2f%%", rolloff * 100.0);
332 if (rolloff != nrolloff) {
333 printf(" + %.2f%% = %.2f%% (nyquist hover: %.2f%%)", \
334 (nrolloff - rolloff) * 100.0, nrolloff * 100.0, \
335 Z_NYQUIST_HOVER * 100.0);
336 }
337 printf("\n");
338 printf(" * drift = %d\n", num);
339 printf(" * width = %d\n", mwing);
340 printf(" */\n");
341 printf("static int32_t z_coeff_q%d[%d] = {", \
342 quality, nwing + (Z_COEFF_OFFSET * 2));
343 for (i = 0; i < (nwing + (Z_COEFF_OFFSET * 2)); i++) {
344 if ((i % 5) == 0)
345 printf("\n ");
346 if (i < Z_COEFF_OFFSET)
347 v = fx_floor(imp[Z_COEFF_OFFSET - i], Z_COEFF_ONE);
348 else if ((i - Z_COEFF_OFFSET) >= nwing)
349 v = fx_floor( \
350 imp[nwing + nwing - i + Z_COEFF_OFFSET - 1],\
351 Z_COEFF_ONE);
352 else
353 v = fx_floor(imp[i - Z_COEFF_OFFSET], Z_COEFF_ONE);
354 printf(" %s0x%08x,", (v < 0) ? "-" : " ", abs(v));
355 }
356 printf("\n};\n\n");
357 printf("/*\n");
358 printf(" * interpolated q%d differences.\n", quality);
359 printf(" */\n");
360 printf("static int32_t z_dcoeff_q%d[%d] = {", quality, nwing);
361 for (i = 1; i <= nwing; i++) {
362 if ((i % 5) == 1)
363 printf("\n ");
364 v = -imp[i - 1];
365 if (i != nwing)
366 v += imp[i];
367 v = fx_floor(v, Z_INTERP_COEFF_ONE);
368 if (abs(v) > abs(largest_interp))
369 largest_interp = v;
370 printf(" %s0x%08x,", (v < 0) ? "-" : " ", abs(v));
371 }
372 printf("\n};\n");
373
374 return (nwing);
375}
376
377function filter_parse(s, a, i, attn, alen)
378{
379 split(s, a, ":");
380 alen = length(a);
381
382 if (alen > 0 && a[1] == "OVERSAMPLING_FACTOR") {
383 if (alen != 2)
384 return (-1);
385 init_drift(floor(a[2]));
386 return (-1);
387 }
388
28#
29
30#
31# FIR filter design by windowing method. This might become one of the
32# funniest joke I've ever written due to too many tricks being applied to
33# ensure maximum precision (well, in fact this is already have the same
34# precision granularity compared to its C counterpart). Nevertheless, it's
35# working, precise, dynamically tunable based on "presets".
36#
37# XXX EXPECT TOTAL REWRITE! DON'T ARGUE!
38#
39# TODO: Using ultraspherical window might be a good idea.
40#
41# Based on:
42#
43# "Digital Audio Resampling" by Julius O. Smith III
44#
45# - http://ccrma.stanford.edu/~jos/resample/
46#
47
48#
49# Some basic Math functions.
50#
51function abs(x)
52{
53 return (((x < 0) ? -x : x) + 0);
54}
55
56function fabs(x)
57{
58 return (((x < 0.0) ? -x : x) + 0.0);
59}
60
61function ceil(x, r)
62{
63 r = int(x);
64 if (r < x)
65 r++;
66 return (r + 0);
67}
68
69function floor(x, r)
70{
71 r = int(x);
72 if (r > x)
73 r--;
74 return (r + 0);
75}
76
77function pow(x, y)
78{
79 return (exp(1.0 * y * log(1.0 * x)));
80}
81
82#
83# What the hell...
84#
85function shl(x, y)
86{
87 while (y > 0) {
88 x *= 2;
89 y--;
90 }
91 return (x);
92}
93
94function shr(x, y)
95{
96 while (y > 0 && x != 0) {
97 x = floor(x / 2);
98 y--;
99 }
100 return (x);
101}
102
103function fx_floor(v, o, r)
104{
105 if (fabs(v) < fabs(smallest))
106 smallest = v;
107 if (fabs(v) > fabs(largest))
108 largest = v;
109
110 r = floor((v * o) + 0.5);
111 if (r < INT32_MIN || r > INT32_MAX)
112 printf("\n#error overflow v=%f, please reduce %d\n", v, o);
113
114 return (r);
115}
116
117#
118# Kaiser linear piecewise functions.
119#
120function kaiserAttn2Beta(attn, beta)
121{
122 if (attn < 0.0)
123 return (Z_KAISER_BETA_DEFAULT);
124
125 if (attn > 50.0)
126 beta = 0.1102 * ((1.0 * attn) - 8.7);
127 else if (attn > 21.0)
128 beta = (0.5842 * pow((1.0 * attn) - 21.0, 0.4)) + \
129 (0.07886 * ((1.0 * attn) - 21.0));
130 else
131 beta = 0.0;
132
133 return (beta);
134}
135
136function kaiserBeta2Attn(beta, x, y, i, attn, xbeta)
137{
138 if (beta < Z_WINDOW_KAISER)
139 return (Z_KAISER_ATTN_DEFAULT);
140
141 if (beta > kaiserAttn2Beta(50.0))
142 attn = ((1.0 * beta) / 0.1102) + 8.7;
143 else {
144 x = 21.0;
145 y = 50.0;
146 attn = 0.5 * (x + y);
147 for (i = 0; i < 128; i++) {
148 xbeta = kaiserAttn2Beta(attn)
149 if (beta == xbeta || \
150 (i > 63 && \
151 fabs(beta - xbeta) < Z_KAISER_EPSILON))
152 break;
153 if (beta > xbeta)
154 x = attn;
155 else
156 y = attn;
157 attn = 0.5 * (x + y);
158 }
159 }
160
161 return (attn);
162}
163
164function kaiserRolloff(len, attn)
165{
166 return (1.0 - (((1.0 * attn) - 7.95) / (((1.0 * len) - 1.0) * 14.36)));
167}
168
169#
170# 0th order modified Bessel function of the first kind.
171#
172function I0(x, s, u, n, h, t)
173{
174 s = n = u = 1.0;
175 h = x * 0.5;
176
177 do {
178 t = h / n;
179 n += 1.0;
180 t *= t;
181 u *= t;
182 s += u;
183 } while (u >= (I0_EPSILON * s));
184
185 return (s);
186}
187
188function wname(beta)
189{
190 if (beta >= Z_WINDOW_KAISER)
191 return ("Kaiser");
192 else if (beta == Z_WINDOW_BLACKMAN_NUTTALL)
193 return ("Blackman - Nuttall");
194 else if (beta == Z_WINDOW_NUTTALL)
195 return ("Nuttall");
196 else if (beta == Z_WINDOW_BLACKMAN_HARRIS)
197 return ("Blackman - Harris");
198 else if (beta == Z_WINDOW_BLACKMAN)
199 return ("Blackman");
200 else if (beta == Z_WINDOW_HAMMING)
201 return ("Hamming");
202 else if (beta == Z_WINDOW_HANN)
203 return ("Hann");
204 else
205 return ("What The Hell !?!?");
206}
207
208function rolloff_round(x)
209{
210 if (x < 0.67)
211 x = 0.67;
212 else if (x > 1.0)
213 x = 1.0;
214
215 return (x);
216}
217
218function tap_round(x, y)
219{
220 y = floor(x + 3);
221 y -= y % 4;
222 return (y);
223}
224
225function lpf(imp, n, rolloff, beta, num, i, j, x, nm, ibeta, w)
226{
227 rolloff = rolloff_round(rolloff + (Z_NYQUIST_HOVER * (1.0 - rolloff)));
228 imp[0] = rolloff;
229
230 #
231 # Generate ideal sinc impulses, locate the last zero-crossing and pad
232 # the remaining with 0.
233 #
234 # Note that there are other (faster) ways of calculating this without
235 # the misery of traversing the entire sinc given the fact that the
236 # distance between each zero crossings is actually the bandwidth of
237 # the impulses, but it seems having 0.0001% chances of failure due to
238 # limited precision.
239 #
240 j = n;
241 for (i = 1; i < n; i++) {
242 x = (M_PI * i) / (1.0 * num);
243 imp[i] = sin(x * rolloff) / x;
244 if (i != 1 && (imp[i] * imp[i - 1]) <= 0.0)
245 j = i;
246 }
247
248 for (i = j; i < n; i++)
249 imp[i] = 0.0;
250
251 nm = 1.0 * (j - 1);
252
253 if (beta >= Z_WINDOW_KAISER)
254 ibeta = I0(beta);
255
256 for (i = 1; i < j; i++) {
257 if (beta >= Z_WINDOW_KAISER) {
258 # Kaiser window...
259 x = (1.0 * i) / nm;
260 w = I0(beta * sqrt(1.0 - (x * x))) / ibeta;
261 } else {
262 # Cosined windows...
263 x = (M_PI * i) / nm;
264 if (beta == Z_WINDOW_BLACKMAN_NUTTALL) {
265 # Blackman - Nuttall
266 w = 0.36335819 + (0.4891775 * cos(x)) + \
267 (0.1365995 * cos(2 * x)) + \
268 (0.0106411 * cos(3 * x));
269 } else if (beta == Z_WINDOW_NUTTALL) {
270 # Nuttall
271 w = 0.355768 + (0.487396 * cos(x)) + \
272 (0.144232 * cos(2 * x)) + \
273 (0.012604 * cos(3 * x));
274 } else if (beta == Z_WINDOW_BLACKMAN_HARRIS) {
275 # Blackman - Harris
276 w = 0.422323 + (0.49755 * cos(x)) + \
277 (0.07922 * cos(2 * x));
278 } else if (beta == Z_WINDOW_BLACKMAN) {
279 # Blackman
280 w = 0.42 + (0.50 * cos(x)) + \
281 (0.08 * cos(2 * x));
282 } else if (beta == Z_WINDOW_HAMMING) {
283 # Hamming
284 w = 0.54 + (0.46 * cos(x));
285 } else if (beta == Z_WINDOW_HANN) {
286 # Hann
287 w = 0.50 + (0.50 * cos(x));
288 } else {
289 # What The Hell !?!?
290 w = 0.0;
291 }
292 }
293 imp[i] *= w;
294 }
295
296 imp["impulse_length"] = j;
297 imp["rolloff"] = rolloff;
298}
299
300function mkfilter(imp, nmult, rolloff, beta, num, \
301 nwing, mwing, nrolloff, i, dcgain, v, quality)
302{
303 nwing = floor((nmult * num) / 2) + 1;
304
305 lpf(imp, nwing, rolloff, beta, num);
306
307 mwing = imp["impulse_length"];
308 nrolloff = imp["rolloff"];
309 quality = imp["quality"];
310
311 dcgain = 0.0;
312 for (i = num; i < mwing; i += num)
313 dcgain += imp[i];
314 dcgain *= 2.0;
315 dcgain += imp[0];
316
317 for (i = 0; i < nwing; i++)
318 imp[i] /= dcgain;
319
320 if (quality > 2)
321 printf("\n");
322 printf("/*\n");
323 printf(" * quality = %d\n", quality);
324 printf(" * window = %s\n", wname(beta));
325 if (beta >= Z_WINDOW_KAISER) {
326 printf(" * beta: %.2f\n", beta);
327 printf(" * stop: -%.2f dB\n", \
328 kaiserBeta2Attn(beta));
329 }
330 printf(" * length = %d\n", nmult);
331 printf(" * bandwidth = %.2f%%", rolloff * 100.0);
332 if (rolloff != nrolloff) {
333 printf(" + %.2f%% = %.2f%% (nyquist hover: %.2f%%)", \
334 (nrolloff - rolloff) * 100.0, nrolloff * 100.0, \
335 Z_NYQUIST_HOVER * 100.0);
336 }
337 printf("\n");
338 printf(" * drift = %d\n", num);
339 printf(" * width = %d\n", mwing);
340 printf(" */\n");
341 printf("static int32_t z_coeff_q%d[%d] = {", \
342 quality, nwing + (Z_COEFF_OFFSET * 2));
343 for (i = 0; i < (nwing + (Z_COEFF_OFFSET * 2)); i++) {
344 if ((i % 5) == 0)
345 printf("\n ");
346 if (i < Z_COEFF_OFFSET)
347 v = fx_floor(imp[Z_COEFF_OFFSET - i], Z_COEFF_ONE);
348 else if ((i - Z_COEFF_OFFSET) >= nwing)
349 v = fx_floor( \
350 imp[nwing + nwing - i + Z_COEFF_OFFSET - 1],\
351 Z_COEFF_ONE);
352 else
353 v = fx_floor(imp[i - Z_COEFF_OFFSET], Z_COEFF_ONE);
354 printf(" %s0x%08x,", (v < 0) ? "-" : " ", abs(v));
355 }
356 printf("\n};\n\n");
357 printf("/*\n");
358 printf(" * interpolated q%d differences.\n", quality);
359 printf(" */\n");
360 printf("static int32_t z_dcoeff_q%d[%d] = {", quality, nwing);
361 for (i = 1; i <= nwing; i++) {
362 if ((i % 5) == 1)
363 printf("\n ");
364 v = -imp[i - 1];
365 if (i != nwing)
366 v += imp[i];
367 v = fx_floor(v, Z_INTERP_COEFF_ONE);
368 if (abs(v) > abs(largest_interp))
369 largest_interp = v;
370 printf(" %s0x%08x,", (v < 0) ? "-" : " ", abs(v));
371 }
372 printf("\n};\n");
373
374 return (nwing);
375}
376
377function filter_parse(s, a, i, attn, alen)
378{
379 split(s, a, ":");
380 alen = length(a);
381
382 if (alen > 0 && a[1] == "OVERSAMPLING_FACTOR") {
383 if (alen != 2)
384 return (-1);
385 init_drift(floor(a[2]));
386 return (-1);
387 }
388
389 if (alen > 0 && a[1] == "COEFFICIENT_BIT") {
390 if (alen != 2)
391 return (-1);
392 init_coeff_bit(floor(a[2]));
393 return (-1);
394 }
395
396 if (alen > 0 && a[1] == "ACCUMULATOR_BIT") {
397 if (alen != 2)
398 return (-1);
399 init_accum_bit(floor(a[2]));
400 return (-1);
401 }
402
403 if (alen > 0 && a[1] == "INTERPOLATOR") {
404 if (alen != 2)
405 return (-1);
406 init_coeff_interpolator(toupper(a[2]));
407 return (-1);
408 }
409
389 if (alen == 1 || alen == 2) {
390 if (a[1] == "NYQUIST_HOVER") {
391 i = 1.0 * a[2];
392 Z_NYQUIST_HOVER = (i > 0.0 && i < 1.0) ? i : 0.0;
393 return (-1);
394 }
395 i = 1;
396 if (alen == 1) {
397 attn = Z_KAISER_ATTN_DEFAULT;
398 Popts["beta"] = Z_KAISER_BETA_DEFAULT;
399 } else if (Z_WINDOWS[a[1]] < Z_WINDOW_KAISER) {
400 Popts["beta"] = Z_WINDOWS[a[1]];
401 i = tap_round(a[2]);
402 Popts["nmult"] = i;
403 if (i < 28)
404 i = 28;
405 i = 1.0 - (6.44 / i);
406 Popts["rolloff"] = rolloff_round(i);
407 return (0);
408 } else {
409 attn = 1.0 * a[i++];
410 Popts["beta"] = kaiserAttn2Beta(attn);
411 }
412 i = tap_round(a[i]);
413 Popts["nmult"] = i;
414 if (i > 7 && i < 28)
415 i = 27;
416 i = kaiserRolloff(i, attn);
417 Popts["rolloff"] = rolloff_round(i);
418
419 return (0);
420 }
421
422 if (!(alen == 3 || alen == 4))
423 return (-1);
424
425 i = 2;
426
427 if (a[1] == "kaiser") {
428 if (alen > 2)
429 Popts["beta"] = 1.0 * a[i++];
430 else
431 Popts["beta"] = Z_KAISER_BETA_DEFAULT;
432 } else if (Z_WINDOWS[a[1]] < Z_WINDOW_KAISER)
433 Popts["beta"] = Z_WINDOWS[a[1]];
434 else if (1.0 * a[1] < Z_WINDOW_KAISER)
435 return (-1);
436 else
437 Popts["beta"] = kaiserAttn2Beta(1.0 * a[1]);
438 Popts["nmult"] = tap_round(a[i++]);
439 if (a[1] == "kaiser" && alen == 3)
440 i = kaiserRolloff(Popts["nmult"], \
441 kaiserBeta2Attn(Popts["beta"]));
442 else
443 i = 1.0 * a[i];
444 Popts["rolloff"] = rolloff_round(i);
445
446 return (0);
447}
448
449function genscale(bit, s1, s2, scale)
450{
410 if (alen == 1 || alen == 2) {
411 if (a[1] == "NYQUIST_HOVER") {
412 i = 1.0 * a[2];
413 Z_NYQUIST_HOVER = (i > 0.0 && i < 1.0) ? i : 0.0;
414 return (-1);
415 }
416 i = 1;
417 if (alen == 1) {
418 attn = Z_KAISER_ATTN_DEFAULT;
419 Popts["beta"] = Z_KAISER_BETA_DEFAULT;
420 } else if (Z_WINDOWS[a[1]] < Z_WINDOW_KAISER) {
421 Popts["beta"] = Z_WINDOWS[a[1]];
422 i = tap_round(a[2]);
423 Popts["nmult"] = i;
424 if (i < 28)
425 i = 28;
426 i = 1.0 - (6.44 / i);
427 Popts["rolloff"] = rolloff_round(i);
428 return (0);
429 } else {
430 attn = 1.0 * a[i++];
431 Popts["beta"] = kaiserAttn2Beta(attn);
432 }
433 i = tap_round(a[i]);
434 Popts["nmult"] = i;
435 if (i > 7 && i < 28)
436 i = 27;
437 i = kaiserRolloff(i, attn);
438 Popts["rolloff"] = rolloff_round(i);
439
440 return (0);
441 }
442
443 if (!(alen == 3 || alen == 4))
444 return (-1);
445
446 i = 2;
447
448 if (a[1] == "kaiser") {
449 if (alen > 2)
450 Popts["beta"] = 1.0 * a[i++];
451 else
452 Popts["beta"] = Z_KAISER_BETA_DEFAULT;
453 } else if (Z_WINDOWS[a[1]] < Z_WINDOW_KAISER)
454 Popts["beta"] = Z_WINDOWS[a[1]];
455 else if (1.0 * a[1] < Z_WINDOW_KAISER)
456 return (-1);
457 else
458 Popts["beta"] = kaiserAttn2Beta(1.0 * a[1]);
459 Popts["nmult"] = tap_round(a[i++]);
460 if (a[1] == "kaiser" && alen == 3)
461 i = kaiserRolloff(Popts["nmult"], \
462 kaiserBeta2Attn(Popts["beta"]));
463 else
464 i = 1.0 * a[i];
465 Popts["rolloff"] = rolloff_round(i);
466
467 return (0);
468}
469
470function genscale(bit, s1, s2, scale)
471{
451 s1 = Z_COEFF_SHIFT - (32 - bit);
472 if ((bit + Z_COEFF_SHIFT) > Z_ACCUMULATOR_BIT)
473 s1 = Z_COEFF_SHIFT - \
474 (32 - (Z_ACCUMULATOR_BIT - Z_COEFF_SHIFT));
475 else
476 s1 = Z_COEFF_SHIFT - (32 - bit);
477
452 s2 = Z_SHIFT + (32 - bit);
453
454 if (s1 == 0)
455 scale = "v";
456 else if (s1 < 0)
457 scale = sprintf("(v) << %d", abs(s1));
458 else
459 scale = sprintf("(v) >> %d", s1);
460
461 scale = sprintf("(%s) * Z_SCALE_CAST(s)", scale);
462
463 if (s2 != 0)
464 scale = sprintf("(%s) >> %d", scale, s2);
465
466 printf("#define Z_SCALE_%d(v, s)\t%s(%s)\n", \
467 bit, (bit < 10) ? "\t" : "", scale);
468}
469
470function genlerp(bit, use64, lerp)
471{
472 if ((bit + Z_LINEAR_SHIFT) <= 32) {
473 lerp = sprintf("(((y) - (x)) * (z)) >> %d", Z_LINEAR_SHIFT);
474 } else if (use64 != 0) {
475 if ((bit + Z_LINEAR_SHIFT) <= 64) {
476 lerp = sprintf( \
477 "(((int64_t)(y) - (x)) * (z)) " \
478 ">> %d", \
479 Z_LINEAR_SHIFT);
480 } else {
481 lerp = sprintf( \
482 "((int64_t)((y) >> %d) - ((x) >> %d)) * ", \
483 "(z)" \
484 bit + Z_LINEAR_SHIFT - 64, \
485 bit + Z_LINEAR_SHIFT - 64);
486 if ((64 - bit) != 0)
487 lerp = sprintf("(%s) >> %d", lerp, 64 - bit);
488 }
489 } else {
490 lerp = sprintf( \
491 "(((y) >> %d) - ((x) >> %d)) * (z)", \
492 bit + Z_LINEAR_SHIFT - 32, \
493 bit + Z_LINEAR_SHIFT - 32);
494 if ((32 - bit) != 0)
495 lerp = sprintf("(%s) >> %d", lerp, 32 - bit);
496 }
497
498 printf("#define Z_LINEAR_INTERPOLATE_%d(z, x, y)" \
499 "\t\t\t\t%s\\\n\t((x) + (%s))\n", \
500 bit, (bit < 10) ? "\t" : "", lerp);
501}
502
503function init_drift(drift, xdrift)
504{
505 xdrift = floor(drift);
506
507 if (Z_DRIFT_SHIFT != -1) {
508 if (xdrift != Z_DRIFT_SHIFT)
509 printf("#error Z_DRIFT_SHIFT reinitialize!\n");
510 return;
511 }
512
513 #
514 # Initialize filter oversampling factor, or in other word
515 # Z_DRIFT_SHIFT.
516 #
517 if (xdrift < 0)
518 xdrift = 1;
519 else if (xdrift > 31)
520 xdrift = 31;
521
522 Z_DRIFT_SHIFT = xdrift;
523 Z_DRIFT_ONE = shl(1, Z_DRIFT_SHIFT);
524
525 Z_SHIFT = Z_FULL_SHIFT - Z_DRIFT_SHIFT;
526 Z_ONE = shl(1, Z_SHIFT);
527 Z_MASK = Z_ONE - 1;
528}
529
478 s2 = Z_SHIFT + (32 - bit);
479
480 if (s1 == 0)
481 scale = "v";
482 else if (s1 < 0)
483 scale = sprintf("(v) << %d", abs(s1));
484 else
485 scale = sprintf("(v) >> %d", s1);
486
487 scale = sprintf("(%s) * Z_SCALE_CAST(s)", scale);
488
489 if (s2 != 0)
490 scale = sprintf("(%s) >> %d", scale, s2);
491
492 printf("#define Z_SCALE_%d(v, s)\t%s(%s)\n", \
493 bit, (bit < 10) ? "\t" : "", scale);
494}
495
496function genlerp(bit, use64, lerp)
497{
498 if ((bit + Z_LINEAR_SHIFT) <= 32) {
499 lerp = sprintf("(((y) - (x)) * (z)) >> %d", Z_LINEAR_SHIFT);
500 } else if (use64 != 0) {
501 if ((bit + Z_LINEAR_SHIFT) <= 64) {
502 lerp = sprintf( \
503 "(((int64_t)(y) - (x)) * (z)) " \
504 ">> %d", \
505 Z_LINEAR_SHIFT);
506 } else {
507 lerp = sprintf( \
508 "((int64_t)((y) >> %d) - ((x) >> %d)) * ", \
509 "(z)" \
510 bit + Z_LINEAR_SHIFT - 64, \
511 bit + Z_LINEAR_SHIFT - 64);
512 if ((64 - bit) != 0)
513 lerp = sprintf("(%s) >> %d", lerp, 64 - bit);
514 }
515 } else {
516 lerp = sprintf( \
517 "(((y) >> %d) - ((x) >> %d)) * (z)", \
518 bit + Z_LINEAR_SHIFT - 32, \
519 bit + Z_LINEAR_SHIFT - 32);
520 if ((32 - bit) != 0)
521 lerp = sprintf("(%s) >> %d", lerp, 32 - bit);
522 }
523
524 printf("#define Z_LINEAR_INTERPOLATE_%d(z, x, y)" \
525 "\t\t\t\t%s\\\n\t((x) + (%s))\n", \
526 bit, (bit < 10) ? "\t" : "", lerp);
527}
528
529function init_drift(drift, xdrift)
530{
531 xdrift = floor(drift);
532
533 if (Z_DRIFT_SHIFT != -1) {
534 if (xdrift != Z_DRIFT_SHIFT)
535 printf("#error Z_DRIFT_SHIFT reinitialize!\n");
536 return;
537 }
538
539 #
540 # Initialize filter oversampling factor, or in other word
541 # Z_DRIFT_SHIFT.
542 #
543 if (xdrift < 0)
544 xdrift = 1;
545 else if (xdrift > 31)
546 xdrift = 31;
547
548 Z_DRIFT_SHIFT = xdrift;
549 Z_DRIFT_ONE = shl(1, Z_DRIFT_SHIFT);
550
551 Z_SHIFT = Z_FULL_SHIFT - Z_DRIFT_SHIFT;
552 Z_ONE = shl(1, Z_SHIFT);
553 Z_MASK = Z_ONE - 1;
554}
555
556function init_coeff_bit(cbit, xcbit)
557{
558 xcbit = floor(cbit);
559
560 if (Z_COEFF_SHIFT != 0) {
561 if (xcbit != Z_COEFF_SHIFT)
562 printf("#error Z_COEFF_SHIFT reinitialize!\n");
563 return;
564 }
565
566 #
567 # Initialize dynamic range of coefficients.
568 #
569 if (xcbit < 1)
570 xcbit = 1;
571 else if (xcbit > 30)
572 xcbit = 30;
573
574 Z_COEFF_SHIFT = xcbit;
575 Z_COEFF_ONE = shl(1, Z_COEFF_SHIFT);
576}
577
578function init_accum_bit(accbit, xaccbit)
579{
580 xaccbit = floor(accbit);
581
582 if (Z_ACCUMULATOR_BIT != 0) {
583 if (xaccbit != Z_ACCUMULATOR_BIT)
584 printf("#error Z_ACCUMULATOR_BIT reinitialize!\n");
585 return;
586 }
587
588 #
589 # Initialize dynamic range of accumulator.
590 #
591 if (xaccbit > 64)
592 xaccbit = 64;
593 else if (xaccbit < 32)
594 xaccbit = 32;
595
596 Z_ACCUMULATOR_BIT = xaccbit;
597}
598
599function init_coeff_interpolator(interp)
600{
601 #
602 # Validate interpolator type.
603 #
604 if (interp == "ZOH" || interp == "LINEAR" || \
605 interp == "QUADRATIC" || interp == "HERMITE" || \
606 interp == "BSPLINE" || interp == "OPT32X" || \
607 interp == "OPT16X" || interp == "OPT8X" || \
608 interp == "OPT4X" || interp == "OPT2X")
609 Z_COEFF_INTERPOLATOR = interp;
610}
611
530BEGIN {
531 I0_EPSILON = 1e-21;
532 M_PI = atan2(0.0, -1.0);
533
534 INT32_MAX = 1 + ((shl(1, 30) - 1) * 2);
535 INT32_MIN = -1 - INT32_MAX;
536
537 Z_COEFF_OFFSET = 5;
538
612BEGIN {
613 I0_EPSILON = 1e-21;
614 M_PI = atan2(0.0, -1.0);
615
616 INT32_MAX = 1 + ((shl(1, 30) - 1) * 2);
617 INT32_MIN = -1 - INT32_MAX;
618
619 Z_COEFF_OFFSET = 5;
620
621 Z_ACCUMULATOR_BIT_DEFAULT = 58;
622 Z_ACCUMULATOR_BIT = 0;
623
539 Z_FULL_SHIFT = 30;
540 Z_FULL_ONE = shl(1, Z_FULL_SHIFT);
541
624 Z_FULL_SHIFT = 30;
625 Z_FULL_ONE = shl(1, Z_FULL_SHIFT);
626
542 Z_COEFF_SHIFT = 28;
543 Z_COEFF_ONE = shl(1, Z_COEFF_SHIFT);
627 Z_COEFF_SHIFT_DEFAULT = 30;
628 Z_COEFF_SHIFT = 0;
629 Z_COEFF_ONE = 0;
544
630
631 Z_COEFF_INTERPOLATOR = 0;
632
545 Z_INTERP_COEFF_SHIFT = 24;
546 Z_INTERP_COEFF_ONE = shl(1, Z_INTERP_COEFF_SHIFT);
547
548 Z_LINEAR_FULL_SHIFT = Z_FULL_SHIFT;
549 Z_LINEAR_FULL_ONE = shl(1, Z_LINEAR_FULL_SHIFT);
550 Z_LINEAR_SHIFT = 8;
551 Z_LINEAR_UNSHIFT = Z_LINEAR_FULL_SHIFT - Z_LINEAR_SHIFT;
552 Z_LINEAR_ONE = shl(1, Z_LINEAR_SHIFT)
553
554 Z_DRIFT_SHIFT_DEFAULT = 5;
555 Z_DRIFT_SHIFT = -1;
556 # meehhhh... let it overflow...
557 #Z_SCALE_SHIFT = 31;
558 #Z_SCALE_ONE = shl(1, Z_SCALE_SHIFT);
559
560 Z_WINDOW_KAISER = 0.0;
561 Z_WINDOW_BLACKMAN_NUTTALL = -1.0;
562 Z_WINDOW_NUTTALL = -2.0;
563 Z_WINDOW_BLACKMAN_HARRIS = -3.0;
564 Z_WINDOW_BLACKMAN = -4.0;
565 Z_WINDOW_HAMMING = -5.0;
566 Z_WINDOW_HANN = -6.0;
567
568 Z_WINDOWS["blackman_nuttall"] = Z_WINDOW_BLACKMAN_NUTTALL;
569 Z_WINDOWS["nuttall"] = Z_WINDOW_NUTTALL;
570 Z_WINDOWS["blackman_harris"] = Z_WINDOW_BLACKMAN_HARRIS;
571 Z_WINDOWS["blackman"] = Z_WINDOW_BLACKMAN;
572 Z_WINDOWS["hamming"] = Z_WINDOW_HAMMING;
573 Z_WINDOWS["hann"] = Z_WINDOW_HANN;
574
575 Z_KAISER_2_BLACKMAN_BETA = 8.568611;
576 Z_KAISER_2_BLACKMAN_NUTTALL_BETA = 11.98;
577
578 Z_KAISER_ATTN_DEFAULT = 100;
579 Z_KAISER_BETA_DEFAULT = kaiserAttn2Beta(Z_KAISER_ATTN_DEFAULT);
580
581 Z_KAISER_EPSILON = 1e-21;
582
583 #
584 # This is practically a joke.
585 #
586 Z_NYQUIST_HOVER = 0.0;
587
588 smallest = 10.000000;
589 largest = 0.000010;
590 largest_interp = 0;
591
592 if (ARGC < 2) {
593 ARGC = 1;
594 ARGV[ARGC++] = "100:8:0.85";
595 ARGV[ARGC++] = "100:36:0.92";
596 ARGV[ARGC++] = "100:164:0.97";
597 #ARGV[ARGC++] = "100:8";
598 #ARGV[ARGC++] = "100:16";
599 #ARGV[ARGC++] = "100:32:0.7929";
600 #ARGV[ARGC++] = "100:64:0.8990";
601 #ARGV[ARGC++] = "100:128:0.9499";
602 }
603
604 printf("#ifndef _FEEDER_RATE_GEN_H_\n");
605 printf("#define _FEEDER_RATE_GEN_H_\n\n");
606 printf("/*\n");
607 printf(" * Generated using feeder_rate_mkfilter.awk, heaven, wind and awesome.\n");
608 printf(" *\n");
609 printf(" * DO NOT EDIT!\n");
610 printf(" */\n\n");
611 printf("#define FEEDER_RATE_PRESETS\t\"");
612 for (i = 1; i < ARGC; i++)
613 printf("%s%s", (i == 1) ? "" : " ", ARGV[i]);
614 printf("\"\n\n");
615 imp["quality"] = 2;
616 for (i = 1; i < ARGC; i++) {
617 if (filter_parse(ARGV[i]) == 0) {
618 beta = Popts["beta"];
619 nmult = Popts["nmult"];
620 rolloff = Popts["rolloff"];
621 if (Z_DRIFT_SHIFT == -1)
622 init_drift(Z_DRIFT_SHIFT_DEFAULT);
633 Z_INTERP_COEFF_SHIFT = 24;
634 Z_INTERP_COEFF_ONE = shl(1, Z_INTERP_COEFF_SHIFT);
635
636 Z_LINEAR_FULL_SHIFT = Z_FULL_SHIFT;
637 Z_LINEAR_FULL_ONE = shl(1, Z_LINEAR_FULL_SHIFT);
638 Z_LINEAR_SHIFT = 8;
639 Z_LINEAR_UNSHIFT = Z_LINEAR_FULL_SHIFT - Z_LINEAR_SHIFT;
640 Z_LINEAR_ONE = shl(1, Z_LINEAR_SHIFT)
641
642 Z_DRIFT_SHIFT_DEFAULT = 5;
643 Z_DRIFT_SHIFT = -1;
644 # meehhhh... let it overflow...
645 #Z_SCALE_SHIFT = 31;
646 #Z_SCALE_ONE = shl(1, Z_SCALE_SHIFT);
647
648 Z_WINDOW_KAISER = 0.0;
649 Z_WINDOW_BLACKMAN_NUTTALL = -1.0;
650 Z_WINDOW_NUTTALL = -2.0;
651 Z_WINDOW_BLACKMAN_HARRIS = -3.0;
652 Z_WINDOW_BLACKMAN = -4.0;
653 Z_WINDOW_HAMMING = -5.0;
654 Z_WINDOW_HANN = -6.0;
655
656 Z_WINDOWS["blackman_nuttall"] = Z_WINDOW_BLACKMAN_NUTTALL;
657 Z_WINDOWS["nuttall"] = Z_WINDOW_NUTTALL;
658 Z_WINDOWS["blackman_harris"] = Z_WINDOW_BLACKMAN_HARRIS;
659 Z_WINDOWS["blackman"] = Z_WINDOW_BLACKMAN;
660 Z_WINDOWS["hamming"] = Z_WINDOW_HAMMING;
661 Z_WINDOWS["hann"] = Z_WINDOW_HANN;
662
663 Z_KAISER_2_BLACKMAN_BETA = 8.568611;
664 Z_KAISER_2_BLACKMAN_NUTTALL_BETA = 11.98;
665
666 Z_KAISER_ATTN_DEFAULT = 100;
667 Z_KAISER_BETA_DEFAULT = kaiserAttn2Beta(Z_KAISER_ATTN_DEFAULT);
668
669 Z_KAISER_EPSILON = 1e-21;
670
671 #
672 # This is practically a joke.
673 #
674 Z_NYQUIST_HOVER = 0.0;
675
676 smallest = 10.000000;
677 largest = 0.000010;
678 largest_interp = 0;
679
680 if (ARGC < 2) {
681 ARGC = 1;
682 ARGV[ARGC++] = "100:8:0.85";
683 ARGV[ARGC++] = "100:36:0.92";
684 ARGV[ARGC++] = "100:164:0.97";
685 #ARGV[ARGC++] = "100:8";
686 #ARGV[ARGC++] = "100:16";
687 #ARGV[ARGC++] = "100:32:0.7929";
688 #ARGV[ARGC++] = "100:64:0.8990";
689 #ARGV[ARGC++] = "100:128:0.9499";
690 }
691
692 printf("#ifndef _FEEDER_RATE_GEN_H_\n");
693 printf("#define _FEEDER_RATE_GEN_H_\n\n");
694 printf("/*\n");
695 printf(" * Generated using feeder_rate_mkfilter.awk, heaven, wind and awesome.\n");
696 printf(" *\n");
697 printf(" * DO NOT EDIT!\n");
698 printf(" */\n\n");
699 printf("#define FEEDER_RATE_PRESETS\t\"");
700 for (i = 1; i < ARGC; i++)
701 printf("%s%s", (i == 1) ? "" : " ", ARGV[i]);
702 printf("\"\n\n");
703 imp["quality"] = 2;
704 for (i = 1; i < ARGC; i++) {
705 if (filter_parse(ARGV[i]) == 0) {
706 beta = Popts["beta"];
707 nmult = Popts["nmult"];
708 rolloff = Popts["rolloff"];
709 if (Z_DRIFT_SHIFT == -1)
710 init_drift(Z_DRIFT_SHIFT_DEFAULT);
711 if (Z_COEFF_SHIFT == 0)
712 init_coeff_bit(Z_COEFF_SHIFT_DEFAULT);
713 if (Z_ACCUMULATOR_BIT == 0)
714 init_accum_bit(Z_ACCUMULATOR_BIT_DEFAULT);
623 ztab[imp["quality"] - 2] = \
624 mkfilter(imp, nmult, rolloff, beta, Z_DRIFT_ONE);
625 imp["quality"]++;
626 }
627 }
628
629 printf("\n");
630 #
631 # XXX
632 #
633 #if (length(ztab) > 0) {
634 # j = 0;
635 # for (i = 0; i < length(ztab); i++) {
636 # if (ztab[i] > j)
637 # j = ztab[i];
638 # }
639 # printf("static int32_t z_coeff_zero[%d] = {", j);
640 # for (i = 0; i < j; i++) {
641 # if ((i % 19) == 0)
642 # printf("\n");
643 # printf(" 0,");
644 # }
645 # printf("\n};\n\n");
646 #}
647 #
648 # XXX
649 #
650 printf("static const struct {\n");
651 printf("\tint32_t len;\n");
652 printf("\tint32_t *coeff;\n");
653 printf("\tint32_t *dcoeff;\n");
654 printf("} z_coeff_tab[] = {\n");
655 if (length(ztab) > 0) {
656 j = 0;
657 for (i = 0; i < length(ztab); i++) {
658 if (ztab[i] > j)
659 j = ztab[i];
660 }
661 j = length(sprintf("%d", j));
662 lfmt = sprintf("%%%dd", j);
663 j = length(sprintf("z_coeff_q%d", length(ztab) + 1));
664 zcfmt = sprintf("%%-%ds", j);
665 zdcfmt = sprintf("%%-%ds", j + 1);
666
667 for (i = 0; i < length(ztab); i++) {
668 l = sprintf(lfmt, ztab[i]);
669 zc = sprintf("z_coeff_q%d", i + 2);
670 zc = sprintf(zcfmt, zc);
671 zdc = sprintf("z_dcoeff_q%d", i + 2);
672 zdc = sprintf(zdcfmt, zdc);
673 printf("\t{ %s, %s, %s },\n", l, zc, zdc);
674 }
675 } else
676 printf("\t{ 0, NULL, NULL }\n");
677 printf("};\n\n");
678
679 #Z_UNSHIFT = 0;
680 #v = shr(Z_ONE - 1, Z_UNSHIFT) * abs(largest_interp);
681 #while (v < 0 || v > INT32_MAX) {
682 # Z_UNSHIFT += 1;
683 # v = shr(Z_ONE - 1, Z_UNSHIFT) * abs(largest_interp);
684 #}
685 v = ((Z_ONE - 1) * abs(largest_interp)) / INT32_MAX;
686 Z_UNSHIFT = ceil(log(v) / log(2.0));
687 Z_INTERP_SHIFT = Z_SHIFT - Z_UNSHIFT + Z_INTERP_COEFF_SHIFT;
688
689 Z_INTERP_UNSHIFT = (Z_SHIFT - Z_UNSHIFT) + Z_INTERP_COEFF_SHIFT \
690 - Z_COEFF_SHIFT;
691
692 printf("#define Z_COEFF_TAB_SIZE\t\t\t\t\t\t\\\n");
693 printf("\t((int32_t)(sizeof(z_coeff_tab) /");
694 printf(" sizeof(z_coeff_tab[0])))\n\n");
695 printf("#define Z_COEFF_OFFSET\t\t%d\n\n", Z_COEFF_OFFSET);
696 printf("#define Z_RSHIFT(x, y)\t\t(((x) + " \
697 "(1 << ((y) - 1))) >> (y))\n");
698 printf("#define Z_RSHIFT_L(x, y)\t(((x) + " \
699 "(1LL << ((y) - 1))) >> (y))\n\n");
700 printf("#define Z_FULL_SHIFT\t\t%d\n", Z_FULL_SHIFT);
701 printf("#define Z_FULL_ONE\t\t0x%08x%s\n", Z_FULL_ONE, \
702 (Z_FULL_ONE > INT32_MAX) ? "U" : "");
703 printf("\n");
704 printf("#define Z_DRIFT_SHIFT\t\t%d\n", Z_DRIFT_SHIFT);
705 #printf("#define Z_DRIFT_ONE\t\t0x%08x\n", Z_DRIFT_ONE);
706 printf("\n");
707 printf("#define Z_SHIFT\t\t\t%d\n", Z_SHIFT);
708 printf("#define Z_ONE\t\t\t0x%08x\n", Z_ONE);
709 printf("#define Z_MASK\t\t\t0x%08x\n", Z_MASK);
710 printf("\n");
711 printf("#define Z_COEFF_SHIFT\t\t%d\n", Z_COEFF_SHIFT);
712 zinterphp = "(z) * (d)";
713 zinterpunshift = Z_SHIFT + Z_INTERP_COEFF_SHIFT - Z_COEFF_SHIFT;
714 if (zinterpunshift > 0) {
715 v = (Z_ONE - 1) * abs(largest_interp);
716 if (v < INT32_MIN || v > INT32_MAX)
717 zinterphp = sprintf("(int64_t)%s", zinterphp);
718 zinterphp = sprintf("(%s) >> %d", zinterphp, zinterpunshift);
719 } else if (zinterpunshift < 0)
720 zinterphp = sprintf("(%s) << %d", zinterphp, \
721 abs(zinterpunshift));
722 if (Z_UNSHIFT == 0)
723 zinterp = "z";
724 else
725 zinterp = sprintf("(z) >> %d", Z_UNSHIFT);
726 zinterp = sprintf("(%s) * (d)", zinterp);
727 if (Z_INTERP_UNSHIFT < 0)
728 zinterp = sprintf("(%s) << %d", zinterp, \
729 abs(Z_INTERP_UNSHIFT));
730 else if (Z_INTERP_UNSHIFT > 0)
731 zinterp = sprintf("(%s) >> %d", zinterp, Z_INTERP_UNSHIFT);
732 if (zinterphp != zinterp) {
733 printf("\n#ifdef SND_FEEDER_RATE_HP\n");
734 printf("#define Z_COEFF_INTERPOLATE(z, c, d)" \
735 "\t\t\t\t\t\\\n\t((c) + (%s))\n", zinterphp);
736 printf("#else\n");
737 printf("#define Z_COEFF_INTERPOLATE(z, c, d)" \
738 "\t\t\t\t\t\\\n\t((c) + (%s))\n", zinterp);
739 printf("#endif\n");
740 } else
741 printf("#define Z_COEFF_INTERPOLATE(z, c, d)" \
742 "\t\t\t\t\t\\\n\t((c) + (%s))\n", zinterp);
743 #printf("\n");
744 #printf("#define Z_SCALE_SHIFT\t\t%d\n", Z_SCALE_SHIFT);
745 #printf("#define Z_SCALE_ONE\t\t0x%08x%s\n", Z_SCALE_ONE, \
746 # (Z_SCALE_ONE > INT32_MAX) ? "U" : "");
747 printf("\n");
748 printf("#define Z_SCALE_CAST(s)\t\t((uint32_t)(s))\n");
749 genscale(8);
750 genscale(16);
751 genscale(24);
752 genscale(32);
753 printf("\n");
715 ztab[imp["quality"] - 2] = \
716 mkfilter(imp, nmult, rolloff, beta, Z_DRIFT_ONE);
717 imp["quality"]++;
718 }
719 }
720
721 printf("\n");
722 #
723 # XXX
724 #
725 #if (length(ztab) > 0) {
726 # j = 0;
727 # for (i = 0; i < length(ztab); i++) {
728 # if (ztab[i] > j)
729 # j = ztab[i];
730 # }
731 # printf("static int32_t z_coeff_zero[%d] = {", j);
732 # for (i = 0; i < j; i++) {
733 # if ((i % 19) == 0)
734 # printf("\n");
735 # printf(" 0,");
736 # }
737 # printf("\n};\n\n");
738 #}
739 #
740 # XXX
741 #
742 printf("static const struct {\n");
743 printf("\tint32_t len;\n");
744 printf("\tint32_t *coeff;\n");
745 printf("\tint32_t *dcoeff;\n");
746 printf("} z_coeff_tab[] = {\n");
747 if (length(ztab) > 0) {
748 j = 0;
749 for (i = 0; i < length(ztab); i++) {
750 if (ztab[i] > j)
751 j = ztab[i];
752 }
753 j = length(sprintf("%d", j));
754 lfmt = sprintf("%%%dd", j);
755 j = length(sprintf("z_coeff_q%d", length(ztab) + 1));
756 zcfmt = sprintf("%%-%ds", j);
757 zdcfmt = sprintf("%%-%ds", j + 1);
758
759 for (i = 0; i < length(ztab); i++) {
760 l = sprintf(lfmt, ztab[i]);
761 zc = sprintf("z_coeff_q%d", i + 2);
762 zc = sprintf(zcfmt, zc);
763 zdc = sprintf("z_dcoeff_q%d", i + 2);
764 zdc = sprintf(zdcfmt, zdc);
765 printf("\t{ %s, %s, %s },\n", l, zc, zdc);
766 }
767 } else
768 printf("\t{ 0, NULL, NULL }\n");
769 printf("};\n\n");
770
771 #Z_UNSHIFT = 0;
772 #v = shr(Z_ONE - 1, Z_UNSHIFT) * abs(largest_interp);
773 #while (v < 0 || v > INT32_MAX) {
774 # Z_UNSHIFT += 1;
775 # v = shr(Z_ONE - 1, Z_UNSHIFT) * abs(largest_interp);
776 #}
777 v = ((Z_ONE - 1) * abs(largest_interp)) / INT32_MAX;
778 Z_UNSHIFT = ceil(log(v) / log(2.0));
779 Z_INTERP_SHIFT = Z_SHIFT - Z_UNSHIFT + Z_INTERP_COEFF_SHIFT;
780
781 Z_INTERP_UNSHIFT = (Z_SHIFT - Z_UNSHIFT) + Z_INTERP_COEFF_SHIFT \
782 - Z_COEFF_SHIFT;
783
784 printf("#define Z_COEFF_TAB_SIZE\t\t\t\t\t\t\\\n");
785 printf("\t((int32_t)(sizeof(z_coeff_tab) /");
786 printf(" sizeof(z_coeff_tab[0])))\n\n");
787 printf("#define Z_COEFF_OFFSET\t\t%d\n\n", Z_COEFF_OFFSET);
788 printf("#define Z_RSHIFT(x, y)\t\t(((x) + " \
789 "(1 << ((y) - 1))) >> (y))\n");
790 printf("#define Z_RSHIFT_L(x, y)\t(((x) + " \
791 "(1LL << ((y) - 1))) >> (y))\n\n");
792 printf("#define Z_FULL_SHIFT\t\t%d\n", Z_FULL_SHIFT);
793 printf("#define Z_FULL_ONE\t\t0x%08x%s\n", Z_FULL_ONE, \
794 (Z_FULL_ONE > INT32_MAX) ? "U" : "");
795 printf("\n");
796 printf("#define Z_DRIFT_SHIFT\t\t%d\n", Z_DRIFT_SHIFT);
797 #printf("#define Z_DRIFT_ONE\t\t0x%08x\n", Z_DRIFT_ONE);
798 printf("\n");
799 printf("#define Z_SHIFT\t\t\t%d\n", Z_SHIFT);
800 printf("#define Z_ONE\t\t\t0x%08x\n", Z_ONE);
801 printf("#define Z_MASK\t\t\t0x%08x\n", Z_MASK);
802 printf("\n");
803 printf("#define Z_COEFF_SHIFT\t\t%d\n", Z_COEFF_SHIFT);
804 zinterphp = "(z) * (d)";
805 zinterpunshift = Z_SHIFT + Z_INTERP_COEFF_SHIFT - Z_COEFF_SHIFT;
806 if (zinterpunshift > 0) {
807 v = (Z_ONE - 1) * abs(largest_interp);
808 if (v < INT32_MIN || v > INT32_MAX)
809 zinterphp = sprintf("(int64_t)%s", zinterphp);
810 zinterphp = sprintf("(%s) >> %d", zinterphp, zinterpunshift);
811 } else if (zinterpunshift < 0)
812 zinterphp = sprintf("(%s) << %d", zinterphp, \
813 abs(zinterpunshift));
814 if (Z_UNSHIFT == 0)
815 zinterp = "z";
816 else
817 zinterp = sprintf("(z) >> %d", Z_UNSHIFT);
818 zinterp = sprintf("(%s) * (d)", zinterp);
819 if (Z_INTERP_UNSHIFT < 0)
820 zinterp = sprintf("(%s) << %d", zinterp, \
821 abs(Z_INTERP_UNSHIFT));
822 else if (Z_INTERP_UNSHIFT > 0)
823 zinterp = sprintf("(%s) >> %d", zinterp, Z_INTERP_UNSHIFT);
824 if (zinterphp != zinterp) {
825 printf("\n#ifdef SND_FEEDER_RATE_HP\n");
826 printf("#define Z_COEFF_INTERPOLATE(z, c, d)" \
827 "\t\t\t\t\t\\\n\t((c) + (%s))\n", zinterphp);
828 printf("#else\n");
829 printf("#define Z_COEFF_INTERPOLATE(z, c, d)" \
830 "\t\t\t\t\t\\\n\t((c) + (%s))\n", zinterp);
831 printf("#endif\n");
832 } else
833 printf("#define Z_COEFF_INTERPOLATE(z, c, d)" \
834 "\t\t\t\t\t\\\n\t((c) + (%s))\n", zinterp);
835 #printf("\n");
836 #printf("#define Z_SCALE_SHIFT\t\t%d\n", Z_SCALE_SHIFT);
837 #printf("#define Z_SCALE_ONE\t\t0x%08x%s\n", Z_SCALE_ONE, \
838 # (Z_SCALE_ONE > INT32_MAX) ? "U" : "");
839 printf("\n");
840 printf("#define Z_SCALE_CAST(s)\t\t((uint32_t)(s))\n");
841 genscale(8);
842 genscale(16);
843 genscale(24);
844 genscale(32);
845 printf("\n");
846 printf("#define Z_ACCUMULATOR_BIT\t%d\n\n", Z_ACCUMULATOR_BIT)
847 for (i = 8; i <= 32; i += 8) {
848 gbit = ((i + Z_COEFF_SHIFT) > Z_ACCUMULATOR_BIT) ? \
849 (i - (Z_ACCUMULATOR_BIT - Z_COEFF_SHIFT)) : 0;
850 printf("#define Z_GUARD_BIT_%d\t\t%d\n", i, gbit);
851 if (gbit == 0)
852 printf("#define Z_NORM_%d(v)\t\t(v)\n\n", i);
853 else
854 printf("#define Z_NORM_%d(v)\t\t" \
855 "((v) >> Z_GUARD_BIT_%d)\n\n", i, i);
856 }
857 printf("\n");
754 printf("#define Z_LINEAR_FULL_ONE\t0x%08xU\n", Z_LINEAR_FULL_ONE);
755 printf("#define Z_LINEAR_SHIFT\t\t%d\n", Z_LINEAR_SHIFT);
756 printf("#define Z_LINEAR_UNSHIFT\t%d\n", Z_LINEAR_UNSHIFT);
757 printf("#define Z_LINEAR_ONE\t\t0x%08x\n", Z_LINEAR_ONE);
758 printf("\n");
759 printf("#ifdef SND_PCM_64\n");
760 genlerp(8, 1);
761 genlerp(16, 1);
762 genlerp(24, 1);
763 genlerp(32, 1);
764 printf("#else\t/* !SND_PCM_64 */\n");
765 genlerp(8, 0);
766 genlerp(16, 0);
767 genlerp(24, 0);
768 genlerp(32, 0);
769 printf("#endif\t/* SND_PCM_64 */\n");
770 printf("\n");
771 printf("#define Z_QUALITY_ZOH\t\t0\n");
772 printf("#define Z_QUALITY_LINEAR\t1\n");
773 printf("#define Z_QUALITY_SINC\t\t%d\n", \
774 floor((length(ztab) - 1) / 2) + 2);
775 printf("\n");
776 printf("#define Z_QUALITY_MIN\t\t0\n");
777 printf("#define Z_QUALITY_MAX\t\t%d\n", length(ztab) + 1);
858 printf("#define Z_LINEAR_FULL_ONE\t0x%08xU\n", Z_LINEAR_FULL_ONE);
859 printf("#define Z_LINEAR_SHIFT\t\t%d\n", Z_LINEAR_SHIFT);
860 printf("#define Z_LINEAR_UNSHIFT\t%d\n", Z_LINEAR_UNSHIFT);
861 printf("#define Z_LINEAR_ONE\t\t0x%08x\n", Z_LINEAR_ONE);
862 printf("\n");
863 printf("#ifdef SND_PCM_64\n");
864 genlerp(8, 1);
865 genlerp(16, 1);
866 genlerp(24, 1);
867 genlerp(32, 1);
868 printf("#else\t/* !SND_PCM_64 */\n");
869 genlerp(8, 0);
870 genlerp(16, 0);
871 genlerp(24, 0);
872 genlerp(32, 0);
873 printf("#endif\t/* SND_PCM_64 */\n");
874 printf("\n");
875 printf("#define Z_QUALITY_ZOH\t\t0\n");
876 printf("#define Z_QUALITY_LINEAR\t1\n");
877 printf("#define Z_QUALITY_SINC\t\t%d\n", \
878 floor((length(ztab) - 1) / 2) + 2);
879 printf("\n");
880 printf("#define Z_QUALITY_MIN\t\t0\n");
881 printf("#define Z_QUALITY_MAX\t\t%d\n", length(ztab) + 1);
882 if (Z_COEFF_INTERPOLATOR != 0)
883 printf("\n#define Z_COEFF_INTERP_%s\t1\n", \
884 Z_COEFF_INTERPOLATOR);
778 printf("\n/*\n * smallest: %.32f\n * largest: %.32f\n *\n", \
779 smallest, largest);
780 printf(" * z_unshift=%d, z_interp_shift=%d\n *\n", \
781 Z_UNSHIFT, Z_INTERP_SHIFT);
782 v = shr(Z_ONE - 1, Z_UNSHIFT) * abs(largest_interp);
783 printf(" * largest interpolation multiplication: %d\n */\n", v);
784 if (v < INT32_MIN || v > INT32_MAX) {
785 printf("\n#ifndef SND_FEEDER_RATE_HP\n");
786 printf("#error interpolation overflow, please reduce" \
787 " Z_INTERP_SHIFT\n");
788 printf("#endif\n");
789 }
790
791 printf("\n#endif /* !_FEEDER_RATE_GEN_H_ */\n");
792}
885 printf("\n/*\n * smallest: %.32f\n * largest: %.32f\n *\n", \
886 smallest, largest);
887 printf(" * z_unshift=%d, z_interp_shift=%d\n *\n", \
888 Z_UNSHIFT, Z_INTERP_SHIFT);
889 v = shr(Z_ONE - 1, Z_UNSHIFT) * abs(largest_interp);
890 printf(" * largest interpolation multiplication: %d\n */\n", v);
891 if (v < INT32_MIN || v > INT32_MAX) {
892 printf("\n#ifndef SND_FEEDER_RATE_HP\n");
893 printf("#error interpolation overflow, please reduce" \
894 " Z_INTERP_SHIFT\n");
895 printf("#endif\n");
896 }
897
898 printf("\n#endif /* !_FEEDER_RATE_GEN_H_ */\n");
899}