diff options
Diffstat (limited to 'trunk/main/libresample/tests')
-rw-r--r-- | trunk/main/libresample/tests/compareresample.c | 183 | ||||
-rw-r--r-- | trunk/main/libresample/tests/resample-sndfile.c | 213 | ||||
-rw-r--r-- | trunk/main/libresample/tests/testresample.c | 182 |
3 files changed, 578 insertions, 0 deletions
diff --git a/trunk/main/libresample/tests/compareresample.c b/trunk/main/libresample/tests/compareresample.c new file mode 100644 index 000000000..8773c9d4e --- /dev/null +++ b/trunk/main/libresample/tests/compareresample.c @@ -0,0 +1,183 @@ +/********************************************************************** + + 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; +} diff --git a/trunk/main/libresample/tests/resample-sndfile.c b/trunk/main/libresample/tests/resample-sndfile.c new file mode 100644 index 000000000..e780228c1 --- /dev/null +++ b/trunk/main/libresample/tests/resample-sndfile.c @@ -0,0 +1,213 @@ +/********************************************************************** + + resample-sndfile.c + + Written 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 <sndfile.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include <sys/time.h> + +#define MIN(A, B) (A) < (B)? (A) : (B) + +void usage(char *progname) +{ + fprintf(stderr, "Usage: %s -by <ratio> <input> <output>\n", progname); + fprintf(stderr, " %s -to <rate> <input> <output>\n", progname); + fprintf(stderr, "\n"); + exit(-1); +} + +int main(int argc, char **argv) +{ + SNDFILE *srcfile, *dstfile; + SF_INFO srcinfo, dstinfo; + SF_FORMAT_INFO formatinfo; + char *extension; + void **handle; + int channels; + int srclen, dstlen; + float *src, *srci; + float *dst, *dsti; + double ratio = 0.0; + double srcrate; + double dstrate = 0.0; + struct timeval tv0, tv1; + double deltat; + int numformats; + int pos, bufferpos, outcount; + int i, c; + + if (argc != 5) + usage(argv[0]); + + if (!strcmp(argv[1], "-by")) { + ratio = atof(argv[2]); + if (ratio <= 0.0) { + fprintf(stderr, "Ratio of %f is illegal\n", ratio); + usage(argv[0]); + } + } + else if (!strcmp(argv[1], "-to")) { + dstrate = atof(argv[2]); + if (dstrate < 10.0 || dstrate > 100000.0) { + fprintf(stderr, "Sample rate of %f is illegal\n", dstrate); + usage(argv[0]); + } + } + else + usage(argv[0]); + + memset(&srcinfo, 0, sizeof(srcinfo)); + memset(&dstinfo, 0, sizeof(dstinfo)); + srcfile = sf_open(argv[3], SFM_READ, &srcinfo); + if (!srcfile) { + fprintf(stderr, "%s", sf_strerror(NULL)); + exit(-1); + } + + srcrate = srcinfo.samplerate; + if (dstrate == 0.0) + dstrate = srcrate * ratio; + else + ratio = dstrate / srcrate; + + channels = srcinfo.channels; + + /* figure out format of destination file */ + + extension = strstr(argv[4], "."); + if (extension) { + extension++; + sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, + &numformats, sizeof(numformats)); + for(i=0; i<numformats; i++) { + memset(&formatinfo, 0, sizeof(formatinfo)); + formatinfo.format = i; + sf_command(NULL, SFC_GET_FORMAT_MAJOR, + &formatinfo, sizeof(formatinfo)); + if (!strcmp(formatinfo.extension, extension)) { + printf("Using %s for output format.\n", formatinfo.name); + dstinfo.format = formatinfo.format | + (srcinfo.format & SF_FORMAT_SUBMASK); + break; + } + } + } + + if (!dstinfo.format) { + if (extension) + printf("Warning: output format (%s) not recognized, " + "using same as input format.\n", + extension); + dstinfo.format = srcinfo.format; + } + + dstinfo.samplerate = (int)(dstrate + 0.5); + dstinfo.channels = channels; + + dstfile = sf_open(argv[4], SFM_WRITE, &dstinfo); + if (!dstfile) { + fprintf(stderr, "%s", sf_strerror(NULL)); + exit(-1); + } + + printf("Source: %s (%d frames, %.2f Hz)\n", + argv[3], (int)srcinfo.frames, srcrate); + printf("Destination: %s (%.2f Hz, ratio=%.5f)\n", argv[4], + dstrate, ratio); + + srclen = 4096; + dstlen = (srclen * ratio + 1000); + srci = (float *)malloc(srclen * channels * sizeof(float)); + dsti = (float *)malloc(dstlen * channels * sizeof(float)); + src = (float *)malloc(srclen * sizeof(float)); + dst = (float *)malloc(dstlen * sizeof(float)); + + handle = (void **)malloc(channels * sizeof(void *)); + for(c=0; c<channels; c++) + handle[c] = resample_open(1, ratio, ratio); + + gettimeofday(&tv0, NULL); + + pos = 0; + bufferpos = 0; + outcount = 0; + while(pos < srcinfo.frames) { + int block = MIN(srclen-bufferpos, srcinfo.frames-pos); + int lastFlag = (pos+block == srcinfo.frames); + int inUsed, inUsed2=0, out=0, out2=0; + + sf_readf_float(srcfile, &srci[bufferpos*channels], block); + block += bufferpos; + + for(c=0; c<channels; c++) { + for(i=0; i<block; i++) + src[i] = srci[i*channels+c]; + + inUsed = 0; + out = resample_process(handle[c], ratio, src, block, lastFlag, + &inUsed, dst, dstlen); + if (c==0) { + inUsed2 = inUsed; + out2 = out; + } + else { + if (inUsed2 != inUsed || out2 != out) { + fprintf(stderr, "Fatal error: channels out of sync!\n"); + exit(-1); + } + } + + for(i=0; i<out; i++) + { + if(dst[i] <= -1) + dsti[i*channels+c] = -1; + else if(dst[i] >= 1) + dsti[i*channels+c] = 1; + else + dsti[i*channels+c] = dst[i]; + } + } + + sf_writef_float(dstfile, dsti, out); + + bufferpos = block - inUsed; + for(i=0; i<bufferpos*channels; i++) + srci[i] = srci[i+(inUsed*channels)]; + pos += inUsed; + outcount += out; + } + + sf_close(srcfile); + sf_close(dstfile); + + gettimeofday(&tv1, NULL); + deltat = + (tv1.tv_sec + tv1.tv_usec * 0.000001) - + (tv0.tv_sec + tv0.tv_usec * 0.000001); + + printf("Elapsed time: %.3f seconds\n", deltat); + printf("%d frames written to output file\n", outcount); + + free(src); + free(srci); + free(dst); + free(dsti); + + exit(0); +} diff --git a/trunk/main/libresample/tests/testresample.c b/trunk/main/libresample/tests/testresample.c new file mode 100644 index 000000000..a59aa8bfd --- /dev/null +++ b/trunk/main/libresample/tests/testresample.c @@ -0,0 +1,182 @@ +/********************************************************************** + + 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; +} |