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

compareresample.c (4509B)


      1 /**********************************************************************
      2 
      3   compareresample.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 <samplerate.h>
     17 
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <math.h>
     21 
     22 #include <sys/time.h>
     23 
     24 #define MIN(A, B) (A) < (B)? (A) : (B)
     25 
     26 void dostat(char *name, float *d1, float *d2, int len)
     27 {
     28    int i;
     29    double sum, sumsq, err, rmserr;
     30 
     31    sum = 0.0;
     32    sumsq = 0.0;
     33    for(i=0; i<len; i++) {
     34       double diff = d1[i] - d2[i];
     35       sum += fabs(diff);
     36       sumsq += diff * diff;
     37    }
     38    err = sum / len;
     39    rmserr = sqrt(sumsq / len);
     40    printf("   %s: Avg err: %f RMS err: %f\n", name, err, rmserr);
     41 }
     42 
     43 void runtest(float *src, int srclen,
     44              float *ans, int anslen,
     45              double factor)
     46 {
     47    struct timeval tv0, tv1;
     48    int dstlen = (int)(srclen * factor);
     49    float *dst_rs = (float *)malloc((dstlen+100) * sizeof(float));
     50    float *dst_rabbit = (float *)malloc((dstlen+100) * sizeof(float));
     51    void *handle;
     52    SRC_DATA rabbit;
     53    double deltat;
     54    int srcblocksize = srclen;
     55    int dstblocksize = dstlen;
     56    int i, out, out_rabbit, o, srcused;
     57    int statlen, srcpos;
     58 
     59    /* do resample */
     60 
     61    for(i=0; i<dstlen+100; i++)
     62       dst_rs[i] = -99.0;
     63 
     64    gettimeofday(&tv0, NULL);
     65 
     66    handle = resample_open(1, factor, factor);
     67    out = 0;
     68    srcpos = 0;
     69    for(;;) {
     70       int srcBlock = MIN(srclen-srcpos, srcblocksize);
     71       int lastFlag = (srcBlock == srclen-srcpos);
     72 
     73       o = resample_process(handle, factor,
     74                            &src[srcpos], srcBlock,
     75                            lastFlag, &srcused,
     76                            &dst_rs[out], MIN(dstlen-out, dstblocksize));
     77       srcpos += srcused;
     78       if (o >= 0)
     79          out += o;
     80       if (o < 0 || (o == 0 && srcpos == srclen))
     81          break;
     82    }
     83    resample_close(handle);
     84 
     85    gettimeofday(&tv1, NULL);
     86    deltat =
     87       (tv1.tv_sec + tv1.tv_usec * 0.000001) -
     88       (tv0.tv_sec + tv0.tv_usec * 0.000001);
     89 
     90    if (o < 0) {
     91       printf("Error: resample_process returned an error: %d\n", o);
     92    }
     93 
     94    if (out <= 0) {
     95       printf("Error: resample_process returned %d samples\n", out);
     96       free(dst_rs);
     97       return;
     98    }
     99 
    100    printf("   resample: %.3f seconds, %d outputs\n", deltat, out);
    101 
    102    /* do rabbit (Erik's libsamplerate) */
    103 
    104    for(i=0; i<dstlen+100; i++)
    105       dst_rabbit[i] = -99.0;
    106 
    107    rabbit.data_in = src;
    108    rabbit.data_out = dst_rabbit;
    109    rabbit.input_frames = srclen;
    110    rabbit.output_frames = dstlen;
    111    rabbit.input_frames_used = 0;
    112    rabbit.output_frames_gen = 0;
    113    rabbit.end_of_input = 1;
    114    rabbit.src_ratio = factor;
    115 
    116    gettimeofday(&tv0, NULL);
    117 
    118    /* src_simple(&rabbit, SRC_SINC_BEST_QUALITY, 1); */
    119    src_simple(&rabbit, SRC_SINC_FASTEST, 1);
    120    /* src_simple(&rabbit, SRC_LINEAR, 1); */
    121 
    122    gettimeofday(&tv1, NULL);
    123    deltat =
    124       (tv1.tv_sec + tv1.tv_usec * 0.000001) -
    125       (tv0.tv_sec + tv0.tv_usec * 0.000001);
    126 
    127    out_rabbit = rabbit.output_frames_gen;
    128 
    129    printf("   rabbit  : %.3f seconds, %d outputs\n",
    130           deltat, out_rabbit);
    131 
    132    statlen = MIN(out, out_rabbit);
    133    if (anslen > 0)
    134       statlen = MIN(statlen, anslen);
    135 
    136    if (ans) {
    137       dostat("resample    ", dst_rs, ans, statlen);
    138       dostat("rabbit      ", dst_rabbit, ans, statlen);
    139    }
    140    dostat(   "RS vs rabbit", dst_rs, dst_rabbit, statlen);
    141 
    142    free(dst_rs);
    143    free(dst_rabbit);
    144 }
    145 
    146 int main(int argc, char **argv)
    147 {
    148    int i, srclen;
    149    float *src, *ans;
    150 
    151    printf("\n*** sin wave, factor = 1.0 *** \n\n");
    152    srclen = 100000;
    153    src = malloc(srclen * sizeof(float));
    154    for(i=0; i<srclen; i++)
    155       src[i] = sin(i/100.0);
    156 
    157    runtest(src, srclen, src, srclen, 1.0);
    158 
    159    printf("\n*** sin wave, factor = 0.25 *** \n\n");
    160    srclen = 100000;
    161    for(i=0; i<srclen; i++)
    162       src[i] = sin(i/100.0);
    163    ans = malloc((srclen/4) * sizeof(float));
    164    for(i=0; i<srclen/4; i++)
    165       ans[i] = sin(i/25.0);
    166 
    167    runtest(src, srclen, ans, srclen/4, 0.25);
    168    free(ans);
    169 
    170    printf("\n*** sin wave, factor = 4.0 *** \n\n");
    171    srclen = 20000;
    172    for(i=0; i<srclen; i++)
    173       src[i] = sin(i/100.0);
    174    ans = malloc((srclen*4) * sizeof(float));
    175    for(i=0; i<srclen*4; i++)
    176       ans[i] = sin(i/400.0);
    177 
    178    runtest(src, srclen, ans, srclen*4, 4.0);
    179    free(ans);
    180    free(src);
    181 
    182    return 0;
    183 }