forked from Mirrors/freeswitch
184 lines
4.4 KiB
C
184 lines
4.4 KiB
C
|
/**********************************************************************
|
||
|
|
||
|
compareresample.c
|
||
|
|
||
|
Real-time library interface by Dominic Mazzoni
|
||
|
|
||
|
Based on resample-1.7:
|
||
|
http://www-ccrma.stanford.edu/~jos/resample/
|
||
|
|
||
|
License: LGPL - see the file LICENSE.txt for more information
|
||
|
|
||
|
**********************************************************************/
|
||
|
|
||
|
#include "../include/libresample.h"
|
||
|
|
||
|
#include <samplerate.h>
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <math.h>
|
||
|
|
||
|
#include <sys/time.h>
|
||
|
|
||
|
#define MIN(A, B) (A) < (B)? (A) : (B)
|
||
|
|
||
|
void dostat(char *name, float *d1, float *d2, int len)
|
||
|
{
|
||
|
int i;
|
||
|
double sum, sumsq, err, rmserr;
|
||
|
|
||
|
sum = 0.0;
|
||
|
sumsq = 0.0;
|
||
|
for(i=0; i<len; i++) {
|
||
|
double diff = d1[i] - d2[i];
|
||
|
sum += fabs(diff);
|
||
|
sumsq += diff * diff;
|
||
|
}
|
||
|
err = sum / len;
|
||
|
rmserr = sqrt(sumsq / len);
|
||
|
printf(" %s: Avg err: %f RMS err: %f\n", name, err, rmserr);
|
||
|
}
|
||
|
|
||
|
void runtest(float *src, int srclen,
|
||
|
float *ans, int anslen,
|
||
|
double factor)
|
||
|
{
|
||
|
struct timeval tv0, tv1;
|
||
|
int dstlen = (int)(srclen * factor);
|
||
|
float *dst_rs = (float *)malloc((dstlen+100) * sizeof(float));
|
||
|
float *dst_rabbit = (float *)malloc((dstlen+100) * sizeof(float));
|
||
|
void *handle;
|
||
|
SRC_DATA rabbit;
|
||
|
double deltat;
|
||
|
int srcblocksize = srclen;
|
||
|
int dstblocksize = dstlen;
|
||
|
int i, out, out_rabbit, o, srcused;
|
||
|
int statlen, srcpos;
|
||
|
|
||
|
/* do resample */
|
||
|
|
||
|
for(i=0; i<dstlen+100; i++)
|
||
|
dst_rs[i] = -99.0;
|
||
|
|
||
|
gettimeofday(&tv0, NULL);
|
||
|
|
||
|
handle = resample_open(1, factor, factor);
|
||
|
out = 0;
|
||
|
srcpos = 0;
|
||
|
for(;;) {
|
||
|
int srcBlock = MIN(srclen-srcpos, srcblocksize);
|
||
|
int lastFlag = (srcBlock == srclen-srcpos);
|
||
|
|
||
|
o = resample_process(handle, factor,
|
||
|
&src[srcpos], srcBlock,
|
||
|
lastFlag, &srcused,
|
||
|
&dst_rs[out], MIN(dstlen-out, dstblocksize));
|
||
|
srcpos += srcused;
|
||
|
if (o >= 0)
|
||
|
out += o;
|
||
|
if (o < 0 || (o == 0 && srcpos == srclen))
|
||
|
break;
|
||
|
}
|
||
|
resample_close(handle);
|
||
|
|
||
|
gettimeofday(&tv1, NULL);
|
||
|
deltat =
|
||
|
(tv1.tv_sec + tv1.tv_usec * 0.000001) -
|
||
|
(tv0.tv_sec + tv0.tv_usec * 0.000001);
|
||
|
|
||
|
if (o < 0) {
|
||
|
printf("Error: resample_process returned an error: %d\n", o);
|
||
|
}
|
||
|
|
||
|
if (out <= 0) {
|
||
|
printf("Error: resample_process returned %d samples\n", out);
|
||
|
free(dst_rs);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
printf(" resample: %.3f seconds, %d outputs\n", deltat, out);
|
||
|
|
||
|
/* do rabbit (Erik's libsamplerate) */
|
||
|
|
||
|
for(i=0; i<dstlen+100; i++)
|
||
|
dst_rabbit[i] = -99.0;
|
||
|
|
||
|
rabbit.data_in = src;
|
||
|
rabbit.data_out = dst_rabbit;
|
||
|
rabbit.input_frames = srclen;
|
||
|
rabbit.output_frames = dstlen;
|
||
|
rabbit.input_frames_used = 0;
|
||
|
rabbit.output_frames_gen = 0;
|
||
|
rabbit.end_of_input = 1;
|
||
|
rabbit.src_ratio = factor;
|
||
|
|
||
|
gettimeofday(&tv0, NULL);
|
||
|
|
||
|
/* src_simple(&rabbit, SRC_SINC_BEST_QUALITY, 1); */
|
||
|
src_simple(&rabbit, SRC_SINC_FASTEST, 1);
|
||
|
/* src_simple(&rabbit, SRC_LINEAR, 1); */
|
||
|
|
||
|
gettimeofday(&tv1, NULL);
|
||
|
deltat =
|
||
|
(tv1.tv_sec + tv1.tv_usec * 0.000001) -
|
||
|
(tv0.tv_sec + tv0.tv_usec * 0.000001);
|
||
|
|
||
|
out_rabbit = rabbit.output_frames_gen;
|
||
|
|
||
|
printf(" rabbit : %.3f seconds, %d outputs\n",
|
||
|
deltat, out_rabbit);
|
||
|
|
||
|
statlen = MIN(out, out_rabbit);
|
||
|
if (anslen > 0)
|
||
|
statlen = MIN(statlen, anslen);
|
||
|
|
||
|
if (ans) {
|
||
|
dostat("resample ", dst_rs, ans, statlen);
|
||
|
dostat("rabbit ", dst_rabbit, ans, statlen);
|
||
|
}
|
||
|
dostat( "RS vs rabbit", dst_rs, dst_rabbit, statlen);
|
||
|
|
||
|
free(dst_rs);
|
||
|
free(dst_rabbit);
|
||
|
}
|
||
|
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
int i, srclen;
|
||
|
float *src, *ans;
|
||
|
|
||
|
printf("\n*** sin wave, factor = 1.0 *** \n\n");
|
||
|
srclen = 100000;
|
||
|
src = malloc(srclen * sizeof(float));
|
||
|
for(i=0; i<srclen; i++)
|
||
|
src[i] = sin(i/100.0);
|
||
|
|
||
|
runtest(src, srclen, src, srclen, 1.0);
|
||
|
|
||
|
printf("\n*** sin wave, factor = 0.25 *** \n\n");
|
||
|
srclen = 100000;
|
||
|
for(i=0; i<srclen; i++)
|
||
|
src[i] = sin(i/100.0);
|
||
|
ans = malloc((srclen/4) * sizeof(float));
|
||
|
for(i=0; i<srclen/4; i++)
|
||
|
ans[i] = sin(i/25.0);
|
||
|
|
||
|
runtest(src, srclen, ans, srclen/4, 0.25);
|
||
|
free(ans);
|
||
|
|
||
|
printf("\n*** sin wave, factor = 4.0 *** \n\n");
|
||
|
srclen = 20000;
|
||
|
for(i=0; i<srclen; i++)
|
||
|
src[i] = sin(i/100.0);
|
||
|
ans = malloc((srclen*4) * sizeof(float));
|
||
|
for(i=0; i<srclen*4; i++)
|
||
|
ans[i] = sin(i/400.0);
|
||
|
|
||
|
runtest(src, srclen, ans, srclen*4, 4.0);
|
||
|
free(ans);
|
||
|
free(src);
|
||
|
|
||
|
return 0;
|
||
|
}
|