static int resampler_basic_direct_single()

in subprojects/speex/resample.c [331:384]


static int resampler_basic_direct_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len)
{
   const int N = st->filt_len;
   int out_sample = 0;
   int last_sample = st->last_sample[channel_index];
   spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
   const spx_word16_t *sinc_table = st->sinc_table;
   const int out_stride = st->out_stride;
   const int int_advance = st->int_advance;
   const int frac_advance = st->frac_advance;
   const spx_uint32_t den_rate = st->den_rate;
   spx_word32_t sum;

   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
   {
      const spx_word16_t *sinct = & sinc_table[samp_frac_num*N];
      const spx_word16_t *iptr = & in[last_sample];

#ifndef OVERRIDE_INNER_PRODUCT_SINGLE
      int j;
      sum = 0;
      for(j=0;j<N;j++) sum += MULT16_16(sinct[j], iptr[j]);

/*    This code is slower on most DSPs which have only 2 accumulators.
      Plus this this forces truncation to 32 bits and you lose the HW guard bits.
      I think we can trust the compiler and let it vectorize and/or unroll itself.
      spx_word32_t accum[4] = {0,0,0,0};
      for(j=0;j<N;j+=4) {
        accum[0] += MULT16_16(sinct[j], iptr[j]);
        accum[1] += MULT16_16(sinct[j+1], iptr[j+1]);
        accum[2] += MULT16_16(sinct[j+2], iptr[j+2]);
        accum[3] += MULT16_16(sinct[j+3], iptr[j+3]);
      }
      sum = accum[0] + accum[1] + accum[2] + accum[3];
*/
      sum = SATURATE32PSHR(sum, 15, 32767);
#else
      sum = inner_product_single(sinct, iptr, N);
#endif

      out[out_stride * out_sample++] = sum;
      last_sample += int_advance;
      samp_frac_num += frac_advance;
      if (samp_frac_num >= den_rate)
      {
         samp_frac_num -= den_rate;
         last_sample++;
      }
   }

   st->last_sample[channel_index] = last_sample;
   st->samp_frac_num[channel_index] = samp_frac_num;
   return out_sample;
}