Skip to content
Snippets Groups Projects
resample.c 42.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • #ifdef FIXED_POINT
            out[j*ostride_save] = ystack[j];
    #else
            out[j*ostride_save] = WORD2INT(ystack[j]);
    #endif
    
         ilen -= ichunk;
         olen -= ochunk;
         out += (ochunk+omagic) * ostride_save;
         if (in)
           in += ichunk * istride_save;
       }
       st->out_stride = ostride_save;
       *in_len -= ilen;
       *out_len -= olen;
    
    
       return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
    
    EXPORT int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
    
    {
       spx_uint32_t i;
       int istride_save, ostride_save;
    
       spx_uint32_t bak_out_len = *out_len;
       spx_uint32_t bak_in_len = *in_len;
    
       istride_save = st->in_stride;
       ostride_save = st->out_stride;
       st->in_stride = st->out_stride = st->nb_channels;
       for (i=0;i<st->nb_channels;i++)
       {
    
          *out_len = bak_out_len;
          *in_len = bak_in_len;
    
          if (in != NULL)
             speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len);
          else
             speex_resampler_process_float(st, i, NULL, in_len, out+i, out_len);
       }
       st->in_stride = istride_save;
       st->out_stride = ostride_save;
    
       return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
    
    EXPORT int speex_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
    
    {
       spx_uint32_t i;
       int istride_save, ostride_save;
    
       spx_uint32_t bak_out_len = *out_len;
       spx_uint32_t bak_in_len = *in_len;
    
       istride_save = st->in_stride;
       ostride_save = st->out_stride;
       st->in_stride = st->out_stride = st->nb_channels;
       for (i=0;i<st->nb_channels;i++)
       {
    
          *out_len = bak_out_len;
          *in_len = bak_in_len;
    
          if (in != NULL)
             speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len);
          else
             speex_resampler_process_int(st, i, NULL, in_len, out+i, out_len);
       }
       st->in_stride = istride_save;
       st->out_stride = ostride_save;
    
       return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS;
    
    EXPORT int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate)
    
    {
       return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);
    }
    
    
    EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate)
    
    EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate)
    
    {
       spx_uint32_t fact;
       spx_uint32_t old_den;
       spx_uint32_t i;
       if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)
          return RESAMPLER_ERR_SUCCESS;
    
       old_den = st->den_rate;
       st->in_rate = in_rate;
       st->out_rate = out_rate;
       st->num_rate = ratio_num;
       st->den_rate = ratio_den;
       /* FIXME: This is terribly inefficient, but who cares (at least for now)? */
       for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++)
       {
          while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))
          {
             st->num_rate /= fact;
             st->den_rate /= fact;
          }
       }
    
       if (old_den > 0)
       {
          for (i=0;i<st->nb_channels;i++)
          {
             st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den;
             /* Safety net */
             if (st->samp_frac_num[i] >= st->den_rate)
                st->samp_frac_num[i] = st->den_rate-1;
          }
       }
    
    EXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den)
    
    EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality)
    
    {
       if (quality > 10 || quality < 0)
          return RESAMPLER_ERR_INVALID_ARG;
       if (st->quality == quality)
          return RESAMPLER_ERR_SUCCESS;
       st->quality = quality;
       if (st->initialised)
    
    EXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality)
    
    EXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride)
    
    EXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride)
    
    EXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride)
    
    EXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride)
    
    EXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st)
    
    EXPORT int speex_resampler_get_output_latency(SpeexResamplerState *st)
    
    {
      return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate;
    }
    
    
    EXPORT int speex_resampler_skip_zeros(SpeexResamplerState *st)
    
    {
       spx_uint32_t i;
       for (i=0;i<st->nb_channels;i++)
          st->last_sample[i] = st->filt_len/2;
       return RESAMPLER_ERR_SUCCESS;
    }
    
    
    EXPORT int speex_resampler_reset_mem(SpeexResamplerState *st)
    
       for (i=0;i<st->nb_channels;i++)
       {
          st->last_sample[i] = 0;
          st->magic_samples[i] = 0;
          st->samp_frac_num[i] = 0;
       }
    
       for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
          st->mem[i] = 0;
       return RESAMPLER_ERR_SUCCESS;
    }
    
    
    EXPORT const char *speex_resampler_strerror(int err)
    
    {
       switch (err)
       {
          case RESAMPLER_ERR_SUCCESS:
             return "Success.";
          case RESAMPLER_ERR_ALLOC_FAILED:
             return "Memory allocation failed.";
          case RESAMPLER_ERR_BAD_STATE:
             return "Bad resampler state.";
          case RESAMPLER_ERR_INVALID_ARG:
             return "Invalid argument.";
          case RESAMPLER_ERR_PTR_OVERLAP:
             return "Input and output buffers overlap.";
          default:
             return "Unknown error. Bad error code or strange version mismatch.";
       }
    }