static int start(sox_effect_t * effp) { priv_t * p = (priv_t *)effp->priv; dft_filter_t * f = p->base.filter_ptr; if (!f->num_taps) { double Fn = effp->in_signal.rate * .5; double * h[2]; int i, n, post_peak, longer; if (p->Fc0 >= Fn || p->Fc1 >= Fn) { lsx_fail("filter frequency must be less than sample-rate / 2"); return SOX_EOF; } h[0] = lpf(Fn, p->Fc0, p->tbw0, &p->num_taps[0], p->att, &p->beta,p->round); h[1] = lpf(Fn, p->Fc1, p->tbw1, &p->num_taps[1], p->att, &p->beta,p->round); if (h[0]) invert(h[0], p->num_taps[0]); longer = p->num_taps[1] > p->num_taps[0]; n = p->num_taps[longer]; if (h[0] && h[1]) { for (i = 0; i < p->num_taps[!longer]; ++i) h[longer][i + (n - p->num_taps[!longer])/2] += h[!longer][i]; if (p->Fc0 < p->Fc1) invert(h[longer], n); free(h[!longer]); } if (p->phase != 50) lsx_fir_to_phase(&h[longer], &n, &post_peak, p->phase); else post_peak = n >> 1; if (effp->global_info->plot != sox_plot_off) { char title[100]; sprintf(title, "SoX effect: sinc filter freq=%g-%g", p->Fc0, p->Fc1? p->Fc1 : Fn); lsx_plot_fir(h[longer], n, effp->in_signal.rate, effp->global_info->plot, title, -p->beta * 10 - 25, 5.); return SOX_EOF; } lsx_set_dft_filter(f, h[longer], n, post_peak); }
static void init_dft_filter(rate_shared_t * p, unsigned which, int num_taps, sox_sample_t const h[], double Fp, double Fc, double Fn, double att, int multiplier, double phase, sox_bool allow_aliasing) { dft_filter_t * f = &p->half_band[which]; int dft_length, i; if (f->num_taps) return; if (h) { // for half_fir_coefs_low dft_length = lsx_set_dft_length(num_taps); f->coefs = lsx_aligned_calloc(dft_length, sizeof(*f->coefs)); for (i = 0; i < num_taps; ++i) f->coefs[(i + dft_length - num_taps + 1) & (dft_length - 1)] = h[abs(num_taps / 2 - i)] / dft_length * 2 * multiplier; f->post_peak = num_taps / 2; } else { double * h2 = lsx_design_lpf(Fp, Fc, Fn, allow_aliasing, att, &num_taps, 0, -1.); if (phase != 50) lsx_fir_to_phase(&h2, &num_taps, &f->post_peak, phase); else f->post_peak = num_taps / 2; dft_length = lsx_set_dft_length(num_taps); f->coefs = lsx_aligned_calloc(dft_length, sizeof(*f->coefs)); for (i = 0; i < num_taps; ++i) f->coefs[(i + dft_length - num_taps + 1) & (dft_length - 1)] = h2[i] / dft_length * 2 * multiplier; lsx_free(h2); } assert(num_taps & 1); f->num_taps = num_taps; f->dft_length = dft_length; f->tmp_buf = lsx_aligned_malloc(dft_length*sizeof(FFTComplex)/2); ff_rdft_x(dft_length, 1, f->coefs, f->tmp_buf); }