commit 9d7dca8bcfd18e5c72539b481e1ed7d778d3cca4
parent 67f775efbc4a97f7f28de9fcc9a9f7e54d4bd628
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Mon, 22 Jul 2019 23:11:20 -0400
Format WatchPoint & Formalize Unit Test
Breaks down the trigger test for the watch point system revealing a few bugs.
The TriggerTest is expected to fail with this commit.
Diffstat:
2 files changed, 128 insertions(+), 97 deletions(-)
diff --git a/src/Synth/WatchPoint.cpp b/src/Synth/WatchPoint.cpp
@@ -113,7 +113,7 @@ void WatchManager::tick(void)
arg_types[j] = 'f';
arg_val[j].f = data_list[i][j];
}
-
+
write_back->writeArray(active_list[i], arg_types, arg_val);
deactivate[i] = true;
}
@@ -132,7 +132,7 @@ void WatchManager::tick(void)
memset(prebuffer[i], 0, sizeof(float)*MAX_SAMPLE);
deactivate[i] = false;
trigger[i] = false;
-
+
}
}
@@ -190,8 +190,8 @@ void WatchManager::satisfy(const char *id, float *f, int n)
// printf("\n matched: %s\n", id);
int space = MAX_SAMPLE - sample_list[selected];
-
-
+
+
for(int i = 0; i < n; ++i){
prebuffer[selected][i] = f[i];
}
@@ -205,45 +205,45 @@ void WatchManager::satisfy(const char *id, float *f, int n)
//FIXME buffer overflow
if(space){
for(int i=0; i<space; ++i){
- if(!trigger[selected]){
- if(i == 0)
- i++;
- if (f[i-1] <= 0 && f[i] > 0){
- trigger[selected] = true;
- for(int k=0; k<MAX_WATCH; ++k){
- if(selected != k && !trigger[k]){
- char tmp[128];
- char tmp1[128];
- strcpy(tmp, active_list[selected]);
- strcpy(tmp1, active_list[k]);
-
- if(strlen(active_list[k]) < strlen(active_list[selected]))
- tmp[strlen(tmp)-1] =0;
- else if (strlen(active_list[k]) > strlen(active_list[selected]))
- tmp1[strlen(tmp1)-1] =0;
- if(!strcmp(tmp1,tmp)){
- trigger[k] = true;
- int space_k = MAX_SAMPLE - sample_list[k];
-
- if(space_k >= n)
- space_k = n;
-
- for(int j = i; j < space_k ; ++j){
- data_list[k][sample_list[k]] = prebuffer[k][j];
- sample_list[k]++;
- }
- }
+ if(!trigger[selected]){
+ if(i == 0)
+ i++;
+ if (f[i-1] <= 0 && f[i] > 0){
+ trigger[selected] = true;
+ for(int k=0; k<MAX_WATCH; ++k){
+ if(selected != k && !trigger[k]){
+ char tmp[128];
+ char tmp1[128];
+ strcpy(tmp, active_list[selected]);
+ strcpy(tmp1, active_list[k]);
+
+ if(strlen(active_list[k]) < strlen(active_list[selected]))
+ tmp[strlen(tmp)-1] =0;
+ else if (strlen(active_list[k]) > strlen(active_list[selected]))
+ tmp1[strlen(tmp1)-1] =0;
+ if(!strcmp(tmp1,tmp)){
+ trigger[k] = true;
+ int space_k = MAX_SAMPLE - sample_list[k];
+
+ if(space_k >= n)
+ space_k = n;
+
+ for(int j = i; j < space_k ; ++j){
+ data_list[k][sample_list[k]] = prebuffer[k][j];
+ sample_list[k]++;
}
+ }
}
}
}
+ }
if(trigger[selected]){
data_list[selected][sample_list[selected]] = f[i];
sample_list[selected]++;
}
}
-
+
}
}
}
diff --git a/src/Tests/TriggerTest.h b/src/Tests/TriggerTest.h
@@ -26,6 +26,7 @@
#include "../Params/Presets.h"
#include "../globals.h"
#include <rtosc/thread-link.h>
+#include <rtosc/rtosc.h>
using namespace std;
using namespace zyn;
@@ -55,12 +56,11 @@ class TriggerTest:public CxxTest::TestSuite
synth->buffersize = 32;
synth->alias(false);
outL = new float[synth->buffersize];
- for(int i = 0; i < synth->buffersize; ++i)
- *(outL + i) = 0;
outR = new float[synth->buffersize];
- for(int i = 0; i < synth->buffersize; ++i)
- *(outR + i) = 0;
-
+ for(int i = 0; i < synth->buffersize; ++i) {
+ outL[i] = 0;
+ outR[i] = 0;
+ }
time = new AbsTime(*synth);
@@ -69,17 +69,8 @@ class TriggerTest:public CxxTest::TestSuite
//prepare the default settings
SUBnoteParameters *defaultPreset = new SUBnoteParameters(time);
- XMLwrapper wrap;
- wrap.loadXMLfile(string(SOURCE_DIR)
- + string("/guitar-adnote.xmz"));
- TS_ASSERT(wrap.enterbranch("MASTER"));
- TS_ASSERT(wrap.enterbranch("PART", 1));
- TS_ASSERT(wrap.enterbranch("INSTRUMENT"));
- TS_ASSERT(wrap.enterbranch("INSTRUMENT_KIT"));
- TS_ASSERT(wrap.enterbranch("INSTRUMENT_KIT_ITEM", 0));
- TS_ASSERT(wrap.enterbranch("SUB_SYNTH_PARAMETERS"));
- defaultPreset->getfromXML(wrap);
-
+ sprng(0x7eefdead);
+
controller = new Controller(*synth, time);
//lets go with.... 50! as a nice note
@@ -101,69 +92,109 @@ class TriggerTest:public CxxTest::TestSuite
delete pars;
}
- void testDefaults() {
- //Note: if these tests fail it is due to the relationship between
- //global.h::RND and SUBnote.cpp
-
- int sampleCount = 0;
-
-//#define WRITE_OUTPUT
+ void dump_samples(const char *s) {
+ puts(s);
+ for(int i=0; i<synth->buffersize; ++i)
+ printf(w->prebuffer[0][i]>0?"+":"-");
+ printf("\n");
+ for(int i=0; i<synth->buffersize; ++i)
+ printf(w->prebuffer[1][i]>0?"+":"-");
+ printf("\n");
+ //for(int i=0; i<synth->buffersize; ++i)
+ // printf("%d->%f\n", i, w->prebuffer[0][i]);
+ //for(int i=0; i<synth->buffersize; ++i)
+ // printf("%d->%f\n", i, w->prebuffer[1][i]);
+ }
-#ifdef WRITE_OUTPUT
- ofstream file("subnoteout", ios::out);
-#endif
+ void testCombinedTrigger() {
+ //Generate a note
note->noteout(outL, outR);
-#ifdef WRITE_OUTPUT
- for(int i = 0; i < synth->buffersize; ++i)
- file << outL[i] << std::endl;
-
-#endif
- sampleCount += synth->buffersize;
note->releasekey();
+
+ //Preconditions
+ //
+ //- No pending messages
+ //- No active watch points
+ //
TS_ASSERT(!tr->hasNext());
+ TS_ASSERT_EQUALS(string(""), w->active_list[0]);
+ TS_ASSERT_EQUALS(string(""), w->active_list[1]);
+ TS_ASSERT_EQUALS(0, w->sample_list[0]);
+ TS_ASSERT_EQUALS(0, w->sample_list[1]);
+ TS_ASSERT(!w->trigger_active("noteout"));
+ TS_ASSERT(!w->trigger_active("noteout1"));
+
+ //Setup a watchpoint
+ //
+ // - Watchpoints will be added to the active list in the watch
+ // manager
+ // - Watchpoints will not be triggered
w->add_watch("noteout");
w->add_watch("noteout1");
TS_ASSERT(!w->trigger_active("noteout"));
TS_ASSERT(!w->trigger_active("noteout1"));
+ TS_ASSERT_EQUALS(string("noteout"), w->active_list[0]);
+ TS_ASSERT_EQUALS(string("noteout1"), w->active_list[1]);
+ TS_ASSERT_EQUALS(0, w->sample_list[0]);
+ TS_ASSERT_EQUALS(0, w->sample_list[1]);
+ dump_samples("Initial pre-buffer");
+
+ //Run the system
+ //noteout1 should trigger on this buffer
note->noteout(outL, outR);
- sampleCount += synth->buffersize;
+ w->tick();
+ dump_samples("Step 1 pre-buffer");
+ TS_ASSERT(w->trigger_active("noteout"));
+ TS_ASSERT(w->trigger_active("noteout1"));
+ TS_ASSERT(!tr->hasNext());
+ TS_ASSERT_LESS_THAN_EQUALS(w->sample_list[0], 32);//only 32 have been
+ TS_ASSERT_LESS_THAN_EQUALS(w->sample_list[1], 32);//processed so far
+
+
+ //Both should continue to accumulate samples
note->noteout(outL, outR);
- sampleCount += synth->buffersize;
+ w->tick();
+ dump_samples("Step 2 pre-buffer\n");
TS_ASSERT(w->trigger_active("noteout1"));
TS_ASSERT(w->trigger_active("noteout"));
+ TS_ASSERT(!tr->hasNext());
+ TS_ASSERT_LESS_THAN_EQUALS(w->sample_list[0], 64);//only 64 have been
+ TS_ASSERT_LESS_THAN_EQUALS(w->sample_list[1], 64);//processed so far
+
+ //Continue accum samples
note->noteout(outL, outR);
- sampleCount += synth->buffersize;
+ w->tick();
+ dump_samples("Step 3 pre-buffer\n");
+ TS_ASSERT(w->trigger_active("noteout1"));
+ TS_ASSERT(w->trigger_active("noteout"));
+ TS_ASSERT(!tr->hasNext());
+ TS_ASSERT_LESS_THAN_EQUALS(w->sample_list[0], 96);//only 96 have been
+ TS_ASSERT_LESS_THAN_EQUALS(w->sample_list[1], 96);//processed so far
+
+ //Finish accumulating samples
note->noteout(outL, outR);
- sampleCount += synth->buffersize;
w->tick();
- TS_ASSERT_EQUALS(string("noteout"), tr->read());
-
- while(!note->finished()) {
- note->noteout(outL, outR);
-#ifdef WRITE_OUTPUT
- for(int i = 0; i < synth->buffersize; ++i)
- file << outL[i] << std::endl;
-
-#endif
- sampleCount += synth->buffersize;
- }
-#ifdef WRITE_OUTPUT
- file.close();
-#endif
+ dump_samples("Step 4 pre-buffer\n");
+ TS_ASSERT(!w->trigger_active("noteout1"));
+ TS_ASSERT(!w->trigger_active("noteout"));
+ TS_ASSERT(tr->hasNext());
+
+
+
+#define f32 "ffffffffffffffffffffffffffffffff"
+#define f128 f32 f32 f32 f32
+ //Verify the output to the user interface
+ //if 128 samples are requested, then 128 should be delivered
+ const char *msg1 = tr->read();
+ TS_ASSERT_EQUALS(string("noteout"), msg1);
+ TS_ASSERT_EQUALS(string(f128), rtosc_argument_string(msg1));
+ TS_ASSERT_EQUALS(128, strlen(rtosc_argument_string(msg1)));
+ TS_ASSERT(tr->hasNext());
+ const char *msg2 = tr->read();
+ TS_ASSERT_EQUALS(string("noteout1"), msg2);
+ TS_ASSERT_EQUALS(128, strlen(rtosc_argument_string(msg2)));
+ TS_ASSERT_EQUALS(string(f128), rtosc_argument_string(msg2));
+ TS_ASSERT(!tr->hasNext());
}
-#define OUTPUT_PROFILE
-#ifdef OUTPUT_PROFILE
- void testSpeed() {
- const int samps = 15000;
-
- int t_on = clock(); // timer before calling func
- for(int i = 0; i < samps; ++i)
- note->noteout(outL, outR);
- int t_off = clock(); // timer when func returns
-
- printf("SubNoteTest: %f seconds for %d Samples to be generated.\n",
- (static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps);
- }
-#endif
};