gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

testresample.c (5280B)


      1 /**********************************************************************
      2 
      3   testresample.c
      4 
      5   Real-time library interface by Dominic Mazzoni
      6 
      7   Based on resample-1.7:
      8     http://www-ccrma.stanford.edu/~jos/resample/
      9 
     10   Dual-licensed as LGPL and BSD; see README.md and LICENSE* files.
     11 
     12 **********************************************************************/
     13 
     14 #include "../include/libresample.h"
     15 
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <math.h>
     19 
     20 #define MIN(A, B) (A) < (B)? (A) : (B)
     21 
     22 void runtest(int srclen, double freq, double factor,
     23              int srcblocksize, int dstblocksize)
     24 {
     25    int expectedlen = (int)(srclen * factor);
     26    int dstlen = expectedlen + 1000;
     27    float *src = (float *)malloc((srclen+100) * sizeof(float));
     28    float *dst = (float *)malloc((dstlen+100) * sizeof(float));
     29    void *handle;
     30    double sum, sumsq, err, rmserr;
     31    int i, out, o, srcused, errcount, rangecount;
     32    int statlen, srcpos, lendiff;
     33    int fwidth;
     34 
     35    printf("-- srclen: %d sin freq: %.1f factor: %.3f srcblk: %d dstblk: %d\n",
     36           srclen, freq, factor, srcblocksize, dstblocksize);
     37 
     38    for(i=0; i<srclen; i++)
     39       src[i] = sin(i/freq);
     40    for(i=srclen; i<srclen+100; i++)
     41       src[i] = -99.0;
     42 
     43    for(i=0; i<dstlen+100; i++)
     44       dst[i] = -99.0;
     45 
     46    handle = resample_open(1, factor, factor);
     47    fwidth = resample_get_filter_width(handle);
     48    out = 0;
     49    srcpos = 0;
     50    for(;;) {
     51       int srcBlock = MIN(srclen-srcpos, srcblocksize);
     52       int lastFlag = (srcBlock == srclen-srcpos);
     53 
     54       o = resample_process(handle, factor,
     55                            &src[srcpos], srcBlock,
     56                            lastFlag, &srcused,
     57                            &dst[out], MIN(dstlen-out, dstblocksize));
     58       srcpos += srcused;
     59       if (o >= 0)
     60          out += o;
     61       if (o < 0 || (o == 0 && srcpos == srclen))
     62          break;
     63    }
     64    resample_close(handle);
     65 
     66    if (o < 0) {
     67       printf("Error: resample_process returned an error: %d\n", o);
     68    }
     69 
     70    if (out <= 0) {
     71       printf("Error: resample_process returned %d samples\n", out);
     72       free(src);
     73       free(dst);
     74       return;
     75    }
     76 
     77    lendiff = abs(out - expectedlen);
     78    if (lendiff > (int)(2*factor + 1.0)) {
     79       printf("   Expected ~%d, got %d samples out\n",
     80              expectedlen, out);
     81    }
     82    
     83    sum = 0.0;
     84    sumsq = 0.0;
     85    errcount = 0.0;
     86 
     87    /* Don't compute statistics on all output values; the last few
     88       are guaranteed to be off because it's based on far less
     89       interpolation. */
     90    statlen = out - fwidth;
     91 
     92    for(i=0; i<statlen; i++) {
     93       double diff = sin((i/freq)/factor) - dst[i];
     94       if (fabs(diff) > 0.05) {
     95          if (errcount == 0)
     96             printf("   First error at i=%d: expected %.3f, got %.3f\n",
     97                    i, sin((i/freq)/factor), dst[i]);
     98          errcount++;
     99       }
    100       sum += fabs(diff);
    101       sumsq += diff * diff;
    102    }
    103 
    104    rangecount = 0;
    105    for(i=0; i<statlen; i++) {
    106       if (dst[i] < -1.01 || dst[i] > 1.01) {
    107          if (rangecount == 0)
    108             printf("   Error at i=%d: value is %.3f\n", i, dst[i]);
    109          rangecount++;
    110       }
    111    }
    112    if (rangecount > 1)
    113       printf("   At least %d samples were out of range\n", rangecount);
    114 
    115    if (errcount > 0) {
    116       i = out - 1;
    117       printf("   i=%d:  expected %.3f, got %.3f\n",
    118              i, sin((i/freq)/factor), dst[i]);
    119       printf("   At least %d samples had significant error.\n", errcount);
    120    }
    121    err = sum / statlen;
    122    rmserr = sqrt(sumsq / statlen);
    123    printf("   Out: %d samples  Avg err: %f RMS err: %f\n", out, err, rmserr);
    124    free(src);
    125    free(dst);
    126 }
    127 
    128 int main(int argc, char **argv)
    129 {
    130    int i, srclen, dstlen, ifreq;
    131    double factor;
    132 
    133    printf("\n*** Vary source block size*** \n\n");
    134    srclen = 10000;
    135    ifreq = 100;
    136    for(i=0; i<20; i++) {
    137       factor = ((rand() % 16) + 1) / 4.0;
    138       dstlen = (int)(srclen * factor + 10);
    139       runtest(srclen, (double)ifreq, factor, 64, dstlen);
    140       runtest(srclen, (double)ifreq, factor, 32, dstlen);
    141       runtest(srclen, (double)ifreq, factor, 8, dstlen);
    142       runtest(srclen, (double)ifreq, factor, 2, dstlen);
    143       runtest(srclen, (double)ifreq, factor, srclen, dstlen);
    144    }
    145 
    146    printf("\n*** Vary dest block size ***\n\n");
    147    srclen = 10000;
    148    ifreq = 100;
    149    for(i=0; i<20; i++) {
    150       factor = ((rand() % 16) + 1) / 4.0;
    151       runtest(srclen, (double)ifreq, factor, srclen, 32);
    152       dstlen = (int)(srclen * factor + 10);
    153       runtest(srclen, (double)ifreq, factor, srclen, dstlen);
    154    }
    155 
    156    printf("\n*** Resample factor 1.0, testing different srclen ***\n\n");
    157    ifreq = 40;
    158    for(i=0; i<100; i++) {
    159       srclen = (rand() % 30000) + 10;
    160       dstlen = (int)(srclen + 10);
    161       runtest(srclen, (double)ifreq, 1.0, srclen, dstlen);
    162    }
    163 
    164    printf("\n*** Resample factor 1.0, testing different sin freq ***\n\n");
    165    srclen = 10000;
    166    for(i=0; i<100; i++) {
    167       ifreq = ((int)rand() % 10000) + 1;
    168       dstlen = (int)(srclen * 10);
    169       runtest(srclen, (double)ifreq, 1.0, srclen, dstlen);
    170    }
    171 
    172    printf("\n*** Resample with different factors ***\n\n");
    173    srclen = 10000;
    174    ifreq = 100;
    175    for(i=0; i<100; i++) {
    176       factor = ((rand() % 64) + 1) / 4.0;
    177       dstlen = (int)(srclen * factor + 10);
    178       runtest(srclen, (double)ifreq, factor, srclen, dstlen);
    179    }
    180 
    181    return 0;
    182 }