2 ZynAddSubFX - a software synthesizer
4 AdNoteTest.h - CxxTest for Synth/SUBnote
5 Copyright (C) 2009-2011 Mark McCurry
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.
14 //Based Upon AdNoteTest.h
15 #include "test-suite.h"
20 #include "../Misc/Master.h"
21 #include "../Misc/Allocator.h"
22 #include "../Misc/Util.h"
23 #include "../Misc/XMLwrapper.h"
24 #include "../Synth/SUBnote.h"
25 #include "../Params/SUBnoteParameters.h"
26 #include "../Params/Presets.h"
27 #include "../globals.h"
28 #include <rtosc/thread-link.h>
29 #include <rtosc/rtosc.h>
40 SUBnoteParameters
*pars
;
44 Controller
*controller
;
47 rtosc::ThreadLink
*tr
;
55 // //First the sensible settings and variables that have to be set:
56 synth
->buffersize
= 32;
58 outL
= new float[synth
->buffersize
];
59 outR
= new float[synth
->buffersize
];
60 for(int i
= 0; i
< synth
->buffersize
; ++i
) {
65 time
= new AbsTime(*synth
);
67 tr
= new rtosc::ThreadLink(1024,3);
68 w
= new WatchManager(tr
);
70 //prepare the default settings
71 SUBnoteParameters
*defaultPreset
= new SUBnoteParameters(time
);
74 controller
= new Controller(*synth
, time
);
76 //lets go with.... 50! as a nice note
77 test_freq_log2
= log2f(440.0f
) + (50.0 - 69.0f
) / 12.0f
;
79 SynthParams pars
{memory
, *controller
, *synth
, *time
, 120, 0, test_freq_log2
, false, prng()};
80 note
= new SUBnote(defaultPreset
, pars
, w
);
81 this->pars
= defaultPreset
;
94 void dump_samples(const char *s
) {
96 for(int i
=0; i
<synth
->buffersize
; ++i
)
97 printf(w
->prebuffer
[0][i
]>0?"+":"-");
99 for(int i
=0; i
<synth
->buffersize
; ++i
)
100 printf(w
->prebuffer
[1][i
]>0?"+":"-");
102 //for(int i=0; i<synth->buffersize; ++i)
103 // printf("%d->%f\n", i, w->prebuffer[0][i]);
104 //for(int i=0; i<synth->buffersize; ++i)
105 // printf("%d->%f\n", i, w->prebuffer[1][i]);
108 void testSine(void) {
109 //Generate a sine table
110 float data
[1024] = {};
111 for(int i
=0; i
<1024; ++i
)
112 data
[i
] = -sin(2*M_PI
*(i
/1024.0));
116 //- No pending messages
117 //- No active watch points
119 TS_ASSERT(!tr
->hasNext());
120 TS_ASSERT_EQUAL_STR("", w
->active_list
[0]);
121 TS_ASSERT_EQUAL_INT(0, w
->sample_list
[0]);
122 TS_ASSERT(!w
->trigger_active("data"));
125 w
->add_watch("noteout/filter");
126 for(int i
=0; i
<1024; ++i
) {
127 w
->satisfy("noteout/filter", &data
[i
], 1);
130 const char *msg1
= tr
->read();
131 float buf1
[128] = {};
132 assert_non_null(msg1
, "valid message", __LINE__
);
133 TS_ASSERT_EQUAL_INT(127, rtosc_narguments(msg1
));
135 printf("msg1 = %s\n", msg1
);
136 printf("msg1 = <%s>\n", rtosc_argument_string(msg1
));
137 printf("nargs = %d\n", rtosc_narguments(msg1
));
138 for(int i
=0; i
<127; ++i
)
139 buf1
[i
] = rtosc_argument(msg1
, i
).f
;
141 w
->add_watch("noteout/amp_int");
142 for(int i
=0; i
<1024/97; ++i
) {
143 w
->satisfy("noteout/amp_int", &data
[i
*97], 97);
146 const char *msg2
= tr
->read();
147 assert_non_null(msg2
, "valid message", __LINE__
);
148 TS_ASSERT_EQUAL_INT(127, rtosc_narguments(msg2
));
149 float buf2
[128] = {};
150 printf("nargs = %d\n", rtosc_narguments(msg2
));
151 for(int i
=0; i
<127; ++i
)
152 buf2
[i
] = rtosc_argument(msg2
, i
).f
;
153 for(int i
=0; i
<127; ++i
){
154 TS_ASSERT_EQUAL_FLT(buf1
[i
], buf2
[i
]);
155 TS_ASSERT_EQUAL_FLT(buf1
[i
],data
[450+i
]);
156 TS_ASSERT_EQUAL_FLT(buf2
[i
],data
[450+i
]);
160 void testCombinedTrigger() {
162 note
->noteout(outL
, outR
);
167 //- No pending messages
168 //- No active watch points
170 TS_ASSERT(!tr
->hasNext());
171 TS_ASSERT_EQUAL_STR("", w
->active_list
[0]);
172 TS_ASSERT_EQUAL_STR("", w
->active_list
[1]);
173 TS_ASSERT_EQUAL_INT(0, w
->sample_list
[0]);
174 TS_ASSERT_EQUAL_INT(0, w
->sample_list
[1]);
175 TS_ASSERT(!w
->trigger_active("noteout/filter"));
176 TS_ASSERT(!w
->trigger_active("noteout/amp_int"));
180 // - Watchpoints will be added to the active list in the watch
182 // - Watchpoints will not be triggered
183 w
->add_watch("noteout/filter");
184 w
->add_watch("noteout/amp_int");
185 TS_ASSERT(!w
->trigger_active("noteout/filter"));
186 TS_ASSERT(!w
->trigger_active("noteout/amp_int"));
187 TS_ASSERT_EQUAL_STR("noteout/filter", w
->active_list
[0]);
188 TS_ASSERT_EQUAL_STR("noteout/amp_int", w
->active_list
[1]);
189 TS_ASSERT_EQUAL_INT(0, w
->sample_list
[0]);
190 TS_ASSERT_EQUAL_INT(0, w
->sample_list
[1]);
191 dump_samples("Initial pre-buffer");
194 //noteout1 should trigger on this buffer
195 note
->noteout(outL
, outR
);
198 dump_samples("Step 1 pre-buffer");
199 TS_ASSERT(!w
->trigger_active("noteout/filter")); //not active as prebuffer is not filled
200 TS_ASSERT(!w
->trigger_active("noteout/amp_int"));
201 TS_ASSERT(!tr
->hasNext());
202 TS_ASSERT(w
->sample_list
[0] <= 0); // Is 0 as prebuffer not filled
203 TS_ASSERT(w
->sample_list
[1] <= 0);
206 //Both should continue to accumulate samples
207 note
->noteout(outL
, outR
);
209 dump_samples("Step 2 pre-buffer\n");
210 TS_ASSERT(!w
->trigger_active("noteout/filter")); //not active as prebuffer is not filled
211 TS_ASSERT(!w
->trigger_active("noteout/amp_int"));
212 TS_ASSERT(!tr
->hasNext());
213 TS_ASSERT(w
->sample_list
[0] <= 0); // Is 0 as prebuffer not filled
214 TS_ASSERT(w
->sample_list
[1] <= 0);
216 //Continue accum samples
217 note
->noteout(outL
, outR
);
219 dump_samples("Step 3 pre-buffer\n");
220 TS_ASSERT(!w
->trigger_active("noteout/filter"));
221 TS_ASSERT(!w
->trigger_active("noteout/amp_int"));
222 TS_ASSERT(!tr
->hasNext());
223 TS_ASSERT(w
->sample_list
[0] <= 0); // Is 0 as prebuffer not filled
224 TS_ASSERT(w
->sample_list
[1] <= 0);
226 //Finish accumulating samples
227 note
->noteout(outL
, outR
);
229 dump_samples("Step 4 pre-buffer\n");
230 TS_ASSERT(w
->trigger_active("noteout/filter")); // trigger activate and filling post buffer
231 TS_ASSERT(w
->trigger_active("noteout/amp_int"));
232 TS_ASSERT(!tr
->hasNext()); // post buffer not reach 128
233 TS_ASSERT(w
->sample_list
[1] <= 128); // prebuffer + postbuffer filled in
234 TS_ASSERT(w
->sample_list
[0] <= 128);
235 note
->noteout(outL
, outR
);
237 note
->noteout(outL
, outR
);
240 #define f32 "ffffffffffffffffffffffffffffffff"
241 #define f128 f32 f32 f32 f32
242 //Verify the output to the user interface
243 //if 128 samples are requested, then 128 should be delivered
244 const char *msg1
= tr
->read();
245 TS_ASSERT_EQUAL_STR("noteout/filter", msg1
);
246 TS_ASSERT_EQUAL_STR(f128
, rtosc_argument_string(msg1
));
247 TS_ASSERT_EQUAL_INT(128, strlen(rtosc_argument_string(msg1
)));
248 note
->noteout(outL
, outR
);
250 TS_ASSERT(tr
->hasNext());
251 const char *msg2
= tr
->read();
252 TS_ASSERT_EQUAL_STR("noteout/amp_int", msg2
);
253 TS_ASSERT_EQUAL_INT(128, strlen(rtosc_argument_string(msg2
)));
254 TS_ASSERT_EQUAL_STR(f128
, rtosc_argument_string(msg2
));
255 TS_ASSERT(!tr
->hasNext());
264 RUN_TEST(testCombinedTrigger
);