static void filter(priv_t * p) { int i, num_in = max(0, fifo_occupancy(&p->input_fifo)); filter_t const * f = p->filter_ptr; int const overlap = f->num_taps - 1; double * output; while (num_in >= f->dft_length) { double const * input = fifo_read_ptr(&p->input_fifo); fifo_read(&p->input_fifo, f->dft_length - overlap, NULL); num_in -= f->dft_length - overlap; output = fifo_reserve(&p->output_fifo, f->dft_length); fifo_trim_by(&p->output_fifo, overlap); memcpy(output, input, f->dft_length * sizeof(*output)); lsx_safe_rdft(f->dft_length, 1, output); output[0] *= f->coefs[0]; output[1] *= f->coefs[1]; for (i = 2; i < f->dft_length; i += 2) { double tmp = output[i]; output[i ] = f->coefs[i ] * tmp - f->coefs[i+1] * output[i+1]; output[i+1] = f->coefs[i+1] * tmp + f->coefs[i ] * output[i+1]; } lsx_safe_rdft(f->dft_length, -1, output); } }
void lsx_set_dft_filter(dft_filter_t *f, double *h, int n, int post_peak) { int i; f->num_taps = n; f->post_peak = post_peak; f->dft_length = lsx_set_dft_length(f->num_taps); f->coefs = lsx_calloc(f->dft_length, sizeof(*f->coefs)); for (i = 0; i < f->num_taps; ++i) f->coefs[(i + f->dft_length - f->num_taps + 1) & (f->dft_length - 1)] = h[i] / f->dft_length * 2; lsx_safe_rdft(f->dft_length, 1, f->coefs); free(h); }