1 /*
2   ZynAddSubFX - a software synthesizer
3 
4   EchoTest.h - CxxTest for Effect/Echo
5   Copyright (C) 2009-2011 Mark McCurry
6   Copyright (C) 2009 Harald Hvaal
7   Authors: Mark McCurry, Harald Hvaal
8 
9   This program is free software; you can redistribute it and/or
10   modify it under the terms of the GNU General Public License
11   as published by the Free Software Foundation; either version 2
12   of the License, or (at your option) any later version.
13 */
14 #include "test-suite.h"
15 #include <cmath>
16 #include <cstdlib>
17 #include <iostream>
18 #include "../Effects/Echo.h"
19 #include "../Misc/Allocator.h"
20 #include "../globals.h"
21 
22 using namespace std;
23 using namespace zyn;
24 
25 SYNTH_T *synth;
26 
27 class EchoTest
28 {
29     public:
setUp()30         void setUp() {
31             synth = new SYNTH_T;
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 Echo(pars);
44         }
45 
tearDown()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 synth;
54         }
55 
56 
testInit()57         void testInit() {
58             //Make sure that the output will be zero at start
59             //(given a zero input)
60             testFX->out(*input);
61             for(int i = 0; i < synth->buffersize; ++i) {
62                 TS_ASSERT_DELTA(outL[i], 0.0f, 0.0001f);
63                 TS_ASSERT_DELTA(outR[i], 0.0f, 0.0001f);
64             }
65         }
66 
testClear()67         void testClear() {
68             char DELAY = 2;
69             testFX->changepar(DELAY, 127);
70 
71             //flood with high input
72             for(int i = 0; i < synth->buffersize; ++i)
73                 input->r[i] = input->l[i] = 1.0f;
74 
75             for(int i = 0; i < 500; ++i)
76                 testFX->out(*input);
77             for(int i = 0; i < synth->buffersize; ++i) {
78                 TS_ASSERT(outL[i] != 0.0f);
79                 TS_ASSERT(outR[i] != 0.0f);
80             }
81             //After making sure the internal buffer has a nonzero value
82             //cleanup
83             //Then get the next output, which should be zereoed out if DELAY
84             //is large enough
85             testFX->cleanup();
86             testFX->out(*input);
87             for(int i = 0; i < synth->buffersize; ++i) {
88                 TS_ASSERT_DELTA(outL[i], 0.0f, 0.0001f);
89                 TS_ASSERT_DELTA(outR[i], 0.0f, 0.0001f);
90             }
91         }
92         //Insures that the proper decay occurs with high feedback
testDecaywFb()93         void testDecaywFb() {
94             //flood with high input
95             for(int i = 0; i < synth->buffersize; ++i)
96                 input->r[i] = input->l[i] = 1.0f;
97             char FEEDBACK = 5;
98             testFX->changepar(FEEDBACK, 127);
99             for(int i = 0; i < 100; ++i)
100                 testFX->out(*input);
101             for(int i = 0; i < synth->buffersize; ++i) {
102                 TS_ASSERT(outL[i] != 0.0f);
103                 TS_ASSERT(outR[i] != 0.0f);
104             }
105             float amp = abs(outL[0] + outR[0]) / 2;
106             //reset input to zero
107             for(int i = 0; i < synth->buffersize; ++i)
108                 input->r[i] = input->l[i] = 0.0f;
109 
110             //give the echo time to fade based upon zero input and high feedback
111             for(int i = 0; i < 50; ++i)
112                 testFX->out(*input);
113             TS_ASSERT(abs(outL[0] + outR[0]) / 2 <= amp);
114         }
115 
116 
117     private:
118         Stereo<float *> *input;
119         float *outR, *outL;
120         Echo  *testFX;
121         Alloc alloc;
122 };
123 
main()124 int main()
125 {
126     tap_quiet = 1;
127     EchoTest test;
128     RUN_TEST(testInit);
129     RUN_TEST(testClear);
130     RUN_TEST(testDecaywFb);
131     return test_summary();
132 }
133