Commit b62c939a authored by aymeric's avatar aymeric

rewrite resampler using speexdsp

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@131 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
parent 386cdbba
#include "mediastreamer2/msfilter.h"
#include <libresample.h>
#include <speex/speex_resampler.h>
#include <math.h>
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;
in = (float*) alloca((size_of_input/2)*sizeof(float));
out = (float*) alloca((size_of_output/2)*sizeof(float));
/* 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;
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);
for (i = 0; i < size_of_input/2; i++)
in[i] = (float) data[i];
int srcused;
int o;
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);
float in[1280];
float out[2560];
/* ms_message("resampling info: err=%i in_len=%i, out_len=%i", err, in_len, out_len); */
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];
o = resample_process(dt->handle, dt->factor,
&in[0], size_of_input/2,
0, &srcused,
&out[0], size_of_output/2);
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
for (i=0;i<out_len;i++)
data_out[i]=floor(.5+out[i]);
obl->b_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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment