paddlec 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,724 @@
1
+ /* Copyright (C) 2019 Théotime Bollengier <theotime.bollengier@gmail.com>
2
+ *
3
+ * This file is part of PaddleC
4
+ *
5
+ * PaddleC is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * PaddleC is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with PaddleC. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ #include <stdlib.h>
20
+ #include <stdio.h>
21
+ #include <string.h>
22
+ #include <math.h>
23
+ #include "libpaddlec.h"
24
+
25
+
26
+ pdlc_fir_filter_t* pdlc_fir_filter_new(int order)
27
+ {
28
+ pdlc_fir_filter_t *fir;
29
+
30
+ fir = malloc(sizeof(pdlc_fir_filter_t));
31
+
32
+ fir->coefs = NULL;
33
+ fir->stater = NULL;
34
+ fir->statei = NULL;
35
+ fir->nb_coefs = 0;
36
+ fir->state_len = 0;
37
+ fir->coef_len = 0;
38
+ fir->index = 0;
39
+ fir->index_mask = 0;
40
+ fir->counter = 0;
41
+ fir->max_counter = 1;
42
+
43
+ if (order >= 0)
44
+ pdlc_fir_filter_initialize(fir, order);
45
+
46
+ return fir;
47
+ }
48
+
49
+
50
+ int pdlc_fir_filter_get_coef_at(const pdlc_fir_filter_t* fir, int index, float *value)
51
+ {
52
+ if (index < 0 || index >= (int)fir->nb_coefs)
53
+ return -1;
54
+
55
+ if (value)
56
+ *value = fir->coefs[0][fir->nb_coefs - 1 - index];
57
+
58
+ return 0;
59
+ }
60
+
61
+
62
+ void pdlc_fir_filter_reset(pdlc_fir_filter_t* fir)
63
+ {
64
+ memset(fir->stater, 0, fir->coef_len * sizeof(float));
65
+ memset(fir->statei, 0, fir->coef_len * sizeof(float));
66
+ fir->index = 0;
67
+ fir->counter = 0;
68
+ }
69
+
70
+
71
+ int pdlc_fir_filter_get_factor(const pdlc_fir_filter_t* fir)
72
+ {
73
+ return fir->max_counter;
74
+ }
75
+
76
+
77
+ void pdlc_fir_filter_interpolator_initialize(pdlc_fir_filter_t* fir, int order, int factor)
78
+ {
79
+ pdlc_fir_filter_initialize(fir, order);
80
+
81
+ if (factor < 1)
82
+ factor = 1;
83
+ if (factor > 32)
84
+ factor = 32;
85
+
86
+ fir->max_counter = factor;
87
+ }
88
+
89
+
90
+ void pdlc_fir_filter_decimator_initialize(pdlc_fir_filter_t* fir, int order, int factor)
91
+ {
92
+ pdlc_fir_filter_initialize(fir, order);
93
+
94
+ if (factor < 1)
95
+ factor = 1;
96
+ if (factor > 32)
97
+ factor = 32;
98
+
99
+ fir->max_counter = factor;
100
+ }
101
+
102
+
103
+ #if defined __AVX__
104
+ #include "fir_filter_avx.c"
105
+ #elif defined __SSE__
106
+ #include "fir_filter_sse.c"
107
+ #elif (defined __ARM_NEON) && ((__ARM_NEON_FP & 4) == 4)
108
+ #include "fir_filter_neon.c"
109
+ #else
110
+
111
+
112
+ void pdlc_fir_filter_inspect(pdlc_fir_filter_t* fir)
113
+ {
114
+ size_t i;
115
+ printf("nb_coefs: %u, state_len: %u, coef_len: %u, index_mask: %x, index: %u\n",
116
+ fir->nb_coefs, fir->state_len, fir->coef_len, fir->index_mask, fir->index);
117
+ printf("state: [%.7g", fir->stater[0]);
118
+ for (i = 1; i < fir->state_len; i++)
119
+ printf(", %.7g", fir->stater[i]);
120
+ printf("]\ncoefs: [%.7g", fir->coefs[0][0]);
121
+ for (i = 1; i < fir->coef_len; i++)
122
+ printf(", %.7g", fir->coefs[0][i]);
123
+ printf("]\n");
124
+ }
125
+
126
+
127
+ void pdlc_fir_filter_initialize(pdlc_fir_filter_t* fir, int order)
128
+ {
129
+ if (fir->coefs) {
130
+ if (fir->coefs[0])
131
+ free(fir->coefs[0]);
132
+ free(fir->coefs);
133
+ fir->coefs = NULL;
134
+ }
135
+
136
+ if (fir->stater)
137
+ free(fir->stater);
138
+ fir->stater = NULL;
139
+
140
+ if (fir->statei)
141
+ free(fir->statei);
142
+ fir->statei = NULL;
143
+
144
+ fir->nb_coefs = 0;
145
+ fir->state_len = 0;
146
+ fir->coef_len = 0;
147
+ fir->index = 0;
148
+ fir->index_mask = 0;
149
+ fir->counter = 0;
150
+ fir->max_counter = 1;
151
+
152
+ if (order < 0)
153
+ return;
154
+
155
+ if (order > 67108863) {
156
+ fprintf(stderr, "ERROR: libpaddlec: Filter order cannot be greater than 67108864\n");
157
+ exit(EXIT_FAILURE);
158
+ }
159
+
160
+ fir->nb_coefs = (unsigned int)(order + 1);
161
+ fir->state_len = (unsigned int)(pow(2.0, ceil(log2(fir->nb_coefs))));
162
+ fir->coef_len = fir->nb_coefs;
163
+ fir->index = 0;
164
+ fir->index_mask = fir->state_len - 1;
165
+
166
+ fir->coefs = malloc(1*sizeof(float*));
167
+ if (fir->coefs == NULL) {
168
+ fprintf(stderr, "ERROR: libpaddlec: Cannot allocate %lu bytes for FIR!\n", 1 * sizeof(float*));
169
+ exit(EXIT_FAILURE);
170
+ }
171
+
172
+ fir->coefs[0] = malloc(fir->coef_len * sizeof(float));
173
+ if (fir->coefs[0] == NULL) {
174
+ fprintf(stderr, "ERROR: libpaddlec: Cannot allocate %lu bytes for FIR!\n", fir->coef_len * sizeof(float));
175
+ exit(EXIT_FAILURE);
176
+ }
177
+
178
+ fir->stater = malloc(fir->state_len * sizeof(float));
179
+ if (fir->stater == NULL) {
180
+ fprintf(stderr, "ERROR: libpaddlec: Cannot allocate %lu bytes for FIR!\n", fir->state_len * sizeof(float));
181
+ exit(EXIT_FAILURE);
182
+ }
183
+
184
+ fir->statei = malloc(fir->state_len * sizeof(float));
185
+ if (fir->statei == NULL) {
186
+ fprintf(stderr, "ERROR: libpaddlec: Cannot allocate %lu bytes for FIR!\n", fir->state_len * sizeof(float));
187
+ exit(EXIT_FAILURE);
188
+ }
189
+
190
+ memset(fir->stater, 0, fir->state_len * sizeof(float));
191
+ memset(fir->statei, 0, fir->state_len * sizeof(float));
192
+ memset(fir->coefs[0], 0, fir->coef_len * sizeof(float));
193
+ }
194
+
195
+
196
+ void pdlc_fir_filter_free(pdlc_fir_filter_t* fir)
197
+ {
198
+ if (!fir)
199
+ return;
200
+
201
+ if (fir->coefs) {
202
+ if (fir->coefs[0])
203
+ free(fir->coefs[0]);
204
+ free(fir->coefs);
205
+ }
206
+
207
+ if (fir->stater)
208
+ free(fir->stater);
209
+
210
+ if (fir->statei)
211
+ free(fir->statei);
212
+
213
+ free(fir);
214
+ }
215
+
216
+
217
+ size_t pdlc_fir_filter_size(pdlc_fir_filter_t* fir)
218
+ {
219
+ size_t res;
220
+
221
+ res = sizeof(pdlc_fir_filter_t);
222
+ res += sizeof(float*);
223
+ res += sizeof(float) * fir->state_len * 2;
224
+ res += sizeof(float) * fir->coef_len * 1;
225
+
226
+ return res;
227
+ }
228
+
229
+
230
+ int pdlc_fir_filter_set_coef_at(pdlc_fir_filter_t* fir, int index, float value)
231
+ {
232
+ if (index < 0 || index >= (int)fir->nb_coefs)
233
+ return -1;
234
+
235
+ fir->coefs[0][fir->nb_coefs - 1 - index] = value;
236
+
237
+ return 0;
238
+ }
239
+
240
+
241
+ float pdlc_fir_filter_filter_float(pdlc_fir_filter_t* fir, float sample, float *delayed)
242
+ {
243
+ const unsigned int nb_coefs = fir->nb_coefs;
244
+ const unsigned int flt_len = fir->state_len;
245
+ const unsigned int mask = fir->index_mask;
246
+ const unsigned int start_index = (flt_len + fir->index + 1 - nb_coefs) & mask;
247
+ const unsigned int middle_index = (start_index + nb_coefs / 2) & mask;
248
+ const float *coefs = fir->coefs[0];
249
+ float acc = 0.0f;
250
+ unsigned int i, j;
251
+
252
+ fir->stater[fir->index] = sample;
253
+ //pdlc_fir_filter_inspect(fir);
254
+ fir->index = (fir->index + 1) & mask;
255
+
256
+ if (delayed) {
257
+ if (nb_coefs & 1)
258
+ *delayed = fir->stater[middle_index];
259
+ else
260
+ *delayed = (fir->stater[middle_index] + fir->stater[(middle_index - 1) & mask]) / 2.0f;
261
+ }
262
+
263
+ j = start_index;
264
+ for (i = 0; i < nb_coefs; i++) {
265
+ acc += coefs[i] * fir->stater[j];
266
+ j = (j+1) & mask;
267
+ }
268
+
269
+ return acc;
270
+ }
271
+
272
+
273
+ pdlc_complex_t pdlc_fir_filter_filter_complex(pdlc_fir_filter_t* fir, pdlc_complex_t sample, pdlc_complex_t *delayed)
274
+ {
275
+ const unsigned int nb_coefs = fir->nb_coefs;
276
+ const unsigned int flt_len = fir->state_len;
277
+ const unsigned int mask = fir->index_mask;
278
+ const unsigned int start_index = (flt_len + fir->index + 1 - nb_coefs) & mask;
279
+ const unsigned int middle_index = (start_index + nb_coefs / 2) & mask;
280
+ const float *coefs = fir->coefs[0];
281
+ pdlc_complex_t acc = {0.0f, 0.0f};
282
+ unsigned int i, j;
283
+
284
+ fir->stater[fir->index] = sample.real;
285
+ fir->statei[fir->index] = sample.imag;
286
+ fir->index = (fir->index + 1) & mask;
287
+
288
+ j = start_index;
289
+ for (i = 0; i < nb_coefs; i++) {
290
+ acc.real += coefs[i] * fir->stater[j];
291
+ acc.imag += coefs[i] * fir->statei[j];
292
+ j = (j+1) & mask;
293
+ }
294
+
295
+ if (delayed) {
296
+ if (nb_coefs & 1) {
297
+ delayed->real = fir->stater[middle_index];
298
+ delayed->imag = fir->statei[middle_index];
299
+ }
300
+ else {
301
+ delayed->real = (fir->stater[middle_index] + fir->stater[(middle_index - 1) & mask]) / 2.0f;
302
+ delayed->imag = (fir->statei[middle_index] + fir->statei[(middle_index - 1) & mask]) / 2.0f;
303
+ }
304
+ }
305
+
306
+ return acc;
307
+ }
308
+
309
+
310
+ pdlc_buffer_t* pdlc_fir_filter_filter_float_buffer(pdlc_fir_filter_t* fir, const pdlc_buffer_t *ifbuf, pdlc_buffer_t *ofbuf, pdlc_buffer_t *delayed)
311
+ {
312
+ const unsigned int nb_coefs = fir->nb_coefs;
313
+ const unsigned int flt_len = fir->state_len;
314
+ const unsigned int mask = fir->index_mask;
315
+ const float *coefs = fir->coefs[0];
316
+ unsigned int start_index = (flt_len + fir->index + 1 - nb_coefs) & mask;
317
+ unsigned int middle_index;
318
+ float acc;
319
+ unsigned int i, j;
320
+ size_t k;
321
+
322
+ if (!ofbuf)
323
+ ofbuf = pdlc_buffer_new(ifbuf->length);
324
+ else if (ofbuf->length != ifbuf->length)
325
+ pdlc_buffer_resize(ofbuf, ifbuf->length, 0);
326
+
327
+ if (delayed) {
328
+ if (delayed->length != ifbuf->length)
329
+ pdlc_buffer_resize(delayed, ifbuf->length, 0);
330
+ middle_index = (start_index + nb_coefs / 2) & mask;
331
+ if (nb_coefs & 1) {
332
+ for (k = 0; k < ifbuf->length; k++) {
333
+ fir->stater[fir->index] = ifbuf->data[k];
334
+ fir->index = (fir->index + 1) & mask;
335
+ acc = 0.0f;
336
+ j = start_index;
337
+ for (i = 0; i < nb_coefs; i++) {
338
+ acc += coefs[i] * fir->stater[j];
339
+ j = (j+1) & mask;
340
+ }
341
+ ofbuf->data[k] = acc;
342
+ start_index = (start_index + 1) & mask;
343
+ delayed->data[k] = fir->stater[middle_index];
344
+ middle_index = (middle_index + 1) & mask;
345
+ }
346
+ }
347
+ else {
348
+ for (k = 0; k < ifbuf->length; k++) {
349
+ fir->stater[fir->index] = ifbuf->data[k];
350
+ fir->index = (fir->index + 1) & mask;
351
+ acc = 0.0f;
352
+ j = start_index;
353
+ for (i = 0; i < nb_coefs; i++) {
354
+ acc += coefs[i] * fir->stater[j];
355
+ j = (j+1) & mask;
356
+ }
357
+ ofbuf->data[k] = acc;
358
+ start_index = (start_index + 1) & mask;
359
+ delayed->data[k] = (fir->stater[middle_index] + fir->stater[(middle_index - 1) & mask]) / 2.0f;
360
+ middle_index = (middle_index + 1) & mask;
361
+ }
362
+ }
363
+ }
364
+ else {
365
+ for (k = 0; k < ifbuf->length; k++) {
366
+ fir->stater[fir->index] = ifbuf->data[k];
367
+ fir->index = (fir->index + 1) & mask;
368
+ acc = 0.0f;
369
+ j = start_index;
370
+ for (i = 0; i < nb_coefs; i++) {
371
+ acc += coefs[i] * fir->stater[j];
372
+ j = (j+1) & mask;
373
+ }
374
+ ofbuf->data[k] = acc;
375
+ start_index = (start_index + 1) & mask;
376
+ }
377
+ }
378
+
379
+ return ofbuf;
380
+ }
381
+
382
+
383
+ pdlc_complex_buffer_t* pdlc_fir_filter_filter_complex_buffer(pdlc_fir_filter_t* fir, const pdlc_complex_buffer_t *icbuf, pdlc_complex_buffer_t *ocbuf, pdlc_complex_buffer_t *delayed)
384
+ {
385
+ const unsigned int nb_coefs = fir->nb_coefs;
386
+ const unsigned int flt_len = fir->state_len;
387
+ const unsigned int mask = fir->index_mask;
388
+ const float *coefs = fir->coefs[0];
389
+ unsigned int start_index = (flt_len + fir->index + 1 - nb_coefs) & mask;
390
+ unsigned int middle_index;
391
+ pdlc_complex_t acc;
392
+ unsigned int i, j;
393
+ size_t k;
394
+
395
+ if (!ocbuf)
396
+ ocbuf = pdlc_complex_buffer_new(icbuf->length);
397
+ else if (ocbuf->length != icbuf->length)
398
+ pdlc_complex_buffer_resize(ocbuf, icbuf->length, 0);
399
+
400
+ if (delayed) {
401
+ if (delayed->length != icbuf->length)
402
+ pdlc_complex_buffer_resize(delayed, icbuf->length, 0);
403
+ middle_index = (start_index + nb_coefs / 2) & mask;
404
+ if (nb_coefs & 1) {
405
+ for (k = 0; k < icbuf->length; k++) {
406
+ fir->stater[fir->index] = icbuf->data[k].real;
407
+ fir->statei[fir->index] = icbuf->data[k].imag;
408
+ fir->index = (fir->index + 1) & mask;
409
+ acc.real = 0.0f;
410
+ acc.imag = 0.0f;
411
+ j = start_index;
412
+ for (i = 0; i < nb_coefs; i++) {
413
+ acc.real += coefs[i] * fir->stater[j];
414
+ acc.imag += coefs[i] * fir->statei[j];
415
+ j = (j+1) & mask;
416
+ }
417
+ ocbuf->data[k] = acc;
418
+ start_index = (start_index + 1) & mask;
419
+ delayed->data[k].real = fir->stater[middle_index];
420
+ delayed->data[k].imag = fir->statei[middle_index];
421
+ middle_index = (middle_index + 1) & mask;
422
+ }
423
+ }
424
+ else {
425
+ for (k = 0; k < icbuf->length; k++) {
426
+ fir->stater[fir->index] = icbuf->data[k].real;
427
+ fir->statei[fir->index] = icbuf->data[k].imag;
428
+ fir->index = (fir->index + 1) & mask;
429
+ acc.real = 0.0f;
430
+ acc.imag = 0.0f;
431
+ j = start_index;
432
+ for (i = 0; i < nb_coefs; i++) {
433
+ acc.real += coefs[i] * fir->stater[j];
434
+ acc.imag += coefs[i] * fir->statei[j];
435
+ j = (j+1) & mask;
436
+ }
437
+ ocbuf->data[k] = acc;
438
+ start_index = (start_index + 1) & mask;
439
+ delayed->data[k].real = (fir->stater[middle_index] + fir->stater[(middle_index - 1) & mask]) / 2.0f;
440
+ delayed->data[k].imag = (fir->statei[middle_index] + fir->statei[(middle_index - 1) & mask]) / 2.0f;
441
+ middle_index = (middle_index + 1) & mask;
442
+ }
443
+ }
444
+ }
445
+ else {
446
+ for (k = 0; k < icbuf->length; k++) {
447
+ fir->stater[fir->index] = icbuf->data[k].real;
448
+ fir->statei[fir->index] = icbuf->data[k].imag;
449
+ fir->index = (fir->index + 1) & mask;
450
+ acc.real = 0.0f;
451
+ acc.imag = 0.0f;
452
+ j = start_index;
453
+ for (i = 0; i < nb_coefs; i++) {
454
+ acc.real += coefs[i] * fir->stater[j];
455
+ acc.imag += coefs[i] * fir->statei[j];
456
+ j = (j+1) & mask;
457
+ }
458
+ ocbuf->data[k] = acc;
459
+ start_index = (start_index + 1) & mask;
460
+ }
461
+ }
462
+
463
+ return ocbuf;
464
+ }
465
+
466
+
467
+ pdlc_buffer_t* pdlc_fir_filter_interpolate_float_buffer(pdlc_fir_filter_t* fir, const pdlc_buffer_t *ifbuf, pdlc_buffer_t *ofbuf)
468
+ {
469
+ const unsigned int nb_coefs = fir->nb_coefs;
470
+ const unsigned int flt_len = fir->state_len;
471
+ const unsigned int mask = fir->index_mask;
472
+ const float *coefs = fir->coefs[0];
473
+ const float ffactor = (float)(fir->max_counter);
474
+ const size_t ibuflen = ifbuf->length;
475
+ const size_t obuflen = ibuflen*fir->max_counter;
476
+ float *stater = fir->stater;
477
+ unsigned int start_index = (flt_len + fir->index + 1 - nb_coefs) & mask;
478
+ float acc;
479
+ unsigned int i, j;
480
+ size_t k, l;
481
+ int m;
482
+
483
+ if (!ofbuf)
484
+ ofbuf = pdlc_buffer_new(obuflen);
485
+ else if (ofbuf->length != obuflen)
486
+ pdlc_buffer_resize(ofbuf, obuflen, 0);
487
+
488
+ for (k = 0, l = 0; k < ibuflen; k++) {
489
+ stater[fir->index] = ifbuf->data[k];
490
+ fir->index = (fir->index + 1) & mask;
491
+ acc = 0.0f;
492
+ j = start_index;
493
+ for (i = 0; i < nb_coefs; i++) {
494
+ acc += coefs[i] * stater[j];
495
+ j = (j+1) & mask;
496
+ }
497
+ ofbuf->data[l++] = acc * ffactor;
498
+ start_index = (start_index + 1) & mask;
499
+
500
+ for (m = 1; m < fir->max_counter; m++) {
501
+ stater[fir->index] = 0.0f;
502
+ fir->index = (fir->index + 1) & mask;
503
+ acc = 0.0f;
504
+ j = start_index;
505
+ for (i = 0; i < nb_coefs; i++) {
506
+ acc += coefs[i] * stater[j];
507
+ j = (j+1) & mask;
508
+ }
509
+ ofbuf->data[l++] = acc * ffactor;
510
+ start_index = (start_index + 1) & mask;
511
+ }
512
+ }
513
+
514
+ return ofbuf;
515
+ }
516
+
517
+
518
+ pdlc_complex_buffer_t* pdlc_fir_filter_interpolate_complex_buffer(pdlc_fir_filter_t* fir, const pdlc_complex_buffer_t *icbuf, pdlc_complex_buffer_t *ocbuf)
519
+ {
520
+ const unsigned int nb_coefs = fir->nb_coefs;
521
+ const unsigned int flt_len = fir->state_len;
522
+ const unsigned int mask = fir->index_mask;
523
+ const float *coefs = fir->coefs[0];
524
+ const float ffactor = (float)(fir->max_counter);
525
+ const size_t ibuflen = icbuf->length;
526
+ const size_t obuflen = ibuflen*fir->max_counter;
527
+ float *stater = fir->stater;
528
+ float *statei = fir->statei;
529
+ unsigned int start_index = (flt_len + fir->index + 1 - nb_coefs) & mask;
530
+ float accr, acci;
531
+ unsigned int i, j;
532
+ size_t k, l;
533
+ int m;
534
+
535
+ if (!ocbuf)
536
+ ocbuf = pdlc_complex_buffer_new(obuflen);
537
+ else if (ocbuf->length != obuflen)
538
+ pdlc_complex_buffer_resize(ocbuf, obuflen, 0);
539
+
540
+ for (k = 0, l = 0; k < ibuflen; k++) {
541
+ stater[fir->index] = icbuf->data[k].real;
542
+ statei[fir->index] = icbuf->data[k].imag;
543
+ fir->index = (fir->index + 1) & mask;
544
+ accr = 0.0f;
545
+ acci = 0.0f;
546
+ j = start_index;
547
+ for (i = 0; i < nb_coefs; i++) {
548
+ accr += coefs[i] * stater[j];
549
+ acci += coefs[i] * statei[j];
550
+ j = (j+1) & mask;
551
+ }
552
+ ocbuf->data[l].real = accr * ffactor;
553
+ ocbuf->data[l++].imag = acci * ffactor;
554
+ start_index = (start_index + 1) & mask;
555
+
556
+ for (m = 1; m < fir->max_counter; m++) {
557
+ stater[fir->index] = 0.0f;
558
+ statei[fir->index] = 0.0f;
559
+ fir->index = (fir->index + 1) & mask;
560
+ accr = 0.0f;
561
+ acci = 0.0f;
562
+ j = start_index;
563
+ for (i = 0; i < nb_coefs; i++) {
564
+ accr += coefs[i] * stater[j];
565
+ acci += coefs[i] * statei[j];
566
+ j = (j+1) & mask;
567
+ }
568
+ ocbuf->data[l].real = accr * ffactor;
569
+ ocbuf->data[l++].imag = acci * ffactor;
570
+ start_index = (start_index + 1) & mask;
571
+ }
572
+ }
573
+
574
+ return ocbuf;
575
+ }
576
+
577
+
578
+ pdlc_buffer_t* pdlc_fir_filter_decimate_float_buffer(pdlc_fir_filter_t* fir, const pdlc_buffer_t *ifbuf, pdlc_buffer_t *ofbuf)
579
+ {
580
+ const unsigned int nb_coefs = fir->nb_coefs;
581
+ const unsigned int flt_len = fir->state_len;
582
+ const unsigned int mask = fir->index_mask;
583
+ const float *coefs = fir->coefs[0];
584
+ const size_t ibuflen = ifbuf->length;
585
+ const int mcounter = fir->max_counter;
586
+ const size_t obuflen = (size_t)ceil(((double)ibuflen - (double)((mcounter - fir->counter) % mcounter)) / (double)mcounter);
587
+ unsigned int start_index = (flt_len + fir->index + 1 - nb_coefs) & mask;
588
+ float *stater = fir->stater;
589
+ float acc;
590
+ unsigned int i, j;
591
+ size_t k, l;
592
+
593
+
594
+ if (!ofbuf)
595
+ ofbuf = pdlc_buffer_new(obuflen);
596
+ else if (ofbuf->length != obuflen)
597
+ pdlc_buffer_resize(ofbuf, obuflen, 0);
598
+
599
+
600
+ for (k = 0, l = 0; k < ibuflen; k++) {
601
+ stater[fir->index] = ifbuf->data[k];
602
+ fir->index = (fir->index + 1) & mask;
603
+ if (fir->counter == 0) {
604
+ acc = 0.0f;
605
+ j = start_index;
606
+ for (i = 0; i < nb_coefs; i++) {
607
+ acc += coefs[i] * stater[j];
608
+ j = (j+1) & mask;
609
+ }
610
+ ofbuf->data[l++] = acc;
611
+ }
612
+ start_index = (start_index + 1) & mask;
613
+ fir->counter = (fir->counter + 1) % mcounter;
614
+ }
615
+
616
+ return ofbuf;
617
+ }
618
+
619
+
620
+ pdlc_complex_buffer_t* pdlc_fir_filter_decimate_complex_buffer(pdlc_fir_filter_t* fir, const pdlc_complex_buffer_t *icbuf, pdlc_complex_buffer_t *ocbuf)
621
+ {
622
+ const unsigned int nb_coefs = fir->nb_coefs;
623
+ const unsigned int flt_len = fir->state_len;
624
+ const unsigned int mask = fir->index_mask;
625
+ const float *coefs = fir->coefs[0];
626
+ const size_t ibuflen = icbuf->length;
627
+ const int mcounter = fir->max_counter;
628
+ const size_t obuflen = (size_t)ceil(((double)ibuflen - (double)((mcounter - fir->counter) % mcounter)) / (double)mcounter);
629
+ unsigned int start_index = (flt_len + fir->index + 1 - nb_coefs) & mask;
630
+ float *stater = fir->stater;
631
+ float *statei = fir->statei;
632
+ float accr, acci;
633
+ unsigned int i, j;
634
+ size_t k, l;
635
+
636
+
637
+ if (!ocbuf)
638
+ ocbuf = pdlc_complex_buffer_new(obuflen);
639
+ else if (ocbuf->length != obuflen)
640
+ pdlc_complex_buffer_resize(ocbuf, obuflen, 0);
641
+
642
+
643
+ for (k = 0, l = 0; k < ibuflen; k++) {
644
+ stater[fir->index] = icbuf->data[k].real;
645
+ statei[fir->index] = icbuf->data[k].imag;
646
+ fir->index = (fir->index + 1) & mask;
647
+ if (fir->counter == 0) {
648
+ accr = 0.0f;
649
+ acci = 0.0f;
650
+ j = start_index;
651
+ for (i = 0; i < nb_coefs; i++) {
652
+ accr += coefs[i] * stater[j];
653
+ acci += coefs[i] * statei[j];
654
+ j = (j+1) & mask;
655
+ }
656
+ ocbuf->data[l].real = accr;
657
+ ocbuf->data[l].imag = acci;
658
+ l++;
659
+ }
660
+ start_index = (start_index + 1) & mask;
661
+ fir->counter = (fir->counter + 1) % mcounter;
662
+ }
663
+
664
+ return ocbuf;
665
+ }
666
+
667
+
668
+ pdlc_complex_buffer_t* pdlc_fir_filter_transform(pdlc_fir_filter_t* fir, const pdlc_buffer_t *ifbuf, pdlc_complex_buffer_t *ocbuf)
669
+ {
670
+ const unsigned int nb_coefs = fir->nb_coefs;
671
+ const unsigned int flt_len = fir->state_len;
672
+ const unsigned int mask = fir->index_mask;
673
+ const float *coefs = fir->coefs[0];
674
+ unsigned int start_index = (flt_len + fir->index + 1 - nb_coefs) & mask;
675
+ unsigned int middle_index = (start_index + nb_coefs / 2) & mask;
676
+ float acc;
677
+ unsigned int i, j;
678
+ size_t k;
679
+
680
+ if (!ocbuf)
681
+ ocbuf = pdlc_complex_buffer_new(ifbuf->length);
682
+ else if (ocbuf->length != ifbuf->length)
683
+ pdlc_complex_buffer_resize(ocbuf, ifbuf->length, 0);
684
+
685
+
686
+ if (nb_coefs & 1) {
687
+ for (k = 0; k < ifbuf->length; k++) {
688
+ fir->stater[fir->index] = ifbuf->data[k];
689
+ fir->index = (fir->index + 1) & mask;
690
+ acc = 0.0f;
691
+ j = start_index;
692
+ for (i = 0; i < nb_coefs; i++) {
693
+ acc += coefs[i] * fir->stater[j];
694
+ j = (j+1) & mask;
695
+ }
696
+ ocbuf->data[k].imag = acc;
697
+ ocbuf->data[k].real = fir->stater[middle_index];
698
+ start_index = (start_index + 1) & mask;
699
+ middle_index = (middle_index + 1) & mask;
700
+ }
701
+ }
702
+ else {
703
+ for (k = 0; k < ifbuf->length; k++) {
704
+ fir->stater[fir->index] = ifbuf->data[k];
705
+ fir->index = (fir->index + 1) & mask;
706
+ acc = 0.0f;
707
+ j = start_index;
708
+ for (i = 0; i < nb_coefs; i++) {
709
+ acc += coefs[i] * fir->stater[j];
710
+ j = (j+1) & mask;
711
+ }
712
+ ocbuf->data[k].imag = acc;
713
+ ocbuf->data[k].real = (fir->stater[middle_index] + fir->stater[(middle_index - 1) & mask]) / 2.0f;
714
+ start_index = (start_index + 1) & mask;
715
+ middle_index = (middle_index + 1) & mask;
716
+ }
717
+ }
718
+
719
+ return ocbuf;
720
+ }
721
+
722
+
723
+ #endif
724
+