From c52413aca485c22cb5be0e902068d74069cc9d4b Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 11 Dec 2015 12:05:12 +0100 Subject: [PATCH] Update zynaddsubfx --- source/native-plugins/zynaddsubfx-src.cpp | 2 + .../zynaddsubfx/Effects/DynamicFilter.cpp | 4 +- .../zynaddsubfx/Effects/DynamicFilter.h | 2 +- .../zynaddsubfx/Effects/EffectMgr.cpp | 6 +- .../zynaddsubfx/Effects/EffectMgr.h | 4 +- .../zynaddsubfx/Misc/Allocator.cpp | 31 +++++++- .../zynaddsubfx/Misc/Allocator.h | 44 ++++++++++- .../zynaddsubfx/Misc/Master.cpp | 8 +- .../native-plugins/zynaddsubfx/Misc/Master.h | 2 +- .../zynaddsubfx/Misc/MiddleWare.cpp | 8 +- .../native-plugins/zynaddsubfx/Misc/Part.cpp | 18 ++--- .../zynaddsubfx/Params/ADnoteParameters.cpp | 76 +++++++++++++------ .../zynaddsubfx/Params/ADnoteParameters.h | 20 ++++- .../zynaddsubfx/Params/Controller.cpp | 10 ++- .../zynaddsubfx/Params/Controller.h | 7 +- .../zynaddsubfx/Params/EnvelopeParams.cpp | 15 +++- .../zynaddsubfx/Params/EnvelopeParams.h | 6 +- .../zynaddsubfx/Params/FilterParams.cpp | 29 ++++++- .../zynaddsubfx/Params/FilterParams.h | 16 +++- .../zynaddsubfx/Params/LFOParams.cpp | 14 +++- .../zynaddsubfx/Params/LFOParams.h | 9 ++- .../zynaddsubfx/Params/PADnoteParameters.cpp | 30 +++++--- .../zynaddsubfx/Params/PADnoteParameters.h | 6 +- .../zynaddsubfx/Params/SUBnoteParameters.cpp | 27 +++++-- .../zynaddsubfx/Params/SUBnoteParameters.h | 6 +- .../zynaddsubfx/Synth/ADnote.cpp | 2 + .../native-plugins/zynaddsubfx/Synth/LFO.cpp | 1 + 27 files changed, 309 insertions(+), 94 deletions(-) diff --git a/source/native-plugins/zynaddsubfx-src.cpp b/source/native-plugins/zynaddsubfx-src.cpp index 9dd6da091..0f6e1b2fb 100644 --- a/source/native-plugins/zynaddsubfx-src.cpp +++ b/source/native-plugins/zynaddsubfx-src.cpp @@ -144,6 +144,8 @@ extern "C" { #include "zynaddsubfx/Synth/ADnote.cpp" #include "zynaddsubfx/Synth/Envelope.cpp" #include "zynaddsubfx/Synth/LFO.cpp" +#undef rChangeCb +#define rChangeCb #include "zynaddsubfx/Synth/OscilGen.cpp" #undef rObject #undef PC diff --git a/source/native-plugins/zynaddsubfx/Effects/DynamicFilter.cpp b/source/native-plugins/zynaddsubfx/Effects/DynamicFilter.cpp index 2afc87629..e9d48ebce 100644 --- a/source/native-plugins/zynaddsubfx/Effects/DynamicFilter.cpp +++ b/source/native-plugins/zynaddsubfx/Effects/DynamicFilter.cpp @@ -26,7 +26,7 @@ #include "../DSP/Filter.h" #include "../Misc/Allocator.h" -DynamicFilter::DynamicFilter(EffectParams pars) +DynamicFilter::DynamicFilter(EffectParams pars, const AbsTime *time) :Effect(pars), lfo(pars.srate, pars.bufsize), Pvolume(110), @@ -37,7 +37,7 @@ DynamicFilter::DynamicFilter(EffectParams pars) filterl(NULL), filterr(NULL) { - filterpars = memory.alloc(0,0,0); + filterpars = memory.alloc(0,0,0,time); setpreset(Ppreset); cleanup(); } diff --git a/source/native-plugins/zynaddsubfx/Effects/DynamicFilter.h b/source/native-plugins/zynaddsubfx/Effects/DynamicFilter.h index a52d187d9..094479342 100644 --- a/source/native-plugins/zynaddsubfx/Effects/DynamicFilter.h +++ b/source/native-plugins/zynaddsubfx/Effects/DynamicFilter.h @@ -30,7 +30,7 @@ class DynamicFilter:public Effect { public: - DynamicFilter(EffectParams pars); + DynamicFilter(EffectParams pars, const AbsTime *time = nullptr); ~DynamicFilter(); void out(const Stereo &smp); diff --git a/source/native-plugins/zynaddsubfx/Effects/EffectMgr.cpp b/source/native-plugins/zynaddsubfx/Effects/EffectMgr.cpp index 621a94a38..0ad8d259b 100644 --- a/source/native-plugins/zynaddsubfx/Effects/EffectMgr.cpp +++ b/source/native-plugins/zynaddsubfx/Effects/EffectMgr.cpp @@ -135,13 +135,15 @@ static const rtosc::Ports local_ports = { const rtosc::Ports &EffectMgr::ports = local_ports; -EffectMgr::EffectMgr(Allocator &alloc, const SYNTH_T &synth_, const bool insertion_) +EffectMgr::EffectMgr(Allocator &alloc, const SYNTH_T &synth_, + const bool insertion_, const AbsTime *time_) :insertion(insertion_), efxoutl(new float[synth_.buffersize]), efxoutr(new float[synth_.buffersize]), filterpars(NULL), nefx(0), efx(NULL), + time(time_), dryonly(false), memory(alloc), synth(synth_) @@ -203,7 +205,7 @@ void EffectMgr::changeeffectrt(int _nefx, bool avoidSmash) efx = memory.alloc(pars); break; case 8: - efx = memory.alloc(pars); + efx = memory.alloc(pars, time); break; //put more effect here default: diff --git a/source/native-plugins/zynaddsubfx/Effects/EffectMgr.h b/source/native-plugins/zynaddsubfx/Effects/EffectMgr.h index 02a150fd7..29497c856 100644 --- a/source/native-plugins/zynaddsubfx/Effects/EffectMgr.h +++ b/source/native-plugins/zynaddsubfx/Effects/EffectMgr.h @@ -36,7 +36,8 @@ class Allocator; class EffectMgr:public Presets { public: - EffectMgr(Allocator &alloc, const SYNTH_T &synth, const bool insertion_); + EffectMgr(Allocator &alloc, const SYNTH_T &synth, const bool insertion_, + const AbsTime *time_ = nullptr); ~EffectMgr(); void paste(EffectMgr &e); @@ -77,6 +78,7 @@ class EffectMgr:public Presets static const rtosc::Ports &ports; int nefx; Effect *efx; + const AbsTime *time; private: //Parameters Prior to initialization diff --git a/source/native-plugins/zynaddsubfx/Misc/Allocator.cpp b/source/native-plugins/zynaddsubfx/Misc/Allocator.cpp index facac669e..aab6960ec 100644 --- a/source/native-plugins/zynaddsubfx/Misc/Allocator.cpp +++ b/source/native-plugins/zynaddsubfx/Misc/Allocator.cpp @@ -33,7 +33,7 @@ struct AllocatorImpl unsigned long long totalAlloced = 0; }; -Allocator::Allocator(void) +Allocator::Allocator(void) : transaction_active() { impl = new AllocatorImpl; size_t default_size = 10*1024*1024; @@ -124,6 +124,19 @@ typedef struct block_header_t static const size_t block_header_free_bit = 1 << 0; #endif +void Allocator::beginTransaction() { + // TODO: log about unsupported nested transaction when a RT compliant + // logging is available and transaction_active == true + transaction_active = true; + transaction_alloc_index = 0; +} + +void Allocator::endTransaction() { + // TODO: log about invalid end of transaction when a RT copmliant logging + // is available and transaction_active == false + transaction_active = false; +} + bool Allocator::memFree(void *pool) const { size_t bh_shift = sizeof(next_t)+sizeof(size_t); @@ -174,6 +187,22 @@ unsigned long long Allocator::totalAlloced() const return impl->totalAlloced; } +void Allocator::rollbackTransaction() { + + // if a transaction is active + if (transaction_active) { + + // deallocate all allocated memory within this transaction + for (size_t temp_idx = 0; + temp_idx < transaction_alloc_index; ++temp_idx) { + dealloc_mem(transaction_alloc_content[temp_idx]); + } + + } + + transaction_active = false; +} + /* * Notes on tlsf internals * - TLSF consists of blocks linked by block headers and these form a doubly diff --git a/source/native-plugins/zynaddsubfx/Misc/Allocator.h b/source/native-plugins/zynaddsubfx/Misc/Allocator.h index 140b7780f..9d1e6c29e 100644 --- a/source/native-plugins/zynaddsubfx/Misc/Allocator.h +++ b/source/native-plugins/zynaddsubfx/Misc/Allocator.h @@ -16,7 +16,8 @@ class Allocator virtual void dealloc_mem(void *memory) = 0; /** - * High level allocator method, which return a pointer to a class or struct + * High level allocator method, which return a pointer to a class + * or struct * allocated with the specialized subclass strategy * @param ts argument(s) for the constructor of the type T * @return a non null pointer to a new object of type T @@ -26,13 +27,17 @@ class Allocator T *alloc(Ts&&... ts) { void *data = alloc_mem(sizeof(T)); - if(!data) + if(!data) { + rollbackTransaction(); throw std::bad_alloc(); + } + append_alloc_to_memory_transaction(data); return new (data) T(std::forward(ts)...); } /** - * High level allocator method, which return a pointer to an array of class or struct + * High level allocator method, which return a pointer to an array of + * class or struct * allocated with the specialized subclass strategy * @param len the array length * @param ts argument(s) for the constructor of the type T @@ -43,8 +48,11 @@ class Allocator T *valloc(size_t len, Ts&&... ts) { T *data = (T*)alloc_mem(len*sizeof(T)); - if(!data) + if(!data) { + rollbackTransaction(); throw std::bad_alloc(); + } + append_alloc_to_memory_transaction(data); for(unsigned i=0; i(ts)...); @@ -83,6 +91,9 @@ class Allocator } } + void beginTransaction(); + void endTransaction(); + virtual void addMemory(void *, size_t mem_size) = 0; //Return true if the current pool cannot allocate n chunks of chunk_size @@ -97,6 +108,31 @@ class Allocator unsigned long long totalAlloced() const; struct AllocatorImpl *impl; + +private: + const static size_t max_transaction_length = 256; + + void* transaction_alloc_content[max_transaction_length]; + size_t transaction_alloc_index; + bool transaction_active; + + void rollbackTransaction(); + + /** + * Append memory block to the list of memory blocks allocated during this + * transaction + * @param new_memory pointer to the memory pointer to freshly allocated + */ + void append_alloc_to_memory_transaction(void *new_memory) { + if (transaction_active) { + if (transaction_alloc_index < max_transaction_length) { + transaction_alloc_content[transaction_alloc_index++] = new_memory; + } + // TODO add log about transaction too long and memory transaction + // safety net being disabled + } + } + }; //! the allocator for normal use diff --git a/source/native-plugins/zynaddsubfx/Misc/Master.cpp b/source/native-plugins/zynaddsubfx/Misc/Master.cpp index f64df62b7..40f328ff0 100644 --- a/source/native-plugins/zynaddsubfx/Misc/Master.cpp +++ b/source/native-plugins/zynaddsubfx/Misc/Master.cpp @@ -301,10 +301,10 @@ vuData::vuData(void) {} Master::Master(const SYNTH_T &synth_, Config* config) - :HDDRecorder(synth_), ctl(synth_), + :HDDRecorder(synth_), time(synth_), ctl(synth_, &time), microtonal(config->cfg.GzipCompression), bank(config), frozenState(false), pendingMemory(false), - synth(synth_), time(synth), gzip_compression(config->cfg.GzipCompression) + synth(synth_), gzip_compression(config->cfg.GzipCompression) { bToU = NULL; uToB = NULL; @@ -335,11 +335,11 @@ Master::Master(const SYNTH_T &synth_, Config* config) //Insertion Effects init for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx) - insefx[nefx] = new EffectMgr(*memory, synth, 1); + insefx[nefx] = new EffectMgr(*memory, synth, 1, &time); //System Effects init for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) - sysefx[nefx] = new EffectMgr(*memory, synth, 0); + sysefx[nefx] = new EffectMgr(*memory, synth, 0, &time); defaults(); diff --git a/source/native-plugins/zynaddsubfx/Misc/Master.h b/source/native-plugins/zynaddsubfx/Misc/Master.h index 4d60dc28b..4fb5f6264 100644 --- a/source/native-plugins/zynaddsubfx/Misc/Master.h +++ b/source/native-plugins/zynaddsubfx/Misc/Master.h @@ -149,6 +149,7 @@ class Master float vuoutpeakpart[NUM_MIDI_PARTS]; unsigned char fakepeakpart[NUM_MIDI_PARTS]; //this is used to compute the "peak" when the part is disabled + AbsTime time; Controller ctl; bool swaplr; //if L and R are swapped @@ -174,7 +175,6 @@ class Master rtosc::ThreadLink *uToB; bool pendingMemory; const SYNTH_T &synth; - AbsTime time; const int& gzip_compression; //!< value from config private: float sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; diff --git a/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp b/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp index d70e5b485..85318dc41 100644 --- a/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp +++ b/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp @@ -1338,15 +1338,17 @@ void MiddleWareImpl::kitEnable(int part, int kit, int type) string url = "/part"+to_s(part)+"/kit"+to_s(kit)+"/"; void *ptr = NULL; if(type == 0 && kits.add[part][kit] == NULL) { - ptr = kits.add[part][kit] = new ADnoteParameters(synth, master->fft); + ptr = kits.add[part][kit] = new ADnoteParameters(synth, master->fft, + &master->time); url += "adpars-data"; obj_store.extractAD(kits.add[part][kit], part, kit); } else if(type == 1 && kits.pad[part][kit] == NULL) { - ptr = kits.pad[part][kit] = new PADnoteParameters(synth, master->fft); + ptr = kits.pad[part][kit] = new PADnoteParameters(synth, master->fft, + &master->time); url += "padpars-data"; obj_store.extractPAD(kits.pad[part][kit], part, kit); } else if(type == 2 && kits.sub[part][kit] == NULL) { - ptr = kits.sub[part][kit] = new SUBnoteParameters(); + ptr = kits.sub[part][kit] = new SUBnoteParameters(&master->time); url += "subpars-data"; } diff --git a/source/native-plugins/zynaddsubfx/Misc/Part.cpp b/source/native-plugins/zynaddsubfx/Misc/Part.cpp index 0f2915807..04080544e 100644 --- a/source/native-plugins/zynaddsubfx/Misc/Part.cpp +++ b/source/native-plugins/zynaddsubfx/Misc/Part.cpp @@ -210,7 +210,7 @@ Part::Part(Allocator &alloc, const SYNTH_T &synth_, const AbsTime &time_, Plegatomode(false), partoutl(new float[synth_.buffersize]), partoutr(new float[synth_.buffersize]), - ctl(synth_), + ctl(synth_, &time_), microtonal(microtonal_), fft(fft_), memory(alloc), @@ -229,11 +229,11 @@ Part::Part(Allocator &alloc, const SYNTH_T &synth_, const AbsTime &time_, kit[n].padpars = nullptr; } - kit[0].adpars = new ADnoteParameters(synth, fft); + kit[0].adpars = new ADnoteParameters(synth, fft, &time); //Part's Insertion Effects init for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) { - partefx[nefx] = new EffectMgr(memory, synth, 1); + partefx[nefx] = new EffectMgr(memory, synth, 1, &time); Pefxbypass[nefx] = false; } assert(partefx[0]); @@ -847,9 +847,9 @@ void Part::setkititemstatus(unsigned kititem, bool Penabled_) else { //All parameters must be NULL in this case assert(!(kkit.adpars || kkit.subpars || kkit.padpars)); - kkit.adpars = new ADnoteParameters(synth, fft); - kkit.subpars = new SUBnoteParameters(); - kkit.padpars = new PADnoteParameters(synth, fft); + kkit.adpars = new ADnoteParameters(synth, fft, &time); + kkit.subpars = new SUBnoteParameters(&time); + kkit.padpars = new PADnoteParameters(synth, fft, &time); } } @@ -1082,7 +1082,7 @@ void Part::getfromXMLinstrument(XMLwrapper& xml) kit[i].Padenabled); if(xml.enterbranch("ADD_SYNTH_PARAMETERS")) { if(!kit[i].adpars) - kit[i].adpars = new ADnoteParameters(synth, fft); + kit[i].adpars = new ADnoteParameters(synth, fft, &time); kit[i].adpars->getfromXML(xml); xml.exitbranch(); } @@ -1091,7 +1091,7 @@ void Part::getfromXMLinstrument(XMLwrapper& xml) kit[i].Psubenabled); if(xml.enterbranch("SUB_SYNTH_PARAMETERS")) { if(!kit[i].subpars) - kit[i].subpars = new SUBnoteParameters(); + kit[i].subpars = new SUBnoteParameters(&time); kit[i].subpars->getfromXML(xml); xml.exitbranch(); } @@ -1100,7 +1100,7 @@ void Part::getfromXMLinstrument(XMLwrapper& xml) kit[i].Ppadenabled); if(xml.enterbranch("PAD_SYNTH_PARAMETERS")) { if(!kit[i].padpars) - kit[i].padpars = new PADnoteParameters(synth, fft); + kit[i].padpars = new PADnoteParameters(synth, fft, &time); kit[i].padpars->getfromXML(xml); xml.exitbranch(); } diff --git a/source/native-plugins/zynaddsubfx/Params/ADnoteParameters.cpp b/source/native-plugins/zynaddsubfx/Params/ADnoteParameters.cpp index e2b8a1ea9..2457b5d8d 100644 --- a/source/native-plugins/zynaddsubfx/Params/ADnoteParameters.cpp +++ b/source/native-plugins/zynaddsubfx/Params/ADnoteParameters.cpp @@ -41,6 +41,8 @@ using rtosc::RtData; #define EXPAND(x) x #define rObject ADnoteVoiceParam +#undef rChangeCb +#define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); } static const Ports voicePorts = { //Send Messages To Oscillator Realtime Table {"OscilSmp/", rDoc("Primary Oscillator"), @@ -221,10 +223,12 @@ static const Ports voicePorts = { d.reply(d.loc, "f", obj->getUnisonFrequencySpreadCents()); }}, }; +#undef rChangeCb #undef rObject #define rObject ADnoteGlobalParam +#define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); } static const Ports globalPorts = { rRecurp(Reson, "Resonance"), rRecurp(FreqLfo, "Frequency LFO"), @@ -298,9 +302,12 @@ static const Ports globalPorts = { }}, }; +#undef rChangeCb #undef rObject #define rObject ADnoteParameters + +#define rChangeCb obj->last_update_timestamp = obj->time.time(); static const Ports adPorts = {//XXX 16 should not be hard coded rSelf(ADnoteParameters), rPaste, @@ -308,13 +315,14 @@ static const Ports adPorts = {//XXX 16 should not be hard coded rRecurs(VoicePar, NUM_VOICES), rRecur(GlobalPar, "Adnote Parameters"), }; - +#undef rChangeCb const Ports &ADnoteParameters::ports = adPorts; const Ports &ADnoteVoiceParam::ports = voicePorts; const Ports &ADnoteGlobalParam::ports = globalPorts; -ADnoteParameters::ADnoteParameters(const SYNTH_T &synth, FFTwrapper *fft_) - :PresetsArray() +ADnoteParameters::ADnoteParameters(const SYNTH_T &synth, FFTwrapper *fft_, + const AbsTime *time_) + :PresetsArray(), GlobalPar(time_), time(time_), last_update_timestamp(0) { setpresettype("Padsynth"); fft = fft_; @@ -322,26 +330,28 @@ ADnoteParameters::ADnoteParameters(const SYNTH_T &synth, FFTwrapper *fft_) for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) { VoicePar[nvoice].GlobalPDetuneType = &GlobalPar.PDetuneType; - EnableVoice(synth, nvoice); + VoicePar[nvoice].time = time_; + EnableVoice(synth, nvoice, time_); } defaults(); } -ADnoteGlobalParam::ADnoteGlobalParam() +ADnoteGlobalParam::ADnoteGlobalParam(const AbsTime *time_) : + time(time_), last_update_timestamp(0) { - FreqEnvelope = new EnvelopeParams(0, 0); + FreqEnvelope = new EnvelopeParams(0, 0, time_); FreqEnvelope->ASRinit(64, 50, 64, 60); - FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0); + FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0, time_); - AmpEnvelope = new EnvelopeParams(64, 1); + AmpEnvelope = new EnvelopeParams(64, 1, time_); AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); - AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1); + AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1, time_); - GlobalFilter = new FilterParams(2, 94, 40); - FilterEnvelope = new EnvelopeParams(0, 1); + GlobalFilter = new FilterParams(2, 94, 40, time_); + FilterEnvelope = new EnvelopeParams(0, 1, time_); FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); - FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2); + FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2, time_); Reson = new Resonance(); } @@ -474,32 +484,34 @@ void ADnoteVoiceParam::defaults() /* * Init the voice parameters */ -void ADnoteParameters::EnableVoice(const SYNTH_T &synth, int nvoice) +void ADnoteParameters::EnableVoice(const SYNTH_T &synth, int nvoice, + const AbsTime *time) { - VoicePar[nvoice].enable(synth, fft, GlobalPar.Reson); + VoicePar[nvoice].enable(synth, fft, GlobalPar.Reson, time); } -void ADnoteVoiceParam::enable(const SYNTH_T &synth, FFTwrapper *fft, Resonance *Reson) +void ADnoteVoiceParam::enable(const SYNTH_T &synth, FFTwrapper *fft, + Resonance *Reson, const AbsTime *time) { OscilSmp = new OscilGen(synth, fft, Reson); FMSmp = new OscilGen(synth, fft, NULL); - AmpEnvelope = new EnvelopeParams(64, 1); + AmpEnvelope = new EnvelopeParams(64, 1, time); AmpEnvelope->ADSRinit_dB(0, 100, 127, 100); - AmpLfo = new LFOParams(90, 32, 64, 0, 0, 30, 0, 1); + AmpLfo = new LFOParams(90, 32, 64, 0, 0, 30, 0, 1, time); - FreqEnvelope = new EnvelopeParams(0, 0); + FreqEnvelope = new EnvelopeParams(0, 0, time); FreqEnvelope->ASRinit(30, 40, 64, 60); - FreqLfo = new LFOParams(50, 40, 0, 0, 0, 0, 0, 0); + FreqLfo = new LFOParams(50, 40, 0, 0, 0, 0, 0, 0, time); - VoiceFilter = new FilterParams(2, 50, 60); - FilterEnvelope = new EnvelopeParams(0, 0); + VoiceFilter = new FilterParams(2, 50, 60, time); + FilterEnvelope = new EnvelopeParams(0, 0, time); FilterEnvelope->ADSRinit_filter(90, 70, 40, 70, 10, 40); - FilterLfo = new LFOParams(50, 20, 64, 0, 0, 0, 0, 2); + FilterLfo = new LFOParams(50, 20, 64, 0, 0, 0, 0, 2, time); - FMFreqEnvelope = new EnvelopeParams(0, 0); + FMFreqEnvelope = new EnvelopeParams(0, 0, time); FMFreqEnvelope->ASRinit(20, 90, 40, 80); - FMAmpEnvelope = new EnvelopeParams(64, 1); + FMAmpEnvelope = new EnvelopeParams(64, 1, time); FMAmpEnvelope->ADSRinit(80, 90, 127, 100); } @@ -919,6 +931,10 @@ void ADnoteParameters::paste(ADnoteParameters &a) this->GlobalPar.paste(a.GlobalPar); for(int i=0; iVoicePar[i].paste(a.VoicePar[i]); + + if ( time ) { + last_update_timestamp = time->time(); + } } void ADnoteParameters::pasteArray(ADnoteParameters &a, int nvoice) @@ -927,6 +943,10 @@ void ADnoteParameters::pasteArray(ADnoteParameters &a, int nvoice) return; VoicePar[nvoice].paste(a.VoicePar[nvoice]); + + if ( time ) { + last_update_timestamp = time->time(); + } } #define copy(x) this->x = a.x @@ -1015,6 +1035,10 @@ void ADnoteVoiceParam::paste(ADnoteVoiceParam &a) RCopy(FMFreqEnvelope); RCopy(FMSmp); + + if ( time ) { + last_update_timestamp = time->time(); + } } void ADnoteGlobalParam::paste(ADnoteGlobalParam &a) @@ -1050,6 +1074,10 @@ void ADnoteGlobalParam::paste(ADnoteGlobalParam &a) RCopy(FilterEnvelope); RCopy(FilterLfo); RCopy(Reson); + + if ( time ) { + last_update_timestamp = time->time(); + } } #undef copy #undef RCopy diff --git a/source/native-plugins/zynaddsubfx/Params/ADnoteParameters.h b/source/native-plugins/zynaddsubfx/Params/ADnoteParameters.h index a9015c617..3ddca66f3 100644 --- a/source/native-plugins/zynaddsubfx/Params/ADnoteParameters.h +++ b/source/native-plugins/zynaddsubfx/Params/ADnoteParameters.h @@ -35,7 +35,7 @@ enum FMTYPE { /*****************************************************************/ struct ADnoteGlobalParam { - ADnoteGlobalParam(); + ADnoteGlobalParam(const AbsTime* time_ = nullptr); ~ADnoteGlobalParam(); void defaults(); void add2XML(XMLwrapper& xml); @@ -106,6 +106,9 @@ struct ADnoteGlobalParam { //how the randomness is applied to the harmonics on more voices using the same oscillator unsigned char Hrandgrouping; + const AbsTime *time; + int64_t last_update_timestamp; + static const rtosc::Ports &ports; }; @@ -115,11 +118,13 @@ struct ADnoteGlobalParam { /* VOICE PARAMETERS */ /***********************************************************/ struct ADnoteVoiceParam { + ADnoteVoiceParam() : time(nullptr), last_update_timestamp(0) { }; void getfromXML(XMLwrapper& xml, unsigned nvoice); void add2XML(XMLwrapper& xml, bool fmoscilused); void paste(ADnoteVoiceParam &p); void defaults(void); - void enable(const SYNTH_T &synth, FFTwrapper *fft, Resonance *Reson); + void enable(const SYNTH_T &synth, FFTwrapper *fft, Resonance *Reson, + const AbsTime *time); void kill(void); float getUnisonFrequencySpreadCents(void) const; /** If the voice is enabled */ @@ -302,13 +307,17 @@ struct ADnoteVoiceParam { unsigned char *GlobalPDetuneType; + const AbsTime *time; + int64_t last_update_timestamp; + static const rtosc::Ports &ports; }; class ADnoteParameters:public PresetsArray { public: - ADnoteParameters(const SYNTH_T &synth, FFTwrapper *fft_); + ADnoteParameters(const SYNTH_T &synth, FFTwrapper *fft_, + const AbsTime *time_ = nullptr); ~ADnoteParameters(); ADnoteGlobalParam GlobalPar; @@ -330,9 +339,12 @@ class ADnoteParameters:public PresetsArray void getfromXMLsection(XMLwrapper& xml, int n); private: - void EnableVoice(const SYNTH_T &synth, int nvoice); + void EnableVoice(const SYNTH_T &synth, int nvoice, const AbsTime* time); void KillVoice(int nvoice); FFTwrapper *fft; + + const AbsTime *time; + int64_t last_update_timestamp; }; #endif diff --git a/source/native-plugins/zynaddsubfx/Params/Controller.cpp b/source/native-plugins/zynaddsubfx/Params/Controller.cpp index 2a608ce87..0716bf18b 100644 --- a/source/native-plugins/zynaddsubfx/Params/Controller.cpp +++ b/source/native-plugins/zynaddsubfx/Params/Controller.cpp @@ -22,6 +22,7 @@ #include "Controller.h" #include "../Misc/Util.h" +#include "../Misc/Time.h" #include "../Misc/XMLwrapper.h" #include #include @@ -31,6 +32,9 @@ using namespace rtosc; #define rObject Controller + +#undef rChangeCb +#define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); } const rtosc::Ports Controller::ports = { rParamZyn(panning.depth, "Depth of Panning MIDI Control"), rParamZyn(filtercutoff.depth, "Depth of Filter Cutoff MIDI Control"), @@ -60,10 +64,10 @@ const rtosc::Ports Controller::ports = { rToggle(NRPN.receive, "NRPN MIDI Enable"), rAction(defaults), }; +#undef rChangeCb - -Controller::Controller(const SYNTH_T &synth_) - :synth(synth_) +Controller::Controller(const SYNTH_T &synth_, const AbsTime *time_) + :time(time_), last_update_timestamp(0), synth(synth_) { defaults(); resetall(); diff --git a/source/native-plugins/zynaddsubfx/Params/Controller.h b/source/native-plugins/zynaddsubfx/Params/Controller.h index 0e7a8fbf6..51fa20abb 100644 --- a/source/native-plugins/zynaddsubfx/Params/Controller.h +++ b/source/native-plugins/zynaddsubfx/Params/Controller.h @@ -24,13 +24,14 @@ #ifndef CONTROLLER_H #define CONTROLLER_H +#include #include "../globals.h" /**(Midi) Controllers implementation*/ class Controller { public: - Controller(const SYNTH_T &synth); + Controller(const SYNTH_T &synth, const AbsTime *time = nullptr); Controller&operator=(const Controller &c); ~Controller(); void resetall(); @@ -215,6 +216,10 @@ class Controller unsigned char receive; //this is saved to disk by Master } NRPN; + + const AbsTime *time; + int64_t last_update_timestamp; + static const rtosc::Ports ports; private: const SYNTH_T &synth; diff --git a/source/native-plugins/zynaddsubfx/Params/EnvelopeParams.cpp b/source/native-plugins/zynaddsubfx/Params/EnvelopeParams.cpp index dd06b55dd..cfd1164df 100644 --- a/source/native-plugins/zynaddsubfx/Params/EnvelopeParams.cpp +++ b/source/native-plugins/zynaddsubfx/Params/EnvelopeParams.cpp @@ -28,6 +28,7 @@ #include "EnvelopeParams.h" #include "../Misc/Util.h" +#include "../Misc/Time.h" #define rObject EnvelopeParams using namespace rtosc; @@ -36,10 +37,11 @@ static const rtosc::Ports localPorts = { rSelf(EnvelopeParams), rPaste, #undef rChangeCb -#define rChangeCb if(!obj->Pfreemode) obj->converttofree(); +#define rChangeCb if(!obj->Pfreemode) obj->converttofree(); if (obj->time) { \ + obj->last_update_timestamp = obj->time->time(); } rToggle(Pfreemode, "Complex Envelope Definitions"), #undef rChangeCb -#define rChangeCb +#define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); } rParamZyn(Penvpoints, rProp(internal), "Number of points in complex definition"), rParamZyn(Penvsustain, rProp(internal), "Location of the sustain point"), rParams(Penvdt, MAX_ENVELOPE_POINTS, "Envelope Delay Times"), @@ -94,11 +96,14 @@ static const rtosc::Ports localPorts = { }}, }; +#undef rChangeCb const rtosc::Ports &EnvelopeParams::ports = localPorts; EnvelopeParams::EnvelopeParams(unsigned char Penvstretch_, - unsigned char Pforcedrelease_) + unsigned char Pforcedrelease_, + const AbsTime *time_): + time(time_), last_update_timestamp(0) { PA_dt = 10; PD_dt = 10; @@ -149,6 +154,10 @@ void EnvelopeParams::paste(const EnvelopeParams &ep) COPY(PD_val); COPY(PS_val); COPY(PR_val); + + if ( time ) { + last_update_timestamp = time->time(); + } } #undef COPY diff --git a/source/native-plugins/zynaddsubfx/Params/EnvelopeParams.h b/source/native-plugins/zynaddsubfx/Params/EnvelopeParams.h index 7fbb1748c..e6497c343 100644 --- a/source/native-plugins/zynaddsubfx/Params/EnvelopeParams.h +++ b/source/native-plugins/zynaddsubfx/Params/EnvelopeParams.h @@ -31,7 +31,8 @@ class EnvelopeParams:public Presets { public: EnvelopeParams(unsigned char Penvstretch_=64, - unsigned char Pforcedrelease_=0); + unsigned char Pforcedrelease_=0, + const AbsTime *time_ = nullptr); ~EnvelopeParams(); void paste(const EnvelopeParams &ep); void ADSRinit(char A_dt, char D_dt, char S_val, char R_dt); @@ -74,6 +75,9 @@ class EnvelopeParams:public Presets // 4 for ADSR_filter parameters (filter parameters) // 5 for ASR_bw parameters (bandwidth parameters) + const AbsTime *time; + int64_t last_update_timestamp; + static const rtosc::Ports &ports; private: void store2defaults(); diff --git a/source/native-plugins/zynaddsubfx/Params/FilterParams.cpp b/source/native-plugins/zynaddsubfx/Params/FilterParams.cpp index 9c5aa7fb1..c457cecc5 100644 --- a/source/native-plugins/zynaddsubfx/Params/FilterParams.cpp +++ b/source/native-plugins/zynaddsubfx/Params/FilterParams.cpp @@ -22,6 +22,7 @@ #include "FilterParams.h" #include "../Misc/Util.h" +#include "../Misc/Time.h" #include #include #include @@ -36,11 +37,15 @@ using namespace rtosc; constexpr int sizeof_pvowels = sizeof(FilterParams::Pvowels); #define rObject FilterParams::Pvowels_t::formants_t + +#undef rChangeCb +#define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); } static const rtosc::Ports subsubports = { rParamZyn(freq, "Formant frequency"), rParamZyn(amp, "Strength of formant"), rParamZyn(q, "Quality Factor"), }; +#undef rChangeCb #undef rObject static const rtosc::Ports subports = { @@ -54,12 +59,14 @@ static const rtosc::Ports subports = { FilterParams::Pvowels_t *obj = (FilterParams::Pvowels_t *) d.obj; d.obj = (void*) &obj->formants[idx]; subsubports.dispatch(msg, d); + if (obj->time) { obj->last_update_timestamp = obj->time->time(); } }}, }; #define rObject FilterParams #undef rChangeCb -#define rChangeCb obj->changed = true; +#define rChangeCb obj->changed = true; if ( obj->time) { \ + obj->last_update_timestamp = obj->time->time(); } const rtosc::Ports FilterParams::ports = { rSelf(FilterParams), rPaste, @@ -127,13 +134,15 @@ const rtosc::Ports FilterParams::ports = { -FilterParams::FilterParams() - :FilterParams(0,64,64) +FilterParams::FilterParams(const AbsTime *time_) + :FilterParams(0,64,64, time_) { } FilterParams::FilterParams(unsigned char Ptype_, unsigned char Pfreq_, - unsigned char Pq_) + unsigned char Pq_, + const AbsTime *time_): + time(time_), last_update_timestamp(0) { setpresettype("Pfilter"); Dtype = Ptype_; @@ -179,10 +188,14 @@ void FilterParams::defaults() void FilterParams::defaults(int n) { int j = n; + + Pvowels[j].time = time; + for(int i = 0; i < FF_MAX_FORMANTS; ++i) { Pvowels[j].formants[i].freq = (int)(RND * 127.0f); //some random freqs Pvowels[j].formants[i].q = 64; Pvowels[j].formants[i].amp = 127; + Pvowels[j].formants[i].time = time; } } @@ -455,6 +468,10 @@ void FilterParams::paste(FilterParams &x) this->Psequence[i] = x.Psequence[i]; COPY(changed); + + if ( time ) { + last_update_timestamp = time->time(); + } } #undef COPY @@ -468,4 +485,8 @@ void FilterParams::pasteArray(FilterParams &x, int nvowel) self.amp = update.amp; self.q = update.q; } + + if ( time ) { + last_update_timestamp = time->time(); + } } diff --git a/source/native-plugins/zynaddsubfx/Params/FilterParams.h b/source/native-plugins/zynaddsubfx/Params/FilterParams.h index 2fdbe889f..f8b5b54c9 100644 --- a/source/native-plugins/zynaddsubfx/Params/FilterParams.h +++ b/source/native-plugins/zynaddsubfx/Params/FilterParams.h @@ -30,10 +30,11 @@ class FilterParams:public PresetsArray { public: - FilterParams(); + FilterParams(const AbsTime *time_ = nullptr); FilterParams(unsigned char Ptype_, unsigned char Pfreq, - unsigned char Pq_); + unsigned char Pq_, + const AbsTime *time_ = nullptr); ~FilterParams(); void add2XML(XMLwrapper& xml); @@ -67,9 +68,17 @@ class FilterParams:public PresetsArray unsigned char Pcenterfreq, Poctavesfreq; //the center frequency of the res. func., and the number of octaves struct Pvowels_t { + Pvowels_t() : last_update_timestamp(0) {} struct formants_t { + formants_t() : last_update_timestamp(0) {} unsigned char freq, amp, q; //frequency,amplitude,Q + + const AbsTime *time; + int64_t last_update_timestamp; } formants[FF_MAX_FORMANTS]; + + const AbsTime *time; + int64_t last_update_timestamp; } Pvowels[FF_MAX_VOWELS]; @@ -94,6 +103,9 @@ class FilterParams:public PresetsArray bool changed; + const AbsTime *time; + int64_t last_update_timestamp; + static const rtosc::Ports ports; private: diff --git a/source/native-plugins/zynaddsubfx/Params/LFOParams.cpp b/source/native-plugins/zynaddsubfx/Params/LFOParams.cpp index 225a1d0a0..befe79b75 100644 --- a/source/native-plugins/zynaddsubfx/Params/LFOParams.cpp +++ b/source/native-plugins/zynaddsubfx/Params/LFOParams.cpp @@ -33,6 +33,8 @@ using namespace rtosc; #define rObject LFOParams +#undef rChangeCb +#define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); } static const rtosc::Ports _ports = { rSelf(LFOParams), rPaste, @@ -50,10 +52,11 @@ static const rtosc::Ports _ports = { rToggle(Pcontinous, "Enable for global operation"), rParamZyn(Pstretch, rCentered, "Note frequency stretch"), }; +#undef rChangeCb const rtosc::Ports &LFOParams::ports = _ports; -LFOParams::LFOParams() +LFOParams::LFOParams(const AbsTime *time_) : time(time_) { Dfreq = 64; Dintensity = 0; @@ -74,8 +77,9 @@ LFOParams::LFOParams(char Pfreq_, char Prandomness_, char Pdelay_, char Pcontinous_, - char fel_) -{ + char fel_, + const AbsTime *time_) : time(time_), + last_update_timestamp(0) { switch(fel_) { case 0: setpresettype("Plfofrequency"); @@ -154,5 +158,9 @@ void LFOParams::paste(LFOParams &x) COPY(Pdelay); COPY(Pcontinous); COPY(Pstretch); + + if ( time ) { + last_update_timestamp = time->time(); + } } #undef COPY diff --git a/source/native-plugins/zynaddsubfx/Params/LFOParams.h b/source/native-plugins/zynaddsubfx/Params/LFOParams.h index 3dd4f5798..5bb120e98 100644 --- a/source/native-plugins/zynaddsubfx/Params/LFOParams.h +++ b/source/native-plugins/zynaddsubfx/Params/LFOParams.h @@ -23,6 +23,7 @@ #ifndef LFO_PARAMS_H #define LFO_PARAMS_H +#include #include #include "Presets.h" @@ -40,7 +41,7 @@ class XMLwrapper; class LFOParams:public Presets { public: - LFOParams(); + LFOParams(const AbsTime* time_ = nullptr); LFOParams(char Pfreq_, char Pintensity_, char Pstartphase_, @@ -48,7 +49,8 @@ class LFOParams:public Presets char Prandomness_, char Pdelay_, char Pcontinous, - char fel_); + char fel_, + const AbsTime* time_ = nullptr); ~LFOParams(); void add2XML(XMLwrapper& xml); @@ -70,6 +72,9 @@ class LFOParams:public Presets int fel; //what kind is the LFO (0 - frequency, 1 - amplitude, 2 - filter) + const AbsTime *time; + int64_t last_update_timestamp; + static const rtosc::Ports &ports; private: /* Default parameters */ diff --git a/source/native-plugins/zynaddsubfx/Params/PADnoteParameters.cpp b/source/native-plugins/zynaddsubfx/Params/PADnoteParameters.cpp index 14e5d9b96..d60e72616 100644 --- a/source/native-plugins/zynaddsubfx/Params/PADnoteParameters.cpp +++ b/source/native-plugins/zynaddsubfx/Params/PADnoteParameters.cpp @@ -35,6 +35,8 @@ using namespace rtosc; #define rObject PADnoteParameters +#undef rChangeCb +#define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); } static const rtosc::Ports realtime_ports = { rRecurp(FreqLfo, "Frequency LFO"), @@ -237,6 +239,7 @@ static const rtosc::Ports non_realtime_ports = {"needPrepare:", rDoc("Unimplemented Stub"), NULL, [](const char *, rtosc::RtData&) {}}, }; +#undef rChangeCb const rtosc::Ports &PADnoteParameters::non_realtime_ports = ::non_realtime_ports; const rtosc::Ports &PADnoteParameters::realtime_ports = ::realtime_ports; @@ -249,8 +252,9 @@ const rtosc::MergePorts PADnoteParameters::ports = }; -PADnoteParameters::PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_) - :Presets(), synth(synth_) +PADnoteParameters::PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_, + const AbsTime *time_) + : Presets(), time(time_), last_update_timestamp(0), synth(synth_) { setpresettype("Ppadsynth"); @@ -260,18 +264,18 @@ PADnoteParameters::PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_) oscilgen = new OscilGen(synth, fft_, resonance); oscilgen->ADvsPAD = true; - FreqEnvelope = new EnvelopeParams(0, 0); + FreqEnvelope = new EnvelopeParams(0, 0, time_); FreqEnvelope->ASRinit(64, 50, 64, 60); - FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0); + FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0, time_); - AmpEnvelope = new EnvelopeParams(64, 1); + AmpEnvelope = new EnvelopeParams(64, 1, time_); AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); - AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1); + AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1, time_); - GlobalFilter = new FilterParams(2, 94, 40); - FilterEnvelope = new EnvelopeParams(0, 1); + GlobalFilter = new FilterParams(2, 94, 40, time_); + FilterEnvelope = new EnvelopeParams(0, 1, time_); FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); - FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2); + FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2, time_); for(int i = 0; i < PAD_MAX_SAMPLES; ++i) sample[i].smp = NULL; @@ -1176,6 +1180,10 @@ void PADnoteParameters::paste(PADnoteParameters &x) oscilgen->paste(*x.oscilgen); resonance->paste(*x.resonance); + + if ( time ) { + last_update_timestamp = time->time(); + } } void PADnoteParameters::pasteRT(PADnoteParameters &x) @@ -1215,5 +1223,9 @@ void PADnoteParameters::pasteRT(PADnoteParameters &x) FilterEnvelope->paste(*x.FilterEnvelope); FilterLfo->paste(*x.FilterLfo); + + if ( time ) { + last_update_timestamp = time->time(); + } } #undef COPY diff --git a/source/native-plugins/zynaddsubfx/Params/PADnoteParameters.h b/source/native-plugins/zynaddsubfx/Params/PADnoteParameters.h index c530c77f5..2cbf68e40 100644 --- a/source/native-plugins/zynaddsubfx/Params/PADnoteParameters.h +++ b/source/native-plugins/zynaddsubfx/Params/PADnoteParameters.h @@ -42,7 +42,8 @@ class PADnoteParameters:public Presets { public: - PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_); + PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_, + const AbsTime *time_ = nullptr); ~PADnoteParameters(); void defaults(); @@ -173,6 +174,9 @@ class PADnoteParameters:public Presets void sampleGenerator(PADnoteParameters::callback cb, std::function do_abort); + const AbsTime *time; + int64_t last_update_timestamp; + static const rtosc::MergePorts ports; static const rtosc::Ports &non_realtime_ports; static const rtosc::Ports &realtime_ports; diff --git a/source/native-plugins/zynaddsubfx/Params/SUBnoteParameters.cpp b/source/native-plugins/zynaddsubfx/Params/SUBnoteParameters.cpp index efcad3d53..591f409e8 100644 --- a/source/native-plugins/zynaddsubfx/Params/SUBnoteParameters.cpp +++ b/source/native-plugins/zynaddsubfx/Params/SUBnoteParameters.cpp @@ -25,6 +25,7 @@ #include "EnvelopeParams.h" #include "FilterParams.h" #include "../Misc/Util.h" +#include "../Misc/Time.h" #include #include @@ -33,6 +34,9 @@ #define rObject SUBnoteParameters using namespace rtosc; + +#undef rChangeCb +#define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); } static const rtosc::Ports SUBnotePorts = { rSelf(SUBnoteParameters), rPaste, @@ -56,7 +60,8 @@ static const rtosc::Ports SUBnotePorts = { rParamZyn(PBendAdjust, "Pitch bend adjustment"), rParamZyn(POffsetHz, "Voice constant offset"), #undef rChangeCb -#define rChangeCb obj->updateFrequencyMultipliers(); +#define rChangeCb obj->updateFrequencyMultipliers(); if (obj->time) { \ + obj->last_update_timestamp = obj->time->time(); } rParamI(POvertoneSpread.type, rMap(min, 0), rMap(max, 7), "Spread of harmonic frequencies"), rParamI(POvertoneSpread.par1, rMap(min, 0), rMap(max, 255), @@ -66,7 +71,7 @@ static const rtosc::Ports SUBnotePorts = { rParamI(POvertoneSpread.par3, rMap(min, 0), rMap(max, 255), "Overtone Parameter"), #undef rChangeCb -#define rChangeCb +#define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); } rParamZyn(Pnumstages, rMap(min, 1), rMap(max, 5), "Number of filter stages"), rParamZyn(Pbandwidth, "Bandwidth of filters"), rParamZyn(Phmagtype, "How the magnitudes are computed (0=linear,1=-60dB,2=-60dB)"), @@ -125,21 +130,23 @@ static const rtosc::Ports SUBnotePorts = { }}, }; +#undef rChangeCb const rtosc::Ports &SUBnoteParameters::ports = SUBnotePorts; -SUBnoteParameters::SUBnoteParameters():Presets() +SUBnoteParameters::SUBnoteParameters(const AbsTime *time_) + : Presets(), time(time_), last_update_timestamp(0) { setpresettype("Psubsynth"); - AmpEnvelope = new EnvelopeParams(64, 1); + AmpEnvelope = new EnvelopeParams(64, 1, time_); AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); - FreqEnvelope = new EnvelopeParams(64, 0); + FreqEnvelope = new EnvelopeParams(64, 0, time_); FreqEnvelope->ASRinit(30, 50, 64, 60); - BandWidthEnvelope = new EnvelopeParams(64, 0); + BandWidthEnvelope = new EnvelopeParams(64, 0, time_); BandWidthEnvelope->ASRinit_bw(100, 70, 64, 60); - GlobalFilter = new FilterParams(2, 80, 40); - GlobalFilterEnvelope = new EnvelopeParams(0, 1); + GlobalFilter = new FilterParams(2, 80, 40, time_); + GlobalFilterEnvelope = new EnvelopeParams(0, 1, time_); GlobalFilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); defaults(); @@ -395,6 +402,10 @@ void SUBnoteParameters::paste(SUBnoteParameters &sub) doPaste(Pbwscale); doPaste(Pstart); + + if ( time ) { + last_update_timestamp = time->time(); + } } void SUBnoteParameters::getfromXML(XMLwrapper& xml) diff --git a/source/native-plugins/zynaddsubfx/Params/SUBnoteParameters.h b/source/native-plugins/zynaddsubfx/Params/SUBnoteParameters.h index 4294cd87b..0059fc539 100644 --- a/source/native-plugins/zynaddsubfx/Params/SUBnoteParameters.h +++ b/source/native-plugins/zynaddsubfx/Params/SUBnoteParameters.h @@ -23,13 +23,14 @@ #ifndef SUB_NOTE_PARAMETERS_H #define SUB_NOTE_PARAMETERS_H +#include #include "../globals.h" #include "Presets.h" class SUBnoteParameters:public Presets { public: - SUBnoteParameters(); + SUBnoteParameters(const AbsTime *time_ = nullptr); ~SUBnoteParameters(); void add2XML(XMLwrapper& xml); @@ -105,6 +106,9 @@ class SUBnoteParameters:public Presets //how the harmonics start("0"=0,"1"=random,"2"=1) unsigned char Pstart; + const AbsTime *time; + int64_t last_update_timestamp; + static const rtosc::Ports &ports; }; diff --git a/source/native-plugins/zynaddsubfx/Synth/ADnote.cpp b/source/native-plugins/zynaddsubfx/Synth/ADnote.cpp index 1d13d2949..c3f4694b5 100644 --- a/source/native-plugins/zynaddsubfx/Synth/ADnote.cpp +++ b/source/native-plugins/zynaddsubfx/Synth/ADnote.cpp @@ -38,6 +38,7 @@ ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars) :SynthNote(spars), pars(*pars_) { + memory.beginTransaction(); tmpwavel = memory.valloc(synth.buffersize); tmpwaver = memory.valloc(synth.buffersize); bypassl = memory.valloc(synth.buffersize); @@ -473,6 +474,7 @@ ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars) } initparameters(); + memory.endTransaction(); } SynthNote *ADnote::cloneLegato(void) diff --git a/source/native-plugins/zynaddsubfx/Synth/LFO.cpp b/source/native-plugins/zynaddsubfx/Synth/LFO.cpp index aea7354f7..b0d691049 100644 --- a/source/native-plugins/zynaddsubfx/Synth/LFO.cpp +++ b/source/native-plugins/zynaddsubfx/Synth/LFO.cpp @@ -124,6 +124,7 @@ float LFO::baseOut(const char waveShape, const float phase) float LFO::lfoout() { //update internals XXX TODO cleanup + if ( ! lfopars_.time || lfopars_.last_update_timestamp == lfopars_.time->time()) { waveShape = lfopars_.PLFOtype; int stretch = lfopars_.Pstretch;