2

I'm trying to re-sample captured 2channel/48khz/32bit audio to 1channel/8khz/32bit using libsamplerate in a windows phone project using WASAPI.

I need to get 160 frames from 960 original frames by re-sampling.After capturing audio using GetBuffer method I send the captured BYTE array of 7680 byte to the below method:

void BackEndAudio::ChangeSampleRate(BYTE* buf)
{

int er2;
st=src_new(2,1,&er2);
//SRC_DATA sd defined before
sd=new SRC_DATA;


BYTE *onechbuf = new BYTE[3840];
int outputIndex = 0;

//convert Stereo to Mono
for (int n = 0; n < 7680; n+=8)
{
    onechbuf[outputIndex++] = buf[n];
    onechbuf[outputIndex++] = buf[n+1];
    onechbuf[outputIndex++] = buf[n+2];
    onechbuf[outputIndex++] = buf[n+3];
}

float *res1=new float[960];
res1=(float *)onechbuf;

float *res2=new float[160];

//change samplerate
sd->data_in=res1;
sd->data_out=res2;
sd->input_frames=960;
sd->output_frames=160;
sd->src_ratio=(double)1/6;
sd->end_of_input=1;
int er=src_process(st,sd);

transportController->WriteAudio((BYTE *)res2,640);

delete[] onechbuf;
src_delete(st);
delete sd;

}

src_process method returns no error and sd->input_frames_used set to 960 and sd->output_frames_gen set to 159 but the rendering output is only noise. I use the code in a real-time VoIP app. What could be the source of problem ?

harsini
  • 326
  • 2
  • 14
  • 1
    Did you convert from integer to float samples first? Meaning, does `buf` contain integer samples, or float samples? – Nikos C. Jan 11 '14 at 14:40
  • 1
    You have a memory leak here: `float *res1=new float[960];` because you reassign to `res1` immediately after, loosing the only pointer to the allocated memory. –  Jan 11 '14 at 14:51
  • @Nabla Thanks for your hint.I'm not well at c++.But I don't think it is the main issue. – harsini Jan 11 '14 at 15:38
  • 1
    @harsini No it is not, thats why I posted it as comment, but you will run into trouble sooner or later when your program takes all your systems memory. –  Jan 11 '14 at 15:50
  • How dd u generate bsamplerate dll ? cn we get the winmd file directly ? – Null Pointer Oct 12 '15 at 06:09
  • It's for almost 2 years ago and I don't remember how I generate that.:-/ – harsini Oct 12 '15 at 09:24
  • Thank you :) . Finally I managed to add the lib in to my project. And it generate 160 frames. But the rendering output is only noise :( . I am doing exactly what you posted in the answer . Any suggestions ? – Null Pointer Oct 14 '15 at 05:50
  • Are you sure that your captured buf is not silent?I mean your capturing works fine? – harsini Oct 14 '15 at 13:47
  • finally found the issue. I was providing 16 bit input data. but libsamplerate is expecting 32 bit data. Thanks – Null Pointer Nov 09 '15 at 11:26

1 Answers1

1

I found the problem.I shouldn't make a new SRC_STATE object and delete it in each call of my function by calling st=src_new(2,1,&er2); and src_delete(st);but call them once is enough for the whole audio re-sampling.Also there is no need to using pointer for the SRC_DATA . I modified my code as below and it works fine now.

void BackEndAudio::ChangeSampleRate(BYTE* buf)
{
BYTE *onechbuf = new BYTE[3840];
int outputIndex = 0;

//convert Stereo to Mono
for (int n = 0; n < 7680; n+=8)
{
    onechbuf[outputIndex++] = buf[n];
    onechbuf[outputIndex++] = buf[n+1];
    onechbuf[outputIndex++] = buf[n+2];
    onechbuf[outputIndex++] = buf[n+3];
}

float *out=new float[160];

//change samplerate
sd.data_in=(float *)onechbuf;
sd.data_out=out;
sd.input_frames=960;
sd.output_frames=160;
sd.src_ratio=(double)1/6;
sd.end_of_input=0;
int er=src_process(st,&sd);
}
harsini
  • 326
  • 2
  • 14