commit 67f775efbc4a97f7f28de9fcc9a9f7e54d4bd628
parent 6e838ba43db848a0645e96d8609310b23db7ea7b
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Mon, 22 Jul 2019 22:32:41 -0400
Merge WIP GSoC Signal Scope PR
Diffstat:
15 files changed, 346 insertions(+), 34 deletions(-)
diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp
@@ -369,7 +369,8 @@ static const Ports automate_ports = {
static const Ports watchPorts = {
{"add:s", rDoc("Add synthesis state to watch"), 0,
rBegin;
- m->watcher.add_watch(rtosc_argument(msg,0).s);
+ if(!m->watcher.active(rtosc_argument(msg,0).s))
+ m->watcher.add_watch(rtosc_argument(msg,0).s);
rEnd},
};
diff --git a/src/Synth/ADnote.cpp b/src/Synth/ADnote.cpp
@@ -32,7 +32,7 @@ namespace zyn {
ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars,
WatchManager *wm, const char *prefix)
- :SynthNote(spars), pars(*pars_)
+ :SynthNote(spars), pars(*pars_), watchOut(wm, prefix, "noteout"), watchOut1(wm,prefix,"noteout1")
{
memory.beginTransaction();
tmpwavel = memory.valloc<float>(synth.buffersize);
@@ -1701,9 +1701,11 @@ int ADnote::noteout(float *outl, float *outr)
else
for(int i = 0; i < synth.buffersize; ++i)
tmpwavel[i] += tw[i];
+ if(nvoice == 0)
+ watchOut(tmpwavel,synth.buffersize);
+
+ watchOut1(tmpwavel,synth.buffersize);
}
-
-
float unison_amplitude = 1.0f / sqrt(unison_size[nvoice]); //reduce the amplitude for large unison sizes
// Amplitude
float oldam = oldamplitude[nvoice] * unison_amplitude;
diff --git a/src/Synth/ADnote.h b/src/Synth/ADnote.h
@@ -19,6 +19,7 @@
#include "LFO.h"
#include "../Params/ADnoteParameters.h"
#include "../Params/Controller.h"
+#include "WatchPoint.h"
//Globals
@@ -57,7 +58,7 @@ class ADnote:public SynthNote
int setupVoiceUnison(int nvoice);
void setupVoiceDetune(int nvoice);
void setupVoiceMod(int nvoice, bool first_run = true);
-
+ VecWatchPoint watchOut,watchOut1;
/**Changes the frequency of an oscillator.
* @param nvoice voice to run computations on
* @param in_freq new frequency*/
diff --git a/src/Synth/PADnote.cpp b/src/Synth/PADnote.cpp
@@ -28,7 +28,8 @@ namespace zyn {
PADnote::PADnote(const PADnoteParameters *parameters,
SynthParams pars, const int& interpolation, WatchManager *wm,
const char *prefix)
- :SynthNote(pars), pars(*parameters), interpolation(interpolation)
+ :SynthNote(pars), pars(*parameters), interpolation(interpolation),
+ watchOut(wm, prefix, "noteout"), watchOut1(wm,prefix,"noteout1")
{
NoteGlobalPar.GlobalFilter = nullptr;
NoteGlobalPar.FilterEnvelope = nullptr;
@@ -354,7 +355,7 @@ int PADnote::Compute_Cubic(float *outl,
int PADnote::noteout(float *outl, float *outr)
-{
+{
computecurrentparameters();
float *smps = pars.sample[nsample].smp;
if(smps == NULL) {
@@ -377,6 +378,7 @@ int PADnote::noteout(float *outl, float *outr)
else
Compute_Linear(outl, outr, freqhi, freqlo);
+ watchOut1(outr,synth.buffersize);
if(firsttime) {
fadein(outl);
@@ -399,6 +401,7 @@ int PADnote::noteout(float *outl, float *outr)
break;
}
}
+
if(ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude, globalnewamplitude))
// Amplitude Interpolation
@@ -420,6 +423,8 @@ int PADnote::noteout(float *outl, float *outr)
// Apply legato-specific sound signal modifications
legato.apply(*this, outl, outr);
+ watchOut(outr,synth.buffersize);
+
// Check if the global amplitude is finished.
// If it does, disable the note
if(NoteGlobalPar.AmpEnvelope->finished()) {
diff --git a/src/Synth/PADnote.h b/src/Synth/PADnote.h
@@ -35,6 +35,8 @@ class PADnote:public SynthNote
bool finished() const;
void entomb(void);
+ VecWatchPoint watchOut,watchOut1;
+
void releasekey();
private:
void setup(float freq, float velocity, int portamento_,
diff --git a/src/Synth/SUBnote.cpp b/src/Synth/SUBnote.cpp
@@ -44,7 +44,8 @@ SUBnote::SUBnote(const SUBnoteParameters *parameters, SynthParams &spars, WatchM
GlobalFilter(nullptr),
GlobalFilterEnvelope(nullptr),
NoteEnabled(true),
- lfilter(nullptr), rfilter(nullptr)
+ lfilter(nullptr), rfilter(nullptr),
+ watchOut(wm, prefix, "noteout"), watchOut1(wm,prefix,"noteout1")
{
setup(spars.frequency, spars.velocity, spars.portamento, spars.note_log2_freq, false, wm, prefix);
}
@@ -518,6 +519,9 @@ void SUBnote::chanOutput(float *out, bpfilter *bp, int buffer_size)
for(int i = 0; i < synth.buffersize; ++i)
out[i] += tmpsmp[i] * rolloff;
+
+ if(n == 0)
+ watchOut(tmpsmp,buffer_size);
}
}
@@ -547,7 +551,7 @@ int SUBnote::noteout(float *outl, float *outr)
memcpy(outr, outl, synth.bufferbytes);
}
-
+ watchOut1(outl,synth.buffersize);
if(firsttick) {
int n = 10;
if(n > synth.buffersize)
diff --git a/src/Synth/SUBnote.h b/src/Synth/SUBnote.h
@@ -16,6 +16,7 @@
#include "SynthNote.h"
#include "../globals.h"
+#include "WatchPoint.h"
namespace zyn {
@@ -28,7 +29,7 @@ class SUBnote:public SynthNote
SynthNote *cloneLegato(void);
void legatonote(LegatoParams pars);
-
+ VecWatchPoint watchOut,watchOut1;
int noteout(float *outl, float *outr); //note output,return 0 if the note is finished
void releasekey();
bool finished() const;
@@ -50,7 +51,7 @@ class SUBnote:public SynthNote
void KillNote();
const SUBnoteParameters &pars;
-
+
//parameters
bool stereo;
int numstages; //number of stages of filters
diff --git a/src/Synth/WatchPoint.cpp b/src/Synth/WatchPoint.cpp
@@ -67,6 +67,9 @@ WatchManager::WatchManager(thrlnk *link)
memset(sample_list, 0, sizeof(sample_list));
memset(data_list, 0, sizeof(data_list));
memset(deactivate, 0, sizeof(deactivate));
+ memset(prebuffer, 0, sizeof(prebuffer));
+ memset(trigger, 0, sizeof(trigger));
+
}
void WatchManager::add_watch(const char *id)
@@ -82,13 +85,14 @@ void WatchManager::add_watch(const char *id)
fast_strcpy(active_list[i], id, MAX_WATCH_PATH);
new_active = true;
sample_list[i] = 0;
+ //printf("\n added watchpoint ID %s\n",id);
break;
}
}
}
void WatchManager::del_watch(const char *id)
-{
+{
//Queue up the delete
for(int i=0; i<MAX_WATCH; ++i)
if(!strcmp(active_list[i], id))
@@ -99,14 +103,17 @@ void WatchManager::tick(void)
{
//Try to send out any vector stuff
for(int i=0; i<MAX_WATCH; ++i) {
- if(sample_list[i]) {
+ int framesize = 2;
+ if(strstr(active_list[i], "noteout") != NULL)
+ framesize = MAX_SAMPLE-1;
+ if(sample_list[i] >= framesize-1) {
char arg_types[MAX_SAMPLE+1] = {0};
rtosc_arg_t arg_val[MAX_SAMPLE];
for(int j=0; j<sample_list[i]; ++j) {
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;
}
@@ -118,9 +125,14 @@ void WatchManager::tick(void)
//Clear deleted slots
for(int i=0; i<MAX_WATCH; ++i) {
if(deactivate[i]) {
- memset(active_list[i], 0, 128);
+ //printf("\ndelete id : %s\n",active_list[i]);
+ memset(active_list[i], 0, MAX_SAMPLE);
sample_list[i] = 0;
+ memset(data_list[i], 0, sizeof(float)*MAX_SAMPLE);
+ memset(prebuffer[i], 0, sizeof(float)*MAX_SAMPLE);
deactivate[i] = false;
+ trigger[i] = false;
+
}
}
@@ -138,6 +150,14 @@ bool WatchManager::active(const char *id) const
return false;
}
+bool WatchManager::trigger_active(const char *id) const
+{
+ for(int i=0; i<MAX_WATCH; ++i)
+ if(!strcmp(active_list[i], id))
+ return trigger[i];
+ return false;
+}
+
int WatchManager::samples(const char *id) const
{
for(int i=0; i<MAX_WATCH; ++i)
@@ -155,8 +175,8 @@ void WatchManager::satisfy(const char *id, float f)
}
void WatchManager::satisfy(const char *id, float *f, int n)
-{
- int selected = -1;
+{
+ int selected = -1;
for(int i=0; i<MAX_WATCH; ++i)
if(!strcmp(active_list[i], id))
selected = i;
@@ -164,9 +184,66 @@ void WatchManager::satisfy(const char *id, float *f, int n)
if(selected == -1)
return;
+ // printf("\npath : %s \n", id);
+
+ // if (!strcmp(id,"/part0/kit0/subpars/noteout"))
+ // 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];
+ }
+
+ if(space >= n)
+ space = n;
+
+ if(n == 2)
+ trigger[selected] = true;
+
//FIXME buffer overflow
- for(int i=0; i<n; ++i)
- data_list[selected][sample_list[selected]++] = f[i];
+ 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]){
+ data_list[selected][sample_list[selected]] = f[i];
+ sample_list[selected]++;
+ }
+ }
+
+ }
}
-
}
diff --git a/src/Synth/WatchPoint.h b/src/Synth/WatchPoint.h
@@ -39,15 +39,18 @@ struct WatchManager
thrlnk *write_back;
bool new_active;
char active_list[MAX_WATCH][MAX_WATCH_PATH];
- float data_list[MAX_SAMPLE][MAX_WATCH];
+ float data_list[MAX_WATCH][MAX_SAMPLE];
+ float prebuffer[MAX_WATCH][MAX_SAMPLE];
int sample_list[MAX_WATCH];
bool deactivate[MAX_WATCH];
+ bool trigger[MAX_WATCH];
//External API
WatchManager(thrlnk *link=0);
void add_watch(const char *);
void del_watch(const char *);
void tick(void);
+ bool trigger_active(const char *) const;
//Watch Point Query API
bool active(const char *) const;
diff --git a/src/Tests/AdNoteTest.h b/src/Tests/AdNoteTest.h
@@ -1,11 +1,9 @@
/*
ZynAddSubFX - a software synthesizer
-
AdNoteTest.h - CxxTest for Synth/ADnote
Copyright (C) 2009-2011 Mark McCurry
Copyright (C) 2009 Harald Hvaal
Authors: Mark McCurry, Harald Hvaal
-
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
@@ -25,6 +23,7 @@
#include "../Params/Presets.h"
#include "../DSP/FFTwrapper.h"
#include "../globals.h"
+#include <rtosc/thread-link.h>
using namespace std;
using namespace zyn;
@@ -35,6 +34,7 @@ SYNTH_T *synth;
class AdNoteTest:public CxxTest::TestSuite
{
public:
+ rtosc::ThreadLink *tr;
ADnote *note;
AbsTime *time;
FFTwrapper *fft;
@@ -42,7 +42,7 @@ class AdNoteTest:public CxxTest::TestSuite
Controller *controller;
Alloc memory;
unsigned char testnote;
-
+ WatchManager *w;
float *outR, *outL;
void setUp() {
@@ -59,6 +59,8 @@ class AdNoteTest:public CxxTest::TestSuite
for(int i = 0; i < synth->buffersize; ++i)
*(outR + i) = 0;
+ tr = new rtosc::ThreadLink(1024,3);
+ w = new WatchManager(tr);
fft = new FFTwrapper(synth->oscilsize);
//prepare the default settings
@@ -93,7 +95,7 @@ class AdNoteTest:public CxxTest::TestSuite
float freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f);
SynthParams pars{memory, *controller, *synth, *time, freq, 120, 0, testnote / 12.0f, false, prng()};
- note = new ADnote(defaultPreset, pars);
+ note = new ADnote(defaultPreset, pars,w);
}
@@ -123,27 +125,38 @@ class AdNoteTest:public CxxTest::TestSuite
#endif
sampleCount += synth->buffersize;
-
TS_ASSERT_DELTA(outL[255], 0.2555f, 0.0001f);
-
note->releasekey();
-
+ TS_ASSERT(!tr->hasNext());
+ w->add_watch("noteout");
note->noteout(outL, outR);
sampleCount += synth->buffersize;
TS_ASSERT_DELTA(outL[255], -0.4688f, 0.0001f);
-
+ w->tick();
+ TS_ASSERT(!tr->hasNext());
+
note->noteout(outL, outR);
sampleCount += synth->buffersize;
+ w->tick();
TS_ASSERT_DELTA(outL[255], 0.0613f, 0.0001f);
note->noteout(outL, outR);
sampleCount += synth->buffersize;
TS_ASSERT_DELTA(outL[255], 0.0971f, 0.0001f);
-
+ w->tick();
note->noteout(outL, outR);
sampleCount += synth->buffersize;
TS_ASSERT_DELTA(outL[255], -0.0901f, 0.0001f);
+ w->tick();
+
+ TS_ASSERT(tr->hasNext());
+ TS_ASSERT_EQUALS(string("noteout"), tr->read());
+ TS_ASSERT(!tr->hasNext());
+
+ note->noteout(outL, outR);
+ sampleCount += synth->buffersize;
+
while(!note->finished()) {
note->noteout(outL, outR);
diff --git a/src/Tests/CMakeLists.txt b/src/Tests/CMakeLists.txt
@@ -31,6 +31,8 @@ CXXTEST_ADD_TEST(KitTest KitTest.cpp
${CMAKE_CURRENT_SOURCE_DIR}/KitTest.h)
CXXTEST_ADD_TEST(MemoryStressTest MemoryStressTest.cpp
${CMAKE_CURRENT_SOURCE_DIR}/MemoryStressTest.h)
+CXXTEST_ADD_TEST(TriggerTest TriggerTest.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/TriggerTest.h)
#Extra libraries added to make test and full compilation use the same library
#links for quirky compilers
@@ -49,6 +51,7 @@ target_link_libraries(RandTest ${test_lib})
target_link_libraries(PADnoteTest ${test_lib})
target_link_libraries(MqTest ${test_lib})
target_link_libraries(WatchTest ${test_lib})
+target_link_libraries(TriggerTest ${test_lib})
target_link_libraries(PluginTest zynaddsubfx_core zynaddsubfx_nio
zynaddsubfx_gui_bridge
${GUI_LIBRARIES} ${NIO_LIBRARIES} ${AUDIO_LIBRARIES})
diff --git a/src/Tests/PadNoteTest.h b/src/Tests/PadNoteTest.h
@@ -29,6 +29,7 @@
#include "../Params/Presets.h"
#include "../DSP/FFTwrapper.h"
#include "../globals.h"
+#include <rtosc/thread-link.h>
using namespace std;
using namespace zyn;
@@ -50,6 +51,8 @@ class PadNoteTest:public CxxTest::TestSuite
unsigned char testnote;
Alloc memory;
int interpolation;
+ rtosc::ThreadLink *tr;
+ WatchManager *w;
float *outR, *outL;
@@ -68,6 +71,8 @@ class PadNoteTest:public CxxTest::TestSuite
for(int i = 0; i < synth->buffersize; ++i)
*(outR + i) = 0;
+ tr = new rtosc::ThreadLink(1024,3);
+ w = new WatchManager(tr);
fft = new FFTwrapper(synth->oscilsize);
//prepare the default settings
@@ -152,10 +157,13 @@ class PadNoteTest:public CxxTest::TestSuite
note->releasekey();
-
+ TS_ASSERT(!tr->hasNext());
+ w->add_watch("noteout");
note->noteout(outL, outR);
sampleCount += synth->buffersize;
TS_ASSERT_DELTA(outL[255], -0.0729f, 0.0005f);
+ w->tick();
+ TS_ASSERT(!tr->hasNext());
note->noteout(outL, outR);
sampleCount += synth->buffersize;
diff --git a/src/Tests/SubNoteTest.h b/src/Tests/SubNoteTest.h
@@ -25,6 +25,7 @@
#include "../Params/SUBnoteParameters.h"
#include "../Params/Presets.h"
#include "../globals.h"
+#include <rtosc/thread-link.h>
using namespace std;
using namespace zyn;
@@ -42,6 +43,8 @@ class SubNoteTest:public CxxTest::TestSuite
Controller *controller;
unsigned char testnote;
Alloc memory;
+ rtosc::ThreadLink *tr;
+ WatchManager *w;
float *outR, *outL;
@@ -59,6 +62,9 @@ class SubNoteTest:public CxxTest::TestSuite
for(int i = 0; i < synth->buffersize; ++i)
*(outR + i) = 0;
+ tr = new rtosc::ThreadLink(1024,3);
+ w = new WatchManager(tr);
+
//prepare the default settings
SUBnoteParameters *defaultPreset = new SUBnoteParameters(time);
XMLwrapper wrap;
@@ -79,7 +85,7 @@ class SubNoteTest:public CxxTest::TestSuite
float freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f);
SynthParams pars{memory, *controller, *synth, *time, freq, 120, 0, testnote / 12.0f, false, prng()};
- note = new SUBnote(defaultPreset, pars);
+ note = new SUBnote(defaultPreset, pars, w);
this->pars = defaultPreset;
}
@@ -116,22 +122,36 @@ class SubNoteTest:public CxxTest::TestSuite
note->releasekey();
-
+ TS_ASSERT(!tr->hasNext());
+ w->add_watch("noteout");
+
note->noteout(outL, outR);
sampleCount += synth->buffersize;
TS_ASSERT_DELTA(outL[255], 0.0029f, 0.0001f);
+ w->tick();
note->noteout(outL, outR);
sampleCount += synth->buffersize;
TS_ASSERT_DELTA(outL[255], -0.0011f, 0.0001f);
+ w->tick();
+ TS_ASSERT(tr->hasNext());
+ TS_ASSERT_EQUALS(string("noteout"), tr->read());
+ TS_ASSERT(!tr->hasNext());
+
+ w->add_watch("noteout1");
note->noteout(outL, outR);
sampleCount += synth->buffersize;
TS_ASSERT_DELTA(outL[255], -0.0017f, 0.0001f);
-
+ w->tick();
+
note->noteout(outL, outR);
sampleCount += synth->buffersize;
TS_ASSERT_DELTA(outL[255], -0.0005f, 0.0001f);
+ w->tick();
+ TS_ASSERT(tr->hasNext());
+ TS_ASSERT_EQUALS(string("noteout1"), tr->read());
+ TS_ASSERT(!tr->hasNext());
while(!note->finished()) {
note->noteout(outL, outR);
diff --git a/src/Tests/TriggerTest.h b/src/Tests/TriggerTest.h
@@ -0,0 +1,169 @@
+/*
+ ZynAddSubFX - a software synthesizer
+
+ AdNoteTest.h - CxxTest for Synth/SUBnote
+ Copyright (C) 2009-2011 Mark McCurry
+ Author: Mark McCurry
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+*/
+
+//Based Upon AdNoteTest.h
+#include <cxxtest/TestSuite.h>
+#include <iostream>
+#include <fstream>
+#include <ctime>
+#include <string>
+#include "../Misc/Master.h"
+#include "../Misc/Allocator.h"
+#include "../Misc/Util.h"
+#include "../Misc/XMLwrapper.h"
+#include "../Synth/SUBnote.h"
+#include "../Params/SUBnoteParameters.h"
+#include "../Params/Presets.h"
+#include "../globals.h"
+#include <rtosc/thread-link.h>
+
+using namespace std;
+using namespace zyn;
+
+SYNTH_T *synth;
+
+class TriggerTest:public CxxTest::TestSuite
+{
+ public:
+
+ SUBnoteParameters *pars;
+ SUBnote *note;
+ Master *master;
+ AbsTime *time;
+ Controller *controller;
+ unsigned char testnote;
+ Alloc memory;
+ rtosc::ThreadLink *tr;
+ WatchManager *w;
+
+
+ float *outR, *outL;
+
+ void setUp() {
+ synth = new SYNTH_T;
+ // //First the sensible settings and variables that have to be set:
+ 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;
+
+
+ time = new AbsTime(*synth);
+
+ tr = new rtosc::ThreadLink(1024,3);
+ w = new WatchManager(tr);
+
+ //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);
+
+ controller = new Controller(*synth, time);
+
+ //lets go with.... 50! as a nice note
+ testnote = 50;
+ float freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f);
+
+ SynthParams pars{memory, *controller, *synth, *time, freq, 120, 0, testnote / 12.0f, false, prng()};
+ note = new SUBnote(defaultPreset, pars, w);
+ this->pars = defaultPreset;
+ }
+
+ void tearDown() {
+ delete controller;
+ delete note;
+ delete [] outL;
+ delete [] outR;
+ delete time;
+ delete synth;
+ 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
+
+#ifdef WRITE_OUTPUT
+ ofstream file("subnoteout", ios::out);
+#endif
+ 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();
+ TS_ASSERT(!tr->hasNext());
+ w->add_watch("noteout");
+ w->add_watch("noteout1");
+ TS_ASSERT(!w->trigger_active("noteout"));
+ TS_ASSERT(!w->trigger_active("noteout1"));
+ note->noteout(outL, outR);
+ sampleCount += synth->buffersize;
+ note->noteout(outL, outR);
+ sampleCount += synth->buffersize;
+ TS_ASSERT(w->trigger_active("noteout1"));
+ TS_ASSERT(w->trigger_active("noteout"));
+ note->noteout(outL, outR);
+ sampleCount += synth->buffersize;
+ 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
+ }
+
+#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
+};
diff --git a/src/Tests/WatchTest.h b/src/Tests/WatchTest.h
@@ -30,6 +30,7 @@
#include "../Misc/Time.h"
#include "../Params/LFOParams.h"
#include "../Synth/LFO.h"
+#include "../Synth/SynthNote.h"
#include <unistd.h>
using namespace std;
using namespace zyn;
@@ -52,6 +53,7 @@ class WatchTest:public CxxTest::TestSuite
w = new WatchManager(tr);
par = new LFOParams;
l = new LFO(*par, 440.0, *at, w);
+
}
void tearDown() {
@@ -77,4 +79,5 @@ class WatchTest:public CxxTest::TestSuite
TS_ASSERT_EQUALS(string("out"), tr->read());
TS_ASSERT(!tr->hasNext());
}
+
};