コード例 #1
0
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_rdft(f->dft_length, 1, output, lsx_fft_br, lsx_fft_sc);
    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_rdft(f->dft_length, -1, output, lsx_fft_br, lsx_fft_sc);
  }
}
コード例 #2
0
static void double_sample(stage_t * p, fifo_t * output_fifo)
{
  sox_sample_t * output;
  int i, j, num_in = max(0, fifo_occupancy(&p->fifo));
  rate_shared_t const * s = p->shared;
  dft_filter_t const * f = &s->half_band[p->which];
  int const overlap = f->num_taps - 1;
#ifdef SSE_
  const float * const coeff = f->coefs;
  sox_sample_t tmp;
  __m128 coef, outp, sign;
  sign = SIGN;
#endif

  while (p->rem + p->tuple * num_in >= f->dft_length) {
    div_t divd = div(f->dft_length - overlap - p->rem + p->tuple - 1, p->tuple);
    sox_sample_t const * input = fifo_read_ptr(&p->fifo);
    fifo_read(&p->fifo, divd.quot, NULL);
    num_in -= divd.quot;

    output = fifo_reserve_aligned(output_fifo, f->dft_length);
    fifo_trim_by(output_fifo, overlap);
    memset(output, 0, f->dft_length * sizeof(*output));
    for (j = 0, i = p->rem; i < f->dft_length; ++j, i += p->tuple)
      output[i] = input[j];
    p->rem = p->tuple - 1 - divd.rem;

    ff_rdft_x(f->dft_length, 1, output, f->tmp_buf);
#ifdef SSE_
    output[0] *= coeff[0];
    output[1] *= coeff[1];
    tmp = output[2];
    output[2] = coeff[2] * tmp - coeff[3] * output[3];
    output[3] = coeff[3] * tmp + coeff[2] * output[3];

    for (i = 4; i < f->dft_length; i += 4)
    {
      outp = _mm_load_ps(output+i);
      coef = _mm_load_ps(coeff+i);
      _mm_store_ps(output+i, ZMUL2(outp, coef, sign));
    }
#else
    output[0] *= f->coefs[0];
    output[1] *= f->coefs[1];
    for (i = 2; i < f->dft_length; i += 2) {
      sox_sample_t 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];
    }
#endif
    ff_rdft_x(f->dft_length, -1, output, f->tmp_buf);
  }
}
コード例 #3
0
static int drain(sox_effect_t * effp, sox_sample_t * obuf, size_t * osamp)
{
  priv_t * p = (priv_t *)effp->priv;
  static size_t isamp = 0;
  size_t samples_out = p->samples_in;
  size_t remaining = samples_out - p->samples_out;
  double * buff = lsx_calloc(1024, sizeof(*buff));

  if ((int)remaining > 0) {
    while ((size_t)fifo_occupancy(&p->output_fifo) < remaining) {
      fifo_write(&p->input_fifo, 1024, buff);
      p->samples_in += 1024;
      filter(p);
    }
    fifo_trim_to(&p->output_fifo, (int)remaining);
    p->samples_in = 0;
  }
  free(buff);
  return flow(effp, 0, obuf, &isamp, osamp);
}
コード例 #4
0
static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
                sox_sample_t * obuf, size_t * isamp, size_t * osamp)
{
  priv_t * p = (priv_t *)effp->priv;
  size_t i, odone = min(*osamp, (size_t)fifo_occupancy(&p->output_fifo));
  double const * s = fifo_read(&p->output_fifo, (int)odone, NULL);
  SOX_SAMPLE_LOCALS;

  for (i = 0; i < odone; ++i)
    *obuf++ = SOX_FLOAT_64BIT_TO_SAMPLE(*s++, effp->clips);
  p->samples_out += odone;

  if (*isamp && odone < *osamp) {
    double * t = fifo_write(&p->input_fifo, (int)*isamp, NULL);
    p->samples_in += (int)*isamp;

    for (i = *isamp; i; --i)
      *t++ = SOX_SAMPLE_TO_FLOAT_64BIT(*ibuf++, effp->clips);
    filter(p);
  }
  else *isamp = 0;
  *osamp = odone;
  return SOX_SUCCESS;
}