zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

ReverseTest.cpp (4259B)


      1 /*
      2   ZynAddSubFX - a software synthesizer
      3 
      4   ReverseTest.h - CxxTest for Effect/Reverse
      5   Copyright (C) 2024 Mark McCurry
      6 
      7   This program is free software; you can redistribute it and/or
      8   modify it under the terms of the GNU General Public License
      9   as published by the Free Software Foundation; either version 2
     10   of the License, or (at your option) any later version.
     11 */
     12 #include "test-suite.h"
     13 #include <cmath>
     14 #include <cstdlib>
     15 #include <iostream>
     16 #include "../Effects/Reverse.h"
     17 #include "../Misc/Allocator.h"
     18 #include "../Misc/Time.h"
     19 #include "../globals.h"
     20 
     21 using namespace std;
     22 using namespace zyn;
     23 
     24 SYNTH_T *synth;
     25 
     26 class ReverseTest
     27 {
     28     public:
     29         void setUp() {
     30             synth = new SYNTH_T;
     31             time  = new AbsTime(*synth);
     32             outL  = new float[synth->buffersize];
     33             for(int i = 0; i < synth->buffersize; ++i)
     34                 outL[i] = 0.0f;
     35             outR = new float[synth->buffersize];
     36             for(int i = 0; i < synth->buffersize; ++i)
     37                 outR[i] = 0.0f;
     38             input = new Stereo<float *>(new float[synth->buffersize],
     39                                         new float[synth->buffersize]);
     40             for(int i = 0; i < synth->buffersize; ++i)
     41                 input->l[i] = input->r[i] = 0.0f;
     42             EffectParams pars{alloc,true, outL, outR, 0, 44100, 256, nullptr};
     43             testFX = new Reverse(pars,time);
     44         }
     45 
     46         void tearDown() {
     47             delete[] input->r;
     48             delete[] input->l;
     49             delete input;
     50             delete[] outL;
     51             delete[] outR;
     52             delete testFX;
     53             delete time;
     54             delete synth;
     55         }
     56 
     57 
     58         void testInit() {
     59             //Make sure that the output will be zero at start
     60             //(given a zero input)
     61             testFX->out(*input);
     62             for(int i = 0; i < synth->buffersize; ++i) {
     63                 TS_ASSERT_DELTA(outL[i], 0.0f, 0.0001f);
     64                 TS_ASSERT_DELTA(outR[i], 0.0f, 0.0001f);
     65             }
     66         }
     67 
     68         void testClear() {
     69             char DELAY = 2;
     70             char MODE = 6;
     71             testFX->changepar(DELAY, 127);
     72             testFX->changepar(MODE, 2);
     73 
     74             //flood with high input
     75             for(int i = 0; i < synth->buffersize; ++i)
     76                 input->r[i] = input->l[i] = 1.0f;
     77 
     78             for(int i = 0; i < 5000; ++i)
     79                 testFX->out(*input);
     80             for(int i = 0; i < synth->buffersize; ++i) {
     81                 TS_ASSERT(outL[i] != 0.0f);
     82                 TS_ASSERT(outR[i] != 0.0f);
     83             }
     84             //After making sure the internal buffer has a nonzero value
     85             //cleanup
     86             //Then get the next output, which should be zereoed out if DELAY
     87             //is large enough
     88             testFX->cleanup();
     89             testFX->out(*input);
     90             for(int i = 0; i < synth->buffersize; ++i) {
     91                 TS_ASSERT_DELTA(outL[i], 0.0f, 0.0001f);
     92                 TS_ASSERT_DELTA(outR[i], 0.0f, 0.0001f);
     93             }
     94         }
     95         //Insures that the proper decay occurs with high feedback
     96         void testRandom() {
     97             const int steps = 100000;
     98             for(int i = 0; i < steps; ++i) {
     99 
    100                 //input is [-0.5..0.5]
    101                 for(int j = 0; j < synth->buffersize; ++j)
    102                     input->r[j] = input->l[j] = RND-0.5;
    103 
    104                 for(int j = 0; j < 6; ++j) {
    105                     if(RND < 0.01) {//1% chance a paramter change occurs
    106                         int value = prng()%128;
    107                         if(j == 6)
    108                             value = prng()%8;
    109                         testFX->changepar(j, value);
    110                     }
    111                 }
    112 
    113                 testFX->out(*input);
    114 
    115                 for(int i = 0; i < synth->buffersize; ++i) {
    116                     TS_ASSERT(fabsf(outL[i]) < 0.75);
    117                     TS_ASSERT(fabsf(outR[i]) < 0.75);
    118                 }
    119             }
    120         }
    121 
    122 
    123     private:
    124         Stereo<float *> *input;
    125         float *outR, *outL;
    126         AbsTime  *time;
    127         Reverse  *testFX;
    128         Alloc alloc;
    129 };
    130 
    131 int main()
    132 {
    133     tap_quiet = 1;
    134     ReverseTest test;
    135     RUN_TEST(testInit);
    136     RUN_TEST(testClear);
    137     RUN_TEST(testRandom);
    138     return test_summary();
    139 }