⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resample.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 3 页
字号:
      /* Per channel data */   st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(int));   st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int));   st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int));   for (i=0;i<nb_channels;i++)   {      st->last_sample[i] = 0;      st->magic_samples[i] = 0;      st->samp_frac_num[i] = 0;   }   speex_resampler_set_quality(st, quality);   speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate);      update_filter(st);      st->initialised = 1;   if (err)      *err = RESAMPLER_ERR_SUCCESS;   return st;}EXPORT void speex_resampler_destroy(SpeexResamplerState *st){   speex_free(st->mem);   speex_free(st->sinc_table);   speex_free(st->last_sample);   speex_free(st->magic_samples);   speex_free(st->samp_frac_num);   speex_free(st);}static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len){   int j=0;   const int N = st->filt_len;   int out_sample = 0;   spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;   spx_uint32_t ilen;      st->started = 1;      /* Call the right resampler through the function ptr */   out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len);      if (st->last_sample[channel_index] < (spx_int32_t)*in_len)      *in_len = st->last_sample[channel_index];   *out_len = out_sample;   st->last_sample[channel_index] -= *in_len;      ilen = *in_len;   for(j=0;j<N-1;++j)     mem[j] = mem[j+ilen];   return RESAMPLER_ERR_SUCCESS;}static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_index, spx_word16_t **out, spx_uint32_t out_len) {   spx_uint32_t tmp_in_len = st->magic_samples[channel_index];   spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;   const int N = st->filt_len;      speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len);   st->magic_samples[channel_index] -= tmp_in_len;      /* If we couldn't process all "magic" input samples, save the rest for next time */   if (st->magic_samples[channel_index])   {      spx_uint32_t i;      for (i=0;i<st->magic_samples[channel_index];i++)         mem[N-1+i]=mem[N-1+i+tmp_in_len];   }   *out += out_len*st->out_stride;   return out_len;}#ifdef FIXED_POINTEXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)#elseEXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)#endif{   int j;   spx_uint32_t ilen = *in_len;   spx_uint32_t olen = *out_len;   spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;   const int filt_offs = st->filt_len - 1;   const spx_uint32_t xlen = st->mem_alloc_size - filt_offs;   const int istride = st->in_stride;   if (st->magic_samples[channel_index])       olen -= speex_resampler_magic(st, channel_index, &out, olen);   if (! st->magic_samples[channel_index]) {      while (ilen && olen) {        spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;        spx_uint32_t ochunk = olen;         if (in) {           for(j=0;j<ichunk;++j)              x[j+filt_offs]=in[j*istride];        } else {          for(j=0;j<ichunk;++j)            x[j+filt_offs]=0;        }        speex_resampler_process_native(st, channel_index, &ichunk, out, &ochunk);        ilen -= ichunk;        olen -= ochunk;        out += ochunk * st->out_stride;        if (in)           in += ichunk * istride;      }   }   *in_len -= ilen;   *out_len -= olen;   return RESAMPLER_ERR_SUCCESS;}#ifdef FIXED_POINTEXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)#elseEXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)#endif{   int j;   const int istride_save = st->in_stride;   const int ostride_save = st->out_stride;   spx_uint32_t ilen = *in_len;   spx_uint32_t olen = *out_len;   spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;   const spx_uint32_t xlen = st->mem_alloc_size - (st->filt_len - 1);#ifdef VAR_ARRAYS   const unsigned int ylen = (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC;   VARDECL(spx_word16_t *ystack);   ALLOC(ystack, ylen, spx_word16_t);#else   const unsigned int ylen = FIXED_STACK_ALLOC;   spx_word16_t ystack[FIXED_STACK_ALLOC];#endif   st->out_stride = 1;      while (ilen && olen) {     spx_word16_t *y = ystack;     spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;     spx_uint32_t ochunk = (olen > ylen) ? ylen : olen;     spx_uint32_t omagic = 0;     if (st->magic_samples[channel_index]) {       omagic = speex_resampler_magic(st, channel_index, &y, ochunk);       ochunk -= omagic;       olen -= omagic;     }     if (! st->magic_samples[channel_index]) {       if (in) {         for(j=0;j<ichunk;++j)#ifdef FIXED_POINT           x[j+st->filt_len-1]=WORD2INT(in[j*istride_save]);#else           x[j+st->filt_len-1]=in[j*istride_save];#endif       } else {         for(j=0;j<ichunk;++j)           x[j+st->filt_len-1]=0;       }       speex_resampler_process_native(st, channel_index, &ichunk, y, &ochunk);     } else {       ichunk = 0;       ochunk = 0;     }     for (j=0;j<ochunk+omagic;++j)#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 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_len = *out_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_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 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_len = *out_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_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 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){   *in_rate = st->in_rate;   *out_rate = st->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;      }   }      if (st->initialised)      update_filter(st);   return RESAMPLER_ERR_SUCCESS;}EXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den){   *ratio_num = st->num_rate;   *ratio_den = st->den_rate;}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)      update_filter(st);   return RESAMPLER_ERR_SUCCESS;}EXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality){   *quality = st->quality;}EXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride){   st->in_stride = stride;}EXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride){   *stride = st->in_stride;}EXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride){   st->out_stride = stride;}EXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride){   *stride = st->out_stride;}EXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st){  return st->filt_len / 2;}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){   spx_uint32_t i;   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.";   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -