1 /*
2   ZynAddSubFX - a software synthesizer
3 
4   AdNoteTest.h - CxxTest for Synth/OscilGen
5   Copyright (C) 20011-2012 Mark McCurry
6   Author: Mark McCurry
7 
8   This program is free software; you can redistribute it and/or
9   modify it under the terms of the GNU General Public License
10   as published by the Free Software Foundation; either version 2
11   of the License, or (at your option) any later version.
12 */
13 #include "test-suite.h"
14 #include <string>
15 #include "../Synth/OscilGen.h"
16 #include "../Misc/XMLwrapper.h"
17 #include "../DSP/FFTwrapper.h"
18 #include "../Misc/Util.h"
19 #include "../globals.h"
20 using namespace std;
21 using namespace zyn;
22 
23 SYNTH_T *synth;
24 
25 class OscilGenTest
26 {
27     public:
28         float  freq;
29         float *outR, *outL;
30         FFTwrapper *fft;
31         OscilGen   *oscil;
32 
setUp()33         void setUp() {
34             synth = new SYNTH_T;
35             //First the sensible settings and variables that have to be set:
36             synth->buffersize = 256;
37             synth->oscilsize  = 1024;
38 
39             outL = new float[synth->oscilsize];
40             outR = new float[synth->oscilsize];
41             memset(outL, 0, sizeof(float) * synth->oscilsize);
42             memset(outR, 0, sizeof(float) * synth->oscilsize);
43 
44             //prepare the default settings
45             fft   = new FFTwrapper(synth->oscilsize);
46             oscil = new OscilGen(*synth, fft, NULL);
47 
48             //Assert defaults [TODO]
49 
50 
51             XMLwrapper wrap;
52             wrap.loadXMLfile(string(SOURCE_DIR)
53                               + string("/guitar-adnote.xmz"));
54             TS_ASSERT(wrap.enterbranch("MASTER"));
55             TS_ASSERT(wrap.enterbranch("PART", 0));
56             TS_ASSERT(wrap.enterbranch("INSTRUMENT"));
57             TS_ASSERT(wrap.enterbranch("INSTRUMENT_KIT"));
58             TS_ASSERT(wrap.enterbranch("INSTRUMENT_KIT_ITEM", 0));
59             TS_ASSERT(wrap.enterbranch("ADD_SYNTH_PARAMETERS"));
60             TS_ASSERT(wrap.enterbranch("VOICE", 0));
61             TS_ASSERT(wrap.enterbranch("OSCIL"));
62             oscil->getfromXML(wrap);
63 
64             //verify xml was loaded [TODO]
65 
66             //lets go with.... 50! as a nice note
67             const char testnote = 50;
68             freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f);
69         }
70 
tearDown()71         void tearDown() {
72             delete oscil;
73             delete fft;
74             delete[] outL;
75             delete[] outR;
76             FFT_cleanup();
77             delete synth;
78         }
79 
80         //verifies that initialization occurs
testInit(void)81         void testInit(void)
82         {
83             oscil->get(outL, freq);
84         }
85 
testOutput(void)86         void testOutput(void)
87         {
88             oscil->get(outL, freq);
89             TS_ASSERT_DELTA(outL[23], -0.5371f, 0.0001f);
90             TS_ASSERT_DELTA(outL[129], 0.3613f, 0.0001f);
91             TS_ASSERT_DELTA(outL[586], 0.1118f, 0.0001f);
92             TS_ASSERT_DELTA(outL[1023], -0.6889f, 0.0001f);
93         }
94 
testSpectrum(void)95         void testSpectrum(void)
96         {
97             oscil->getspectrum(synth->oscilsize / 2, outR, 1);
98             TS_ASSERT_DELTA(outR[1], 350.698059f, 0.0001f);
99             TS_ASSERT_DELTA(outR[2], 228.889267f, 0.0001f);
100             TS_ASSERT_DELTA(outR[3], 62.187931f, 0.0001f);
101             TS_ASSERT_DELTA(outR[4], 22.295225f, 0.0001f);
102             TS_ASSERT_DELTA(outR[5], 6.942001f, 0.0001f);
103             TS_ASSERT_DELTA(outR[27], 0.015110f, 0.0001f);
104             TS_ASSERT_DELTA(outR[48], 0.003425f, 0.0001f);
105             TS_ASSERT_DELTA(outR[66], 0.001293f, 0.0001f);
106         }
107 
108         //performance testing
109 #ifdef __linux__
testSpeed()110         void testSpeed() {
111             const int samps = 15000;
112 
113             int t_on = clock(); // timer before calling func
114             for(int i = 0; i < samps; ++i)
115                 oscil->prepare();
116             int t_off = clock(); // timer when func returns
117 
118             printf("OscilGenTest: %f seconds for %d prepares.\n",
119                    (static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps);
120 
121             t_on = clock(); // timer before calling func
122             for(int i = 0; i < samps; ++i)
123                 oscil->get(outL, freq);
124             t_off = clock(); // timer when func returns
125 
126             printf("OscilGenTest: %f seconds for %d gets.\n",
127                    (static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps);
128         }
129 #endif
130 };
131 
main()132 int main()
133 {
134     OscilGenTest test;
135     RUN_TEST(testInit);
136     RUN_TEST(testOutput);
137     RUN_TEST(testSpectrum);
138 #ifdef __linux__
139     RUN_TEST(testSpeed);
140 #endif
141     return test_summary();
142 }
143