summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJeffrey C. Ollie <jeff@ocjtech.us>2008-09-11 00:51:00 -0500
committerJeffrey C. Ollie <jeff@ocjtech.us>2008-09-11 00:51:00 -0500
commitaa2c396b174fb4bc11af10b9a50ae4c045eeb00d (patch)
treec020a8248a1a4a0916dd34dc5e3a1865bc210b68 /tests
downloadlibresample-aa2c396b174fb4bc11af10b9a50ae4c045eeb00d.tar.gz
libresample-aa2c396b174fb4bc11af10b9a50ae4c045eeb00d.tar.xz
libresample-aa2c396b174fb4bc11af10b9a50ae4c045eeb00d.zip
Initial import of libresample 0.1.3libresample-0.1.3vendor
Diffstat (limited to 'tests')
-rw-r--r--tests/compareresample.c183
-rw-r--r--tests/resample-sndfile.c213
-rw-r--r--tests/testresample.c182
3 files changed, 578 insertions, 0 deletions
diff --git a/tests/compareresample.c b/tests/compareresample.c
new file mode 100644
index 0000000..8773c9d
--- /dev/null
+++ b/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/tests/resample-sndfile.c b/tests/resample-sndfile.c
new file mode 100644
index 0000000..e780228
--- /dev/null
+++ b/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/tests/testresample.c b/tests/testresample.c
new file mode 100644
index 0000000..a59aa8b
--- /dev/null
+++ b/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;
+}