diff --git a/linphone/mediastreamer2/src/msresample.c b/linphone/mediastreamer2/src/msresample.c index 4fb710083..7bff53cb1 100644 --- a/linphone/mediastreamer2/src/msresample.c +++ b/linphone/mediastreamer2/src/msresample.c @@ -1,7 +1,8 @@ #include "mediastreamer2/msfilter.h" -#include +#include +#include typedef struct _ResampleData{ MSBufferizer *bz; @@ -9,8 +10,7 @@ typedef struct _ResampleData{ uint32_t input_rate; uint32_t output_rate; - void *handle; - float factor; + SpeexResamplerState *handle; int nb_unprocessed; } ResampleData; @@ -20,9 +20,9 @@ static ResampleData * resample_data_new(){ obj->ts=0; obj->input_rate=8000; obj->output_rate=16000; + obj->handle=NULL; obj->nb_unprocessed=0; - obj->factor=obj->output_rate/obj->input_rate; return obj; } @@ -37,17 +37,21 @@ static void resample_init(MSFilter *obj){ static void resample_uninit(MSFilter *obj){ resample_data_destroy((ResampleData*)obj->data); + } static void resample_preprocess(MSFilter *obj){ ResampleData *dt=(ResampleData*)obj->data; + int err=0; - dt->handle = resample_open(1, dt->factor, dt->factor); + dt->handle = speex_resampler_init(1, dt->input_rate, dt->output_rate, SPEEX_RESAMPLER_QUALITY_VOIP, &err); } static void resample_postprocess(MSFilter *obj){ ResampleData *dt=(ResampleData*)obj->data; - resample_close(dt->handle); + if (dt->handle!=NULL) + speex_resampler_destroy((SpeexResamplerState*)dt->handle); + dt->handle=NULL; } static void resample_process_ms2(MSFilter *obj){ @@ -77,125 +81,51 @@ static void resample_process_ms2(MSFilter *obj){ ms_bufferizer_put(bz,m); } while (ms_bufferizer_read(bz,buffer,size_of_input)==size_of_input){ -#if 0 mblk_t *obl=allocb(size_of_output,0); - int outpos, o, srcused; - int srcpos; - int fwidth; - - int expectedlen = (int)(size_of_input * dt->factor); - int dstlen = expectedlen + 1000; - float in[1280]; - float out[2560]; + float *in; + float *out; + spx_uint32_t in_len; + spx_uint32_t out_len; + int err; short *data = (short*)buffer; + short *data_out = (short*)obl->b_wptr; + int i; - /* Convert the samples to floats */ - for (i = dt->nb_unprocessed; i < size_of_input; i++) - in[i] = (float) data[i-dt->nb_unprocessed]; - dt->nb_unprocessed=0; + + in = (float*) alloca((size_of_input/2)*sizeof(float)); + out = (float*) alloca((size_of_output/2)*sizeof(float)); - outpos = 0; - srcpos = 0; - for(;;) { - int srcBlock = MIN(size_of_input-srcpos, size_of_input); - int lastFlag = (srcBlock == size_of_input-srcpos); - - o = resample_process(dt->handle, dt->factor, - &in[srcpos], srcBlock, - lastFlag, &srcused, - &out[outpos], MIN(dstlen-outpos, size_of_input * dt->factor + 10)); - srcpos += srcused; - if (o >= 0) - outpos += o; - if (o < 0 || (o == 0 && srcpos == size_of_input)) - break; - } - - if (outpos>0 && outpos<=size_of_output) - { - //resample - data = (short*)obl->b_wptr; - for (i = 0; i < outpos/2; i++) - { - /* bound checks! */ - int bc=(short) out[i]; - if (bc < -32768) - bc = -32768; - else if (bc > 32767) - bc = 32767; - *data = bc; - data++; - } - - obl->b_wptr=obl->b_wptr+outpos; - dt->ts+=160; - ms_queue_put(obj->outputs[0],obl); - } - else - { - ms_warning("resample failed!"); - freeb(obl); - } -#else - mblk_t *obl=allocb(size_of_output,0); - - int srcused; - int o; - - float in[1280]; - float out[2560]; - - short *data = (short*)buffer; - int i; /* Convert the samples to floats */ for (i = 0; i < size_of_input/2; i++) - in[i] = (float) data[i-dt->nb_unprocessed]; + in[i] = (float) data[i]; - o = resample_process(dt->handle, dt->factor, - &in[0], size_of_input/2, - 0, &srcused, - &out[0], size_of_output/2); + in_len = size_of_input/2; + out_len = size_of_output/2; + err = speex_resampler_process_float(dt->handle, 0, in, &in_len, out, &out_len); - if (o>0 && o<=size_of_output/2) - { - data = (short*)obl->b_wptr; - for (i = 0; i < o; i++) - { - /* bound checks! */ - int bc=(short) out[i]; - if (bc < -32768) - bc = -32768; - else if (bc > 32767) - bc = 32767; - data[i] = bc; - } - obl->b_wptr=obl->b_wptr+(o*2); /* size_of_output; */ - mblk_set_timestamp_info(obl,dt->ts); - dt->ts+=160; - ms_queue_put(obj->outputs[0],obl); - } - else - { - ms_warning("resample failed!"); - freeb(obl); - } -#endif + /* ms_message("resampling info: err=%i in_len=%i, out_len=%i", err, in_len, out_len); */ + + for (i=0;ib_wptr=obl->b_wptr+(out_len*2); /* size_of_output; */ + + mblk_set_timestamp_info(obl,dt->ts); + dt->ts+=160; + ms_queue_put(obj->outputs[0],obl); } } int ms_resample_set_sr(MSFilter *obj, void *arg){ ResampleData *dt=(ResampleData*)obj->data; dt->input_rate=((int*)arg)[0]; - dt->factor=((float)dt->output_rate/(float)dt->input_rate); return 0; } int ms_resample_set_output_sr(MSFilter *obj, void *arg){ ResampleData *dt=(ResampleData*)obj->data; dt->output_rate=((int*)arg)[0]; - dt->factor=((float)dt->output_rate/(float)dt->input_rate); return 0; }