forked from Mirrors/freeswitch
32fce49ba3
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2880 d0543943-73ff-0310-b7d9-9358b9ac24b2
183 lines
5.2 KiB
C
183 lines
5.2 KiB
C
/**********************************************************************
|
|
|
|
testresample.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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#define MIN(A, B) (A) < (B)? (A) : (B)
|
|
|
|
void runtest(int srclen, double freq, double factor,
|
|
int srcblocksize, int dstblocksize)
|
|
{
|
|
int expectedlen = (int)(srclen * factor);
|
|
int dstlen = expectedlen + 1000;
|
|
float *src = (float *)malloc((srclen+100) * sizeof(float));
|
|
float *dst = (float *)malloc((dstlen+100) * sizeof(float));
|
|
void *handle;
|
|
double sum, sumsq, err, rmserr;
|
|
int i, out, o, srcused, errcount, rangecount;
|
|
int statlen, srcpos, lendiff;
|
|
int fwidth;
|
|
|
|
printf("-- srclen: %d sin freq: %.1f factor: %.3f srcblk: %d dstblk: %d\n",
|
|
srclen, freq, factor, srcblocksize, dstblocksize);
|
|
|
|
for(i=0; i<srclen; i++)
|
|
src[i] = sin(i/freq);
|
|
for(i=srclen; i<srclen+100; i++)
|
|
src[i] = -99.0;
|
|
|
|
for(i=0; i<dstlen+100; i++)
|
|
dst[i] = -99.0;
|
|
|
|
handle = resample_open(1, factor, factor);
|
|
fwidth = resample_get_filter_width(handle);
|
|
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[out], MIN(dstlen-out, dstblocksize));
|
|
srcpos += srcused;
|
|
if (o >= 0)
|
|
out += o;
|
|
if (o < 0 || (o == 0 && srcpos == srclen))
|
|
break;
|
|
}
|
|
resample_close(handle);
|
|
|
|
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(src);
|
|
free(dst);
|
|
return;
|
|
}
|
|
|
|
lendiff = abs(out - expectedlen);
|
|
if (lendiff > (int)(2*factor + 1.0)) {
|
|
printf(" Expected ~%d, got %d samples out\n",
|
|
expectedlen, out);
|
|
}
|
|
|
|
sum = 0.0;
|
|
sumsq = 0.0;
|
|
errcount = 0.0;
|
|
|
|
/* Don't compute statistics on all output values; the last few
|
|
are guaranteed to be off because it's based on far less
|
|
interpolation. */
|
|
statlen = out - fwidth;
|
|
|
|
for(i=0; i<statlen; i++) {
|
|
double diff = sin((i/freq)/factor) - dst[i];
|
|
if (fabs(diff) > 0.05) {
|
|
if (errcount == 0)
|
|
printf(" First error at i=%d: expected %.3f, got %.3f\n",
|
|
i, sin((i/freq)/factor), dst[i]);
|
|
errcount++;
|
|
}
|
|
sum += fabs(diff);
|
|
sumsq += diff * diff;
|
|
}
|
|
|
|
rangecount = 0;
|
|
for(i=0; i<statlen; i++) {
|
|
if (dst[i] < -1.01 || dst[i] > 1.01) {
|
|
if (rangecount == 0)
|
|
printf(" Error at i=%d: value is %.3f\n", i, dst[i]);
|
|
rangecount++;
|
|
}
|
|
}
|
|
if (rangecount > 1)
|
|
printf(" At least %d samples were out of range\n", rangecount);
|
|
|
|
if (errcount > 0) {
|
|
i = out - 1;
|
|
printf(" i=%d: expected %.3f, got %.3f\n",
|
|
i, sin((i/freq)/factor), dst[i]);
|
|
printf(" At least %d samples had significant error.\n", errcount);
|
|
}
|
|
err = sum / statlen;
|
|
rmserr = sqrt(sumsq / statlen);
|
|
printf(" Out: %d samples Avg err: %f RMS err: %f\n", out, err, rmserr);
|
|
free(src);
|
|
free(dst);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int i, srclen, dstlen, ifreq;
|
|
double factor;
|
|
|
|
printf("\n*** Vary source block size*** \n\n");
|
|
srclen = 10000;
|
|
ifreq = 100;
|
|
for(i=0; i<20; i++) {
|
|
factor = ((rand() % 16) + 1) / 4.0;
|
|
dstlen = (int)(srclen * factor + 10);
|
|
runtest(srclen, (double)ifreq, factor, 64, dstlen);
|
|
runtest(srclen, (double)ifreq, factor, 32, dstlen);
|
|
runtest(srclen, (double)ifreq, factor, 8, dstlen);
|
|
runtest(srclen, (double)ifreq, factor, 2, dstlen);
|
|
runtest(srclen, (double)ifreq, factor, srclen, dstlen);
|
|
}
|
|
|
|
printf("\n*** Vary dest block size ***\n\n");
|
|
srclen = 10000;
|
|
ifreq = 100;
|
|
for(i=0; i<20; i++) {
|
|
factor = ((rand() % 16) + 1) / 4.0;
|
|
runtest(srclen, (double)ifreq, factor, srclen, 32);
|
|
dstlen = (int)(srclen * factor + 10);
|
|
runtest(srclen, (double)ifreq, factor, srclen, dstlen);
|
|
}
|
|
|
|
printf("\n*** Resample factor 1.0, testing different srclen ***\n\n");
|
|
ifreq = 40;
|
|
for(i=0; i<100; i++) {
|
|
srclen = (rand() % 30000) + 10;
|
|
dstlen = (int)(srclen + 10);
|
|
runtest(srclen, (double)ifreq, 1.0, srclen, dstlen);
|
|
}
|
|
|
|
printf("\n*** Resample factor 1.0, testing different sin freq ***\n\n");
|
|
srclen = 10000;
|
|
for(i=0; i<100; i++) {
|
|
ifreq = ((int)rand() % 10000) + 1;
|
|
dstlen = (int)(srclen * 10);
|
|
runtest(srclen, (double)ifreq, 1.0, srclen, dstlen);
|
|
}
|
|
|
|
printf("\n*** Resample with different factors ***\n\n");
|
|
srclen = 10000;
|
|
ifreq = 100;
|
|
for(i=0; i<100; i++) {
|
|
factor = ((rand() % 64) + 1) / 4.0;
|
|
dstlen = (int)(srclen * factor + 10);
|
|
runtest(srclen, (double)ifreq, factor, srclen, dstlen);
|
|
}
|
|
|
|
return 0;
|
|
}
|