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

📄 resample.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 3 页
字号:
static int resampler_basic_direct_double(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;   double sum;   int j;   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))   {      const spx_word16_t *sinc = & sinc_table[samp_frac_num*N];      const spx_word16_t *iptr = & in[last_sample];#ifndef OVERRIDE_INNER_PRODUCT_DOUBLE      double accum[4] = {0,0,0,0};      for(j=0;j<N;j+=4) {        accum[0] += sinc[j]*iptr[j];        accum[1] += sinc[j+1]*iptr[j+1];        accum[2] += sinc[j+2]*iptr[j+2];        accum[3] += sinc[j+3]*iptr[j+3];      }      sum = accum[0] + accum[1] + accum[2] + accum[3];#else      sum = inner_product_double(sinc, iptr, N);#endif      out[out_stride * out_sample++] = PSHR32(sum, 15);      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;}#endifstatic int resampler_basic_interpolate_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 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;   int j;   spx_word32_t sum;   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))   {      const spx_word16_t *iptr = & in[last_sample];      const int offset = samp_frac_num*st->oversample/st->den_rate;#ifdef FIXED_POINT      const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);#else      const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;#endif      spx_word16_t interp[4];#ifndef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE      spx_word32_t accum[4] = {0,0,0,0};      for(j=0;j<N;j++) {        const spx_word16_t curr_in=iptr[j];        accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);        accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);        accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);        accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);      }      cubic_coef(frac, interp);      sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]);#else      cubic_coef(frac, interp);      sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);#endif            out[out_stride * out_sample++] = PSHR32(sum,15);      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;}#ifdef FIXED_POINT#else/* This is the same as the previous function, except with a double-precision accumulator */static int resampler_basic_interpolate_double(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 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;   int j;   spx_word32_t sum;   while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))   {      const spx_word16_t *iptr = & in[last_sample];      const int offset = samp_frac_num*st->oversample/st->den_rate;#ifdef FIXED_POINT      const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate);#else      const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate;#endif      spx_word16_t interp[4];#ifndef OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE      double accum[4] = {0,0,0,0};      for(j=0;j<N;j++) {        const double curr_in=iptr[j];        accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]);        accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]);        accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]);        accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]);      }      cubic_coef(frac, interp);      sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]);#else      cubic_coef(frac, interp);      sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);#endif            out[out_stride * out_sample++] = PSHR32(sum,15);      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;}#endifstatic void update_filter(SpeexResamplerState *st){   spx_uint32_t old_length;      old_length = st->filt_len;   st->oversample = quality_map[st->quality].oversample;   st->filt_len = quality_map[st->quality].base_length;      if (st->num_rate > st->den_rate)   {      /* down-sampling */      st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate;      /* FIXME: divide the numerator and denominator by a certain amount if they're too large */      st->filt_len = st->filt_len*st->num_rate / st->den_rate;      /* Round down to make sure we have a multiple of 4 */      st->filt_len &= (~0x3);      if (2*st->den_rate < st->num_rate)         st->oversample >>= 1;      if (4*st->den_rate < st->num_rate)         st->oversample >>= 1;      if (8*st->den_rate < st->num_rate)         st->oversample >>= 1;      if (16*st->den_rate < st->num_rate)         st->oversample >>= 1;      if (st->oversample < 1)         st->oversample = 1;   } else {      /* up-sampling */      st->cutoff = quality_map[st->quality].upsample_bandwidth;   }      /* Choose the resampling type that requires the least amount of memory */   if (st->den_rate <= st->oversample)   {      spx_uint32_t i;      if (!st->sinc_table)         st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t));      else if (st->sinc_table_length < st->filt_len*st->den_rate)      {         st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t));         st->sinc_table_length = st->filt_len*st->den_rate;      }      for (i=0;i<st->den_rate;i++)      {         spx_int32_t j;         for (j=0;j<st->filt_len;j++)         {            st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func);         }      }#ifdef FIXED_POINT      st->resampler_ptr = resampler_basic_direct_single;#else      if (st->quality>8)         st->resampler_ptr = resampler_basic_direct_double;      else         st->resampler_ptr = resampler_basic_direct_single;#endif      /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/   } else {      spx_int32_t i;      if (!st->sinc_table)         st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t));      else if (st->sinc_table_length < st->filt_len*st->oversample+8)      {         st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t));         st->sinc_table_length = st->filt_len*st->oversample+8;      }      for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++)         st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len, quality_map[st->quality].window_func);#ifdef FIXED_POINT      st->resampler_ptr = resampler_basic_interpolate_single;#else      if (st->quality>8)         st->resampler_ptr = resampler_basic_interpolate_double;      else         st->resampler_ptr = resampler_basic_interpolate_single;#endif      /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/   }   st->int_advance = st->num_rate/st->den_rate;   st->frac_advance = st->num_rate%st->den_rate;      /* Here's the place where we update the filter memory to take into account      the change in filter length. It's probably the messiest part of the code      due to handling of lots of corner cases. */   if (!st->mem)   {      spx_uint32_t i;      st->mem_alloc_size = st->filt_len-1 + st->buffer_size;      st->mem = (spx_word16_t*)speex_alloc(st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t));      for (i=0;i<st->nb_channels*st->mem_alloc_size;i++)         st->mem[i] = 0;      /*speex_warning("init filter");*/   } else if (!st->started)   {      spx_uint32_t i;      st->mem_alloc_size = st->filt_len-1 + st->buffer_size;      st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t));      for (i=0;i<st->nb_channels*st->mem_alloc_size;i++)         st->mem[i] = 0;      /*speex_warning("reinit filter");*/   } else if (st->filt_len > old_length)   {      spx_int32_t i;      /* Increase the filter length */      /*speex_warning("increase filter size");*/      int old_alloc_size = st->mem_alloc_size;      if ((st->filt_len-1 + st->buffer_size) > st->mem_alloc_size)      {         st->mem_alloc_size = st->filt_len-1 + st->buffer_size;         st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*st->mem_alloc_size * sizeof(spx_word16_t));      }      for (i=st->nb_channels-1;i>=0;i--)      {         spx_int32_t j;         spx_uint32_t olen = old_length;         /*if (st->magic_samples[i])*/         {            /* Try and remove the magic samples as if nothing had happened */                        /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */            olen = old_length + 2*st->magic_samples[i];            for (j=old_length-2+st->magic_samples[i];j>=0;j--)               st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j];            for (j=0;j<st->magic_samples[i];j++)               st->mem[i*st->mem_alloc_size+j] = 0;            st->magic_samples[i] = 0;         }         if (st->filt_len > olen)         {            /* If the new filter length is still bigger than the "augmented" length */            /* Copy data going backward */            for (j=0;j<olen-1;j++)               st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)];            /* Then put zeros for lack of anything better */            for (;j<st->filt_len-1;j++)               st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0;            /* Adjust last_sample */            st->last_sample[i] += (st->filt_len - olen)/2;         } else {            /* Put back some of the magic! */            st->magic_samples[i] = (olen - st->filt_len)/2;            for (j=0;j<st->filt_len-1+st->magic_samples[i];j++)               st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];         }      }   } else if (st->filt_len < old_length)   {      spx_uint32_t i;      /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic"         samples so they can be used directly as input the next time(s) */      for (i=0;i<st->nb_channels;i++)      {         spx_uint32_t j;         spx_uint32_t old_magic = st->magic_samples[i];         st->magic_samples[i] = (old_length - st->filt_len)/2;         /* We must copy some of the memory that's no longer used */         /* Copy data going backward */         for (j=0;j<st->filt_len-1+st->magic_samples[i]+old_magic;j++)            st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];         st->magic_samples[i] += old_magic;      }   }}EXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err){   return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err);}EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err){   spx_uint32_t i;   SpeexResamplerState *st;   if (quality > 10 || quality < 0)   {      if (err)         *err = RESAMPLER_ERR_INVALID_ARG;      return NULL;   }   st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState));   st->initialised = 0;   st->started = 0;   st->in_rate = 0;   st->out_rate = 0;   st->num_rate = 0;   st->den_rate = 0;   st->quality = -1;   st->sinc_table_length = 0;   st->mem_alloc_size = 0;   st->filt_len = 0;   st->mem = 0;   st->resampler_ptr = 0;            st->cutoff = 1.f;   st->nb_channels = nb_channels;   st->in_stride = 1;   st->out_stride = 1;   #ifdef FIXED_POINT   st->buffer_size = 160;#else   st->buffer_size = 160;#endif

⌨️ 快捷键说明

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