Пример #1
0
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);
}