mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-21 21:28:08 +00:00
rewrite resampler using speexdsp
git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@131 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
This commit is contained in:
parent
386cdbba9c
commit
b62c939a3e
1 changed files with 33 additions and 103 deletions
|
|
@ -1,7 +1,8 @@
|
|||
|
||||
#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;
|
||||
/* 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;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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue