commit 8e2d5b49dc03517c60f363b1048dcfc93277f48e
parent 752b97b4009b1e6651c7e689344ba05c00af41ec
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Fri, 27 May 2016 13:51:51 -0400
Envelope: Add Basic Watchpoint Support
Diffstat:
7 files changed, 102 insertions(+), 43 deletions(-)
diff --git a/src/Synth/ADnote.cpp b/src/Synth/ADnote.cpp
@@ -819,7 +819,9 @@ void ADnote::initparameters(WatchManager *wm, const char *prefix)
newamplitude[nvoice] = 1.0f;
if(param.PAmpEnvelopeEnabled) {
- vce.AmpEnvelope = memory.alloc<Envelope>(*param.AmpEnvelope, basefreq, synth.dt());
+ vce.AmpEnvelope = memory.alloc<Envelope>(*param.AmpEnvelope,
+ basefreq, synth.dt(), wm,
+ (pre+"VoicePar"+nvoice+"/AmpEnvelope/").c_str);
vce.AmpEnvelope->envout_dB(); //discard the first envelope sample
newamplitude[nvoice] *= vce.AmpEnvelope->envout_dB();
}
@@ -832,7 +834,9 @@ void ADnote::initparameters(WatchManager *wm, const char *prefix)
/* Voice Frequency Parameters Init */
if(param.PFreqEnvelopeEnabled)
- vce.FreqEnvelope = memory.alloc<Envelope>(*param.FreqEnvelope, basefreq, synth.dt());
+ vce.FreqEnvelope = memory.alloc<Envelope>(*param.FreqEnvelope,
+ basefreq, synth.dt(), wm,
+ (pre+"VoicePar"+nvoice+"/FreqEnvelope/").c_str);
if(param.PFreqLfoEnabled)
vce.FreqLfo = memory.alloc<LFO>(*param.FreqLfo, basefreq, time, wm,
@@ -848,7 +852,9 @@ void ADnote::initparameters(WatchManager *wm, const char *prefix)
if(param.PFilterEnvelopeEnabled) {
vce.FilterEnvelope =
- memory.alloc<Envelope>(*param.FilterEnvelope, basefreq, synth.dt());
+ memory.alloc<Envelope>(*param.FilterEnvelope,
+ basefreq, synth.dt(), wm,
+ (pre+"VoicePar"+nvoice+"/FilterEnvelope/").c_str);
vce.Filter->addMod(*vce.FilterEnvelope);
}
@@ -898,13 +904,17 @@ void ADnote::initparameters(WatchManager *wm, const char *prefix)
}
if(param.PFMFreqEnvelopeEnabled)
- vce.FMFreqEnvelope = memory.alloc<Envelope>(*param.FMFreqEnvelope, basefreq, synth.dt());
+ vce.FMFreqEnvelope = memory.alloc<Envelope>(*param.FMFreqEnvelope,
+ basefreq, synth.dt(), wm,
+ (pre+"VoicePar"+nvoice+"/FMFreqEnvelope/").c_str);
FMnewamplitude[nvoice] = vce.FMVolume * ctl.fmamp.relamp;
if(param.PFMAmpEnvelopeEnabled ) {
vce.FMAmpEnvelope =
- memory.alloc<Envelope>(*param.FMAmpEnvelope, basefreq, synth.dt());
+ memory.alloc<Envelope>(*param.FMAmpEnvelope,
+ basefreq, synth.dt(), wm,
+ (pre+"VoicePar"+nvoice+"/FMAmpEnvelope/").c_str);
FMnewamplitude[nvoice] *= vce.FMAmpEnvelope->envout_dB();
}
}
@@ -1884,11 +1894,13 @@ void ADnote::Global::initparameters(const ADnoteGlobalParam ¶m,
const char *prefix)
{
ScratchString pre = prefix;
- FreqEnvelope = memory.alloc<Envelope>(*param.FreqEnvelope, basefreq, synth.dt());
+ FreqEnvelope = memory.alloc<Envelope>(*param.FreqEnvelope, basefreq,
+ synth.dt(), wm, (pre+"GlobalPar/FreqEnvelope/").c_str);
FreqLfo = memory.alloc<LFO>(*param.FreqLfo, basefreq, time, wm,
(pre+"GlobalPar/FreqLfo/").c_str);
- AmpEnvelope = memory.alloc<Envelope>(*param.AmpEnvelope, basefreq, synth.dt());
+ AmpEnvelope = memory.alloc<Envelope>(*param.AmpEnvelope, basefreq,
+ synth.dt(), wm, (pre+"GlobalPar/AmpEnvelope/").c_str);
AmpLfo = memory.alloc<LFO>(*param.AmpLfo, basefreq, time, wm,
(pre+"GlobalPar/AmpLfo/").c_str);
@@ -1898,7 +1910,8 @@ void ADnote::Global::initparameters(const ADnoteGlobalParam ¶m,
Filter = memory.alloc<ModFilter>(*param.GlobalFilter, synth, time, memory,
stereo, basefreq);
- FilterEnvelope = memory.alloc<Envelope>(*param.FilterEnvelope, basefreq, synth.dt());
+ FilterEnvelope = memory.alloc<Envelope>(*param.FilterEnvelope, basefreq,
+ synth.dt(), wm, (pre+"GlobalPar/FilterEnvelope/").c_str);
FilterLfo = memory.alloc<LFO>(*param.FilterLfo, basefreq, time, wm,
(pre+"GlobalPar/FilterLfo/").c_str);
diff --git a/src/Synth/Envelope.cpp b/src/Synth/Envelope.cpp
@@ -15,7 +15,9 @@
#include "Envelope.h"
#include "../Params/EnvelopeParams.h"
-Envelope::Envelope(EnvelopeParams &pars, float basefreq, float bufferdt)
+Envelope::Envelope(EnvelopeParams &pars, float basefreq, float bufferdt,
+ WatchManager *m, const char *watch_prefix)
+ :watchOut(m, watch_prefix, "out")
{
envpoints = pars.Penvpoints;
if(envpoints > MAX_ENVELOPE_POINTS)
@@ -100,20 +102,28 @@ void Envelope::forceFinish(void)
/*
* Envelope Output
*/
-float Envelope::envout()
+float Envelope::envout(bool doWatch)
{
float out;
if(envfinish) { //if the envelope is finished
envoutval = envval[envpoints - 1];
+ if(doWatch) {
+ float pos[2] = {(float)envpoints - 1, envoutval};
+ watchOut(pos, 2);
+ }
return envoutval;
}
if((currentpoint == envsustain + 1) && !keyreleased) { //if it is sustaining now
envoutval = envval[envsustain];
+ if(doWatch) {
+ float pos[2] = {(float)envsustain, envoutval};
+ watchOut(pos, 2);
+ }
return envoutval;
}
- if(keyreleased && (forcedrelease != 0)) { //do the forced release
+ if(keyreleased && forcedrelease) { //do the forced release
int tmp = (envsustain < 0) ? (envpoints - 1) : (envsustain + 1); //if there is no sustain point, use the last point for release
if(envdt[tmp] < 0.00000001f)
@@ -130,6 +140,12 @@ float Envelope::envout()
if((currentpoint >= envpoints) || (envsustain < 0))
envfinish = true;
}
+
+ if(doWatch) {
+ float pos[2] = {(float)tmp + t, envoutval};
+ watchOut(pos, 2);
+ }
+
return out;
}
if(inct >= 1.0f)
@@ -149,6 +165,11 @@ float Envelope::envout()
}
envoutval = out;
+
+ if(doWatch) {
+ float pos[2] = {(float)currentpoint + t, envoutval};
+ watchOut(pos, 2);
+ }
return out;
}
@@ -166,10 +187,10 @@ inline float Envelope::env_rap2dB(float rap) {
float Envelope::envout_dB()
{
float out;
- if(linearenvelope != 0)
- return envout();
+ if(linearenvelope)
+ return envout(true);
- if((currentpoint == 1) && (!keyreleased || (forcedrelease == 0))) { //first point is always lineary interpolated
+ if((currentpoint == 1) && (!keyreleased || !forcedrelease)) { //first point is always lineary interpolated
float v1 = env_dB2rap(envval[0]);
float v2 = env_dB2rap(envval[1]);
out = v1 + (v2 - v1) * t;
@@ -186,9 +207,11 @@ float Envelope::envout_dB()
envoutval = env_rap2dB(out);
else
envoutval = MIN_ENVELOPE_DB;
- }
- else
- out = env_dB2rap(envout());
+ } else
+ out = env_dB2rap(envout(false));
+
+ float pos[2] = {(float)currentpoint + t, out};
+ watchOut(pos, 2);
return out;
}
diff --git a/src/Synth/Envelope.h b/src/Synth/Envelope.h
@@ -15,6 +15,7 @@
#define ENVELOPE_H
#include "../globals.h"
+#include "WatchPoint.h"
/**Implementation of a general Envelope*/
class Envelope
@@ -22,17 +23,18 @@ class Envelope
public:
/**Constructor*/
- Envelope(class EnvelopeParams &pars, float basefreq, float dt);
+ Envelope(class EnvelopeParams &pars, float basefreq, float dt, WatchManager *m=0,
+ const char *watch_prefix=0);
/**Destructor*/
- ~Envelope();
- void releasekey();
+ ~Envelope(void);
+ void releasekey(void);
/**Push Envelope to finishing state*/
void forceFinish(void);
- float envout();
- float envout_dB();
+ float envout(bool doWatch=true);
+ float envout_dB(void);
/**Determines the status of the Envelope
* @return returns 1 if the envelope is finished*/
- bool finished() const;
+ bool finished(void) const;
private:
float env_rap2dB(float rap);
float env_dB2rap(float db);
@@ -44,12 +46,14 @@ class Envelope
int linearenvelope;
int currentpoint; //current envelope point (starts from 1)
- int forcedrelease;
+ bool forcedrelease;
bool keyreleased; //if the key was released
bool envfinish;
float t; // the time from the last point
float inct; // the time increment
float envoutval; //used to do the forced release
+
+ VecWatchPoint watchOut;
};
diff --git a/src/Synth/PADnote.cpp b/src/Synth/PADnote.cpp
@@ -135,13 +135,19 @@ void PADnote::setup(float freq,
ScratchString pre = prefix;
- NoteGlobalPar.FreqEnvelope = memory.alloc<Envelope>(*pars.FreqEnvelope, basefreq, synth.dt());
- NoteGlobalPar.FreqLfo = memory.alloc<LFO>(*pars.FreqLfo, basefreq, time, wm,
- (pre+"freqlfo/").c_str);
-
- NoteGlobalPar.AmpEnvelope = memory.alloc<Envelope>(*pars.AmpEnvelope, basefreq, synth.dt());
- NoteGlobalPar.AmpLfo = memory.alloc<LFO>(*pars.AmpLfo, basefreq, time, wm,
- (pre+"amplfo/").c_str);
+ NoteGlobalPar.FreqEnvelope =
+ memory.alloc<Envelope>(*pars.FreqEnvelope, basefreq, synth.dt(),
+ wm, (pre+"FreqEnvelope/").c_str);
+ NoteGlobalPar.FreqLfo =
+ memory.alloc<LFO>(*pars.FreqLfo, basefreq, time,
+ wm, (pre+"FreqLfo/").c_str);
+
+ NoteGlobalPar.AmpEnvelope =
+ memory.alloc<Envelope>(*pars.AmpEnvelope, basefreq, synth.dt(),
+ wm, (pre+"AmpEnvelope/").c_str);
+ NoteGlobalPar.AmpLfo =
+ memory.alloc<LFO>(*pars.AmpLfo, basefreq, time,
+ wm, (pre+"AmpLfo/").c_str);
}
NoteGlobalPar.Volume = 4.0f
@@ -155,6 +161,7 @@ void PADnote::setup(float freq,
* NoteGlobalPar.AmpLfo->amplfoout();
if(!legato) {
+ ScratchString pre = prefix;
auto &flt = NoteGlobalPar.GlobalFilter;
auto &env = NoteGlobalPar.FilterEnvelope;
auto &lfo = NoteGlobalPar.FilterLfo;
@@ -162,8 +169,10 @@ void PADnote::setup(float freq,
flt = memory.alloc<ModFilter>(*pars.GlobalFilter, synth, time, memory, true, basefreq);
//setup mod
- env = memory.alloc<Envelope>(*pars.FilterEnvelope, basefreq, synth.dt());
- lfo = memory.alloc<LFO>(*pars.FilterLfo, basefreq, time);
+ env = memory.alloc<Envelope>(*pars.FilterEnvelope, basefreq,
+ synth.dt(), wm, (pre+"FilterEnvelope/").c_str);
+ lfo = memory.alloc<LFO>(*pars.FilterLfo, basefreq, time,
+ wm, (pre+"FilterLfo/").c_str);
flt->addMod(*env);
flt->addMod(*lfo);
}
diff --git a/src/Synth/SUBnote.cpp b/src/Synth/SUBnote.cpp
@@ -20,6 +20,7 @@
#include "SUBnote.h"
#include "Envelope.h"
#include "ModFilter.h"
+#include "../Containers/ScratchString.h"
#include "../Params/Controller.h"
#include "../Params/SUBnoteParameters.h"
#include "../Params/FilterParams.h"
@@ -35,7 +36,8 @@ SUBnote::SUBnote(const SUBnoteParameters *parameters, SynthParams &spars)
GlobalFilter(nullptr),
GlobalFilterEnvelope(nullptr),
NoteEnabled(true),
- lfilter(nullptr), rfilter(nullptr)
+ lfilter(nullptr), rfilter(nullptr),
+ wm(nullptr)
{
setup(spars.frequency, spars.velocity, spars.portamento, spars.note);
}
@@ -198,9 +200,9 @@ void SUBnote::setup(float freq,
oldbandwidth = 64;
if(!legato) { //normal note
if(pars.Pfixedfreq == 0)
- initparameters(basefreq);
+ initparameters(basefreq, wm);
else
- initparameters(basefreq / 440.0f * freq);
+ initparameters(basefreq / 440.0f * freq, wm);
}
else {
if(pars.Pfixedfreq == 0)
@@ -376,18 +378,25 @@ void SUBnote::filter(bpfilter &filter, float *smps)
/*
* Init Parameters
*/
-void SUBnote::initparameters(float freq)
+void SUBnote::initparameters(float freq, WatchManager *wm)
{
- AmpEnvelope = memory.alloc<Envelope>(*pars.AmpEnvelope, freq, synth.dt());
+ //TODO populate this base string
+ ScratchString pre;
+ AmpEnvelope = memory.alloc<Envelope>(*pars.AmpEnvelope, freq,
+ synth.dt(), wm, (pre+"AmpEnvelope/").c_str);
if(pars.PFreqEnvelopeEnabled)
- FreqEnvelope = memory.alloc<Envelope>(*pars.FreqEnvelope, freq, synth.dt());
+ FreqEnvelope = memory.alloc<Envelope>(*pars.FreqEnvelope, freq,
+ synth.dt(), wm, (pre+"FreqEnvelope/").c_str);
if(pars.PBandWidthEnvelopeEnabled)
- BandWidthEnvelope = memory.alloc<Envelope>(*pars.BandWidthEnvelope, freq, synth.dt());
+ BandWidthEnvelope = memory.alloc<Envelope>(*pars.BandWidthEnvelope,
+ freq, synth.dt(), wm, (pre+"BandWidthEnvelope/").c_str);
if(pars.PGlobalFilterEnabled) {
- GlobalFilterEnvelope = memory.alloc<Envelope>(*pars.GlobalFilterEnvelope, freq, synth.dt());
+ GlobalFilterEnvelope =
+ memory.alloc<Envelope>(*pars.GlobalFilterEnvelope, freq,
+ synth.dt(), wm, (pre+"GlobalFilterEnvelope/").c_str);
GlobalFilter = memory.alloc<ModFilter>(*pars.GlobalFilter, synth, time, memory, stereo, freq);
diff --git a/src/Synth/SUBnote.h b/src/Synth/SUBnote.h
@@ -43,7 +43,7 @@ class SUBnote:public SynthNote
* Initialize envelopes and global filter
* calls computercurrentparameters()
*/
- void initparameters(float freq);
+ void initparameters(float freq, WatchManager *wm);
void KillNote();
const SUBnoteParameters &pars;
@@ -101,6 +101,7 @@ class SUBnote:public SynthNote
int oldpitchwheel, oldbandwidth;
float globalfiltercenterq;
float velocity;
+ WatchManager *wm;
};
#endif
diff --git a/src/Synth/WatchPoint.h b/src/Synth/WatchPoint.h
@@ -13,7 +13,7 @@
#pragma once
-class WatchManager;
+struct WatchManager;
namespace rtosc {class ThreadLink;}
struct WatchPoint