commit 2c952c5aa81b1ead5454ce95222028db434dd853
parent 8f070f1e15b6e24a97a75cb5c7e85b729dcbed54
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Fri, 8 May 2015 13:16:39 -0400
Demote 'synth' From Global Scope
Diffstat:
69 files changed, 633 insertions(+), 668 deletions(-)
diff --git a/src/DSP/Filter.cpp b/src/DSP/Filter.cpp
@@ -20,8 +20,9 @@
*/
-#include <math.h>
-#include <stdio.h>
+#include <cmath>
+#include <cstdio>
+#include <cassert>
#include "Filter.h"
#include "AnalogFilter.h"
@@ -41,10 +42,8 @@ Filter::Filter(unsigned int srate, int bufsize)
Filter *Filter::generate(Allocator &memory, FilterParams *pars,
unsigned int srate, int bufsize)
{
- if (srate == 0)
- srate = synth->samplerate;
- if (bufsize == 0)
- bufsize = synth->buffersize;
+ assert(srate != 0);
+ assert(bufsize != 0);
unsigned char Ftype = pars->Ptype;
unsigned char Fstages = pars->Pstages;
diff --git a/src/DSP/Filter.h b/src/DSP/Filter.h
@@ -29,7 +29,8 @@ class Filter
{
public:
static float getrealfreq(float freqpitch);
- static Filter *generate(class Allocator &memory, class FilterParams * pars, unsigned int srate = 0, int bufsize = 0);
+ static Filter *generate(class Allocator &memory, class FilterParams *pars,
+ unsigned int srate, int bufsize);
Filter(unsigned int srate, int bufsize);
virtual ~Filter() {}
diff --git a/src/Effects/EffectMgr.cpp b/src/Effects/EffectMgr.cpp
@@ -108,19 +108,20 @@ static const rtosc::Ports local_ports = {
const rtosc::Ports &EffectMgr::ports = local_ports;
-EffectMgr::EffectMgr(Allocator &alloc, const bool insertion_)
+EffectMgr::EffectMgr(Allocator &alloc, const SYNTH_T &synth_, const bool insertion_)
:insertion(insertion_),
- efxoutl(new float[synth->buffersize]),
- efxoutr(new float[synth->buffersize]),
+ efxoutl(new float[synth_.buffersize]),
+ efxoutr(new float[synth_.buffersize]),
filterpars(NULL),
nefx(0),
efx(NULL),
dryonly(false),
- memory(alloc)
+ memory(alloc),
+ synth(synth_)
{
setpresettype("Peffect");
- memset(efxoutl, 0, synth->bufferbytes);
- memset(efxoutr, 0, synth->bufferbytes);
+ memset(efxoutl, 0, synth.bufferbytes);
+ memset(efxoutr, 0, synth.bufferbytes);
memset(settings, 0, sizeof(settings));
defaults();
}
@@ -146,11 +147,11 @@ void EffectMgr::changeeffectrt(int _nefx)
if(nefx == _nefx && efx != NULL)
return;
nefx = _nefx;
- memset(efxoutl, 0, synth->bufferbytes);
- memset(efxoutr, 0, synth->bufferbytes);
+ memset(efxoutl, 0, synth.bufferbytes);
+ memset(efxoutr, 0, synth.bufferbytes);
memory.dealloc(efx);
EffectParams pars(memory, insertion, efxoutl, efxoutr, 0,
- synth->samplerate, synth->buffersize);
+ synth.samplerate, synth.buffersize);
switch(nefx) {
case 1:
efx = memory.alloc<Reverb>(pars);
@@ -285,7 +286,7 @@ void EffectMgr::out(float *smpsl, float *smpsr)
{
if(!efx) {
if(!insertion)
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
smpsl[i] = 0.0f;
smpsr[i] = 0.0f;
efxoutl[i] = 0.0f;
@@ -293,7 +294,7 @@ void EffectMgr::out(float *smpsl, float *smpsr)
}
return;
}
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
smpsl[i] += denormalkillbuf[i];
smpsr[i] += denormalkillbuf[i];
efxoutl[i] = 0.0f;
@@ -304,8 +305,8 @@ void EffectMgr::out(float *smpsl, float *smpsr)
float volume = efx->volume;
if(nefx == 7) { //this is need only for the EQ effect
- memcpy(smpsl, efxoutl, synth->bufferbytes);
- memcpy(smpsr, efxoutr, synth->bufferbytes);
+ memcpy(smpsl, efxoutl, synth.bufferbytes);
+ memcpy(smpsr, efxoutr, synth.bufferbytes);
return;
}
@@ -324,20 +325,20 @@ void EffectMgr::out(float *smpsl, float *smpsr)
v2 *= v2; //for Reverb and Echo, the wet function is not liniar
if(dryonly) //this is used for instrument effect only
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
smpsl[i] *= v1;
smpsr[i] *= v1;
efxoutl[i] *= v2;
efxoutr[i] *= v2;
}
else // normal instrument/insertion effect
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
smpsl[i] = smpsl[i] * v1 + efxoutl[i] * v2;
smpsr[i] = smpsr[i] * v1 + efxoutr[i] * v2;
}
}
else // System effect
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
efxoutl[i] *= 2.0f * volume;
efxoutr[i] *= 2.0f * volume;
smpsl[i] = efxoutl[i];
diff --git a/src/Effects/EffectMgr.h b/src/Effects/EffectMgr.h
@@ -43,7 +43,7 @@ class Allocator;
class EffectMgr:public Presets
{
public:
- EffectMgr(Allocator &alloc, const bool insertion_);
+ EffectMgr(Allocator &alloc, const SYNTH_T &synth, const bool insertion_);
~EffectMgr();
void paste(EffectMgr &e);
@@ -93,6 +93,7 @@ class EffectMgr:public Presets
bool dryonly;
Allocator &memory;
+ const SYNTH_T &synth;
};
#endif
diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp
@@ -210,13 +210,13 @@ static const Ports master_ports = {
m.pendingMemory = false;
}},
{"samplerate:", rMap(unit, Hz) rDoc("Synthesizer Global Sample Rate"), 0, [](const char *, RtData &d) {
- //Master &m = *(Master*)d.obj;
- d.reply("/samplerate", "f", synth->samplerate_f);
+ Master &m = *(Master*)d.obj;
+ d.reply("/samplerate", "f", m.synth.samplerate_f);
}},
{"oscilsize:", rDoc("Synthesizer Global Oscillator Size"), 0, [](const char *, RtData &d) {
- //Master &m = *(Master*)d.obj;
- d.reply("/oscilsize", "f", synth->oscilsize_f);
- d.reply("/oscilsize", "i", synth->oscilsize);
+ Master &m = *(Master*)d.obj;
+ d.reply("/oscilsize", "f", m.synth.oscilsize_f);
+ d.reply("/oscilsize", "i", m.synth.oscilsize);
}},
{"undo_pause",0,0,[](const char *, rtosc::RtData &d)
{d.reply("/undo_pause", "");}},
@@ -284,8 +284,8 @@ vuData::vuData(void)
rmspeakl(0.0f), rmspeakr(0.0f), clipped(0)
{}
-Master::Master()
-:midi(Master::ports), frozenState(false), pendingMemory(false)
+Master::Master(const SYNTH_T &synth_)
+:HDDRecorder(synth_), ctl(synth_), midi(Master::ports), frozenState(false), pendingMemory(false), synth(synth_)
{
bToU = NULL;
uToB = NULL;
@@ -294,10 +294,10 @@ Master::Master()
swaplr = 0;
off = 0;
smps = 0;
- bufl = new float[synth->buffersize];
- bufr = new float[synth->buffersize];
+ bufl = new float[synth.buffersize];
+ bufr = new float[synth.buffersize];
- fft = new FFTwrapper(synth->oscilsize);
+ fft = new FFTwrapper(synth.oscilsize);
shutup = 0;
for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
@@ -306,15 +306,15 @@ Master::Master()
}
for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
- part[npart] = new Part(*memory, µtonal, fft);
+ part[npart] = new Part(*memory, synth, µtonal, fft);
//Insertion Effects init
for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
- insefx[nefx] = new EffectMgr(*memory, 1);
+ insefx[nefx] = new EffectMgr(*memory, synth, 1);
//System Effects init
for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx)
- sysefx[nefx] = new EffectMgr(*memory, 0);
+ sysefx[nefx] = new EffectMgr(*memory, synth, 0);
defaults();
@@ -471,7 +471,7 @@ void Master::vuUpdate(const float *outl, const float *outr)
//Peak computation (for vumeters)
vu.outpeakl = 1e-12;
vu.outpeakr = 1e-12;
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
if(fabs(outl[i]) > vu.outpeakl)
vu.outpeakl = fabs(outl[i]);
if(fabs(outr[i]) > vu.outpeakr)
@@ -487,12 +487,12 @@ void Master::vuUpdate(const float *outl, const float *outr)
//RMS Peak computation (for vumeters)
vu.rmspeakl = 1e-12;
vu.rmspeakr = 1e-12;
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
vu.rmspeakl += outl[i] * outl[i];
vu.rmspeakr += outr[i] * outr[i];
}
- vu.rmspeakl = sqrt(vu.rmspeakl / synth->buffersize_f);
- vu.rmspeakr = sqrt(vu.rmspeakr / synth->buffersize_f);
+ vu.rmspeakl = sqrt(vu.rmspeakl / synth.buffersize_f);
+ vu.rmspeakr = sqrt(vu.rmspeakr / synth.buffersize_f);
//Part Peak computation (for Part vumeters or fake part vumeters)
for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
@@ -500,7 +500,7 @@ void Master::vuUpdate(const float *outl, const float *outr)
if(part[npart]->Penabled != 0) {
float *outl = part[npart]->partoutl,
*outr = part[npart]->partoutr;
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float tmp = fabs(outl[i] + outr[i]);
if(tmp > vuoutpeakpart[npart])
vuoutpeakpart[npart] = tmp;
@@ -655,8 +655,8 @@ void Master::AudioOut(float *outl, float *outr)
swap(outl, outr);
//clean up the output samples (should not be needed?)
- memset(outl, 0, synth->bufferbytes);
- memset(outr, 0, synth->bufferbytes);
+ memset(outl, 0, synth.bufferbytes);
+ memset(outr, 0, synth.bufferbytes);
//Compute part samples and store them part[npart]->partoutl,partoutr
for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
@@ -693,11 +693,11 @@ void Master::AudioOut(float *outl, float *outr)
//the volume or the panning has changed and needs interpolation
if(ABOVE_AMPLITUDE_THRESHOLD(oldvol.l, newvol.l)
|| ABOVE_AMPLITUDE_THRESHOLD(oldvol.r, newvol.r)) {
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
Stereo<float> vol(INTERPOLATE_AMPLITUDE(oldvol.l, newvol.l,
- i, synth->buffersize),
+ i, synth.buffersize),
INTERPOLATE_AMPLITUDE(oldvol.r, newvol.r,
- i, synth->buffersize));
+ i, synth.buffersize));
part[npart]->partoutl[i] *= vol.l;
part[npart]->partoutr[i] *= vol.r;
}
@@ -705,7 +705,7 @@ void Master::AudioOut(float *outl, float *outr)
part[npart]->oldvolumer = newvol.r;
}
else {
- for(int i = 0; i < synth->buffersize; ++i) { //the volume did not changed
+ for(int i = 0; i < synth.buffersize; ++i) { //the volume did not changed
part[npart]->partoutl[i] *= newvol.l;
part[npart]->partoutr[i] *= newvol.r;
}
@@ -718,11 +718,11 @@ void Master::AudioOut(float *outl, float *outr)
if(sysefx[nefx]->geteffect() == 0)
continue; //the effect is disabled
- float tmpmixl[synth->buffersize];
- float tmpmixr[synth->buffersize];
+ float tmpmixl[synth.buffersize];
+ float tmpmixr[synth.buffersize];
//Clean up the samples used by the system effects
- memset(tmpmixl, 0, synth->bufferbytes);
- memset(tmpmixr, 0, synth->bufferbytes);
+ memset(tmpmixl, 0, synth.bufferbytes);
+ memset(tmpmixr, 0, synth.bufferbytes);
//Mix the channels according to the part settings about System Effect
for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
@@ -736,7 +736,7 @@ void Master::AudioOut(float *outl, float *outr)
//the output volume of each part to system effect
const float vol = sysefxvol[nefx][npart];
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
tmpmixl[i] += part[npart]->partoutl[i] * vol;
tmpmixr[i] += part[npart]->partoutr[i] * vol;
}
@@ -746,7 +746,7 @@ void Master::AudioOut(float *outl, float *outr)
for(int nefxfrom = 0; nefxfrom < nefx; ++nefxfrom)
if(Psysefxsend[nefxfrom][nefx] != 0) {
const float vol = sysefxsend[nefxfrom][nefx];
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
tmpmixl[i] += sysefx[nefxfrom]->efxoutl[i] * vol;
tmpmixr[i] += sysefx[nefxfrom]->efxoutr[i] * vol;
}
@@ -756,7 +756,7 @@ void Master::AudioOut(float *outl, float *outr)
//Add the System Effect to sound output
const float outvol = sysefx[nefx]->sysefxgetvolume();
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
outl[i] += tmpmixl[i] * outvol;
outr[i] += tmpmixr[i] * outvol;
}
@@ -765,7 +765,7 @@ void Master::AudioOut(float *outl, float *outr)
//Mix all parts
for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
if(part[npart]->Penabled) //only mix active parts
- for(int i = 0; i < synth->buffersize; ++i) { //the volume did not changed
+ for(int i = 0; i < synth.buffersize; ++i) { //the volume did not changed
outl[i] += part[npart]->partoutl[i];
outr[i] += part[npart]->partoutr[i];
}
@@ -777,7 +777,7 @@ void Master::AudioOut(float *outl, float *outr)
//Master Volume
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
outl[i] *= volume;
outr[i] *= volume;
}
@@ -786,8 +786,8 @@ void Master::AudioOut(float *outl, float *outr)
//Shutup if it is asked (with fade-out)
if(shutup) {
- for(int i = 0; i < synth->buffersize; ++i) {
- float tmp = (synth->buffersize_f - i) / synth->buffersize_f;
+ for(int i = 0; i < synth.buffersize; ++i) {
+ float tmp = (synth.buffersize_f - i) / synth.buffersize_f;
outl[i] *= tmp;
outr[i] *= tmp;
}
@@ -808,8 +808,8 @@ void Master::GetAudioOutSamples(size_t nsamples,
off_t out_off = 0;
//Fail when resampling rather than doing a poor job
- if(synth->samplerate != samplerate) {
- printf("darn it: %d vs %d\n", synth->samplerate, samplerate);
+ if(synth.samplerate != samplerate) {
+ printf("darn it: %d vs %d\n", synth.samplerate, samplerate);
return;
}
@@ -824,7 +824,7 @@ void Master::GetAudioOutSamples(size_t nsamples,
AudioOut(bufl, bufr);
off = 0;
out_off += smps;
- smps = synth->buffersize;
+ smps = synth.buffersize;
}
else { //use some samples
memcpy(outl + out_off, bufl + off, sizeof(float) * nsamples);
diff --git a/src/Misc/Master.h b/src/Misc/Master.h
@@ -49,7 +49,7 @@ class Master
{
public:
/** Constructor TODO make private*/
- Master();
+ Master(const SYNTH_T &synth);
/** Destructor*/
~Master();
@@ -167,6 +167,7 @@ class Master
rtosc::ThreadLink *bToU;
rtosc::ThreadLink *uToB;
bool pendingMemory;
+ const SYNTH_T &synth;
private:
float sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
float sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
diff --git a/src/Misc/MiddleWare.cpp b/src/Misc/MiddleWare.cpp
@@ -529,7 +529,7 @@ class MiddleWareImpl
}
public:
- MiddleWareImpl(MiddleWare *mw, int prefered_port);
+ MiddleWareImpl(MiddleWare *mw, SYNTH_T synth, int prefered_port);
~MiddleWareImpl(void);
void warnMemoryLeaks(void);
@@ -616,7 +616,7 @@ public:
auto alloc = std::async(std::launch::async,
[master,filename,this,npart](){
- Part *p = new Part(*master->memory, &master->microtonal, master->fft);
+ Part *p = new Part(*master->memory, synth, &master->microtonal, master->fft);
if(p->loadXMLinstrument(filename))
fprintf(stderr, "Warning: failed to load part!\n");
@@ -650,7 +650,7 @@ public:
//structures at once... TODO error handling
void loadMaster(const char *filename)
{
- Master *m = new Master();
+ Master *m = new Master(synth);
m->uToB = uToB;
m->bToU = bToU;
if(filename) {
@@ -799,10 +799,13 @@ public:
//LIBLO
lo_server server;
string last_url, curr_url;
+
+ //Synthesis Rate Parameters
+ const SYNTH_T synth;
};
-MiddleWareImpl::MiddleWareImpl(MiddleWare *mw, int prefered_port)
- :parent(mw)
+MiddleWareImpl::MiddleWareImpl(MiddleWare *mw, SYNTH_T synth_, int prefered_port)
+ :parent(mw), synth(synth_)
{
bToU = new rtosc::ThreadLink(4096*2,1024);
uToB = new rtosc::ThreadLink(4096*2,1024);
@@ -821,7 +824,7 @@ MiddleWareImpl::MiddleWareImpl(MiddleWare *mw, int prefered_port)
idle = 0;
the_bToU = bToU;
- master = new Master();
+ master = new Master(synth);
master->bToU = bToU;
master->uToB = uToB;
osc = GUI::genOscInterface(mw);
@@ -1073,11 +1076,11 @@ 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(master->fft);
+ ptr = kits.add[part][kit] = new ADnoteParameters(synth, master->fft);
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(master->fft);
+ ptr = kits.pad[part][kit] = new PADnoteParameters(synth, master->fft);
url += "padpars-data";
obj_store.extractPAD(kits.pad[part][kit], part, kit);
} else if(type == 2 && kits.sub[part][kit] == NULL) {
@@ -1212,8 +1215,8 @@ void MiddleWareImpl::warnMemoryLeaks(void)
/******************************************************************************
* MidleWare Forwarding Stubs *
******************************************************************************/
-MiddleWare::MiddleWare(int prefered_port)
-:impl(new MiddleWareImpl(this, prefered_port))
+MiddleWare::MiddleWare(SYNTH_T synth, int prefered_port)
+:impl(new MiddleWareImpl(this, synth, prefered_port))
{}
MiddleWare::~MiddleWare(void)
{
@@ -1289,3 +1292,8 @@ void MiddleWare::activeUrl(std::string u)
{
impl->last_url = u;
}
+
+const SYNTH_T &MiddleWare::getSynth(void) const
+{
+ return impl->synth;
+}
diff --git a/src/Misc/MiddleWare.h b/src/Misc/MiddleWare.h
@@ -3,11 +3,12 @@
#include <cstdarg>
#include <string>
+struct SYNTH_T;
//Link between realtime and non-realtime layers
class MiddleWare
{
public:
- MiddleWare(int prefered_port = -1);
+ MiddleWare(SYNTH_T synth, int prefered_port = -1);
~MiddleWare(void);
//returns internal master pointer
class Master *spawnMaster(void);
@@ -32,6 +33,8 @@ class MiddleWare
//Get/Set the active bToU url
std::string activeUrl(void);
void activeUrl(std::string u);
+ //View Synthesis Parameters
+ const SYNTH_T &getSynth(void) const;
private:
class MiddleWareImpl *impl;
};
diff --git a/src/Misc/Part.cpp b/src/Misc/Part.cpp
@@ -168,13 +168,13 @@ static const Ports kitPorts = {
const Ports &Part::Kit::ports = kitPorts;
const Ports &Part::ports = partPorts;
-Part::Part(Allocator &alloc, Microtonal *microtonal_, FFTwrapper *fft_)
- :memory(alloc)
+Part::Part(Allocator &alloc, const SYNTH_T &synth_, Microtonal *microtonal_, FFTwrapper *fft_)
+ :ctl(synth_), memory(alloc), synth(synth_)
{
microtonal = microtonal_;
fft = fft_;
- partoutl = new float [synth->buffersize];
- partoutr = new float [synth->buffersize];
+ partoutl = new float [synth.buffersize];
+ partoutr = new float [synth.buffersize];
monomemClear();
@@ -185,17 +185,17 @@ Part::Part(Allocator &alloc, Microtonal *microtonal_, FFTwrapper *fft_)
kit[n].padpars = nullptr;
}
- kit[0].adpars = new ADnoteParameters(fft);
+ kit[0].adpars = new ADnoteParameters(synth, fft);
//Part's Insertion Effects init
for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
- partefx[nefx] = new EffectMgr(memory, 1);
+ partefx[nefx] = new EffectMgr(memory, synth, 1);
Pefxbypass[nefx] = false;
}
for(int n = 0; n < NUM_PART_EFX + 1; ++n) {
- partfxinputl[n] = new float [synth->buffersize];
- partfxinputr[n] = new float [synth->buffersize];
+ partfxinputl[n] = new float [synth.buffersize];
+ partfxinputr[n] = new float [synth.buffersize];
}
killallnotes = false;
@@ -311,7 +311,7 @@ void Part::cleanup(bool final_)
{
for(int k = 0; k < POLYPHONY; ++k)
KillNotePos(k);
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
partoutl[i] = final_ ? 0.0f : denormalkillbuf[i];
partoutr[i] = final_ ? 0.0f : denormalkillbuf[i];
}
@@ -319,7 +319,7 @@ void Part::cleanup(bool final_)
for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx)
partefx[nefx]->cleanup();
for(int n = 0; n < NUM_PART_EFX + 1; ++n)
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
partfxinputl[n][i] = final_ ? 0.0f : denormalkillbuf[i];
partfxinputr[n][i] = final_ ? 0.0f : denormalkillbuf[i];
}
@@ -553,7 +553,7 @@ void Part::NoteOn(unsigned char note,
if(Pkitmode == 0) { //init the notes for the "normal mode"
partnote[pos].kititem[0].sendtoparteffect = 0;
- SynthParams pars{memory, ctl, notebasefreq, vel, (bool) portamento, note, false};
+ SynthParams pars{memory, ctl, synth, notebasefreq, vel, (bool) portamento, note, false};
if(kit[0].Padenabled)
partnote[pos].kititem[0].adnote =
@@ -599,7 +599,7 @@ void Part::NoteOn(unsigned char note,
//if this parameter is 127 for "unprocessed"
note1.sendtoparteffect = limit((int)kit[item].Psendtoparteffect, 0, NUM_PART_EFX);
- SynthParams pars{memory, ctl, notebasefreq, vel, (bool) portamento, note, false};
+ SynthParams pars{memory, ctl, synth, notebasefreq, vel, (bool) portamento, note, false};
if(kit[item].adpars && kit[item].Padenabled)
note1.adnote =
@@ -946,13 +946,13 @@ void Part::RunNote(unsigned int k)
continue;
noteplay++;
- float tmpoutr[synth->buffersize];
- float tmpoutl[synth->buffersize];
+ float tmpoutr[synth.buffersize];
+ float tmpoutl[synth.buffersize];
(*note)->noteout(&tmpoutl[0], &tmpoutr[0]);
if((*note)->finished())
memory.dealloc(*note);
- for(int i = 0; i < synth->buffersize; ++i) { //add the note to part(mix)
+ for(int i = 0; i < synth.buffersize; ++i) { //add the note to part(mix)
partfxinputl[sendcurrenttofx][i] += tmpoutl[i];
partfxinputr[sendcurrenttofx][i] += tmpoutr[i];
}
@@ -970,7 +970,7 @@ void Part::RunNote(unsigned int k)
void Part::ComputePartSmps()
{
for(unsigned nefx = 0; nefx < NUM_PART_EFX + 1; ++nefx)
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
partfxinputl[nefx][i] = 0.0f;
partfxinputr[nefx][i] = 0.0f;
}
@@ -989,25 +989,25 @@ void Part::ComputePartSmps()
if(!Pefxbypass[nefx]) {
partefx[nefx]->out(partfxinputl[nefx], partfxinputr[nefx]);
if(Pefxroute[nefx] == 2)
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
partfxinputl[nefx + 1][i] += partefx[nefx]->efxoutl[i];
partfxinputr[nefx + 1][i] += partefx[nefx]->efxoutr[i];
}
}
int routeto = ((Pefxroute[nefx] == 0) ? nefx + 1 : NUM_PART_EFX);
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
partfxinputl[routeto][i] += partfxinputl[nefx][i];
partfxinputr[routeto][i] += partfxinputr[nefx][i];
}
}
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
partoutl[i] = partfxinputl[NUM_PART_EFX][i];
partoutr[i] = partfxinputr[NUM_PART_EFX][i];
}
if(killallnotes) {
- for(int i = 0; i < synth->buffersize; ++i) {
- float tmp = (synth->buffersize_f - i) / synth->buffersize_f;
+ for(int i = 0; i < synth.buffersize; ++i) {
+ float tmp = (synth.buffersize_f - i) / synth.buffersize_f;
partoutl[i] *= tmp;
partoutr[i] *= tmp;
}
@@ -1065,9 +1065,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(fft);
+ kkit.adpars = new ADnoteParameters(synth, fft);
kkit.subpars = new SUBnoteParameters();
- kkit.padpars = new PADnoteParameters(fft);
+ kkit.padpars = new PADnoteParameters(synth, fft);
}
}
@@ -1301,7 +1301,7 @@ void Part::getfromXMLinstrument(XMLwrapper *xml)
kit[i].Padenabled);
if(xml->enterbranch("ADD_SYNTH_PARAMETERS")) {
if(!kit[i].adpars)
- kit[i].adpars = new ADnoteParameters(fft);
+ kit[i].adpars = new ADnoteParameters(synth, fft);
kit[i].adpars->getfromXML(xml);
xml->exitbranch();
}
@@ -1319,7 +1319,7 @@ void Part::getfromXMLinstrument(XMLwrapper *xml)
kit[i].Ppadenabled);
if(xml->enterbranch("PAD_SYNTH_PARAMETERS")) {
if(!kit[i].padpars)
- kit[i].padpars = new PADnoteParameters(fft);
+ kit[i].padpars = new PADnoteParameters(synth, fft);
kit[i].padpars->getfromXML(xml);
xml->exitbranch();
}
diff --git a/src/Misc/Part.h b/src/Misc/Part.h
@@ -37,7 +37,7 @@ class Part
/**Constructor
* @param microtonal_ Pointer to the microtonal object
* @param fft_ Pointer to the FFTwrapper*/
- Part(Allocator &alloc, Microtonal *microtonal_, FFTwrapper *fft_);
+ Part(Allocator &alloc, const SYNTH_T &synth, Microtonal *microtonal_, FFTwrapper *fft_);
/**Destructor*/
~Part();
@@ -197,6 +197,7 @@ class Part
Microtonal *microtonal;
FFTwrapper *fft;
Allocator &memory;
+ const SYNTH_T &synth;
};
#endif
diff --git a/src/Misc/PresetExtractor.cpp b/src/Misc/PresetExtractor.cpp
@@ -291,17 +291,17 @@ void doClassPaste(std::string type, std::string type_, MiddleWare &mw, string ur
else if(type == "FilterParams")
doPaste<FilterParams>(mw, url, type_, data);
else if(type == "ADnoteParameters")
- doPaste<ADnoteParameters>(mw, url, type_, data, (FFTwrapper*)NULL);
+ doPaste<ADnoteParameters>(mw, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL);
else if(type == "PADnoteParameters")
- doPaste<PADnoteParameters>(mw, url, type_, data, (FFTwrapper*)NULL);
+ doPaste<PADnoteParameters>(mw, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL);
else if(type == "SUBnoteParameters")
doPaste<SUBnoteParameters>(mw, url, type_, data);
else if(type == "OscilGen")
- doPaste<OscilGen>(mw, url, type_, data, (FFTwrapper*)NULL, (Resonance*)NULL);
+ doPaste<OscilGen>(mw, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL, (Resonance*)NULL);
else if(type == "Resonance")
doPaste<Resonance>(mw, url, type_, data);
else if(type == "EffectMgr")
- doPaste<EffectMgr>(mw, url, type_, data, DummyAlloc, false);
+ doPaste<EffectMgr>(mw, url, type_, data, DummyAlloc, mw.getSynth(), false);
else {
fprintf(stderr, "Warning: Unknown type<%s> from url<%s>\n", type.c_str(), url.c_str());
}
@@ -336,7 +336,7 @@ void doClassArrayPaste(std::string type, std::string type_, int field, MiddleWar
if(type == "FilterParams")
doArrayPaste<FilterParams>(mw, field, url, type_, data);
else if(type == "ADnoteParameters")
- doArrayPaste<ADnoteParameters>(mw, field, url, type_, data, (FFTwrapper*)NULL);
+ doArrayPaste<ADnoteParameters>(mw, field, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL);
}
std::string doClassArrayCopy(std::string type, int field, MiddleWare &mw, string url, string name)
diff --git a/src/Misc/Recorder.cpp b/src/Misc/Recorder.cpp
@@ -23,10 +23,11 @@
#include <sys/stat.h>
#include "Recorder.h"
#include "WavFile.h"
+#include "../globals.h"
#include "../Nio/Nio.h"
-Recorder::Recorder()
- :status(0), notetrigger(0)
+Recorder::Recorder(const SYNTH_T &synth_)
+ :status(0), notetrigger(0),synth(synth_)
{}
Recorder::~Recorder()
@@ -45,7 +46,7 @@ int Recorder::preparefile(std::string filename_, int overwrite)
return 1;
}
- Nio::waveNew(new WavFile(filename_, synth->samplerate, 2));
+ Nio::waveNew(new WavFile(filename_, synth.samplerate, 2));
status = 1; //ready
diff --git a/src/Misc/Recorder.h b/src/Misc/Recorder.h
@@ -23,14 +23,14 @@
#ifndef RECORDER_H
#define RECORDER_H
#include <string>
-#include "../globals.h"
+struct SYNTH_T;
/**Records sound to a file*/
class Recorder
{
public:
- Recorder();
+ Recorder(const SYNTH_T &synth);
~Recorder();
/**Prepare the given file.
* @returns 1 if the file exists */
@@ -49,6 +49,7 @@ class Recorder
private:
int notetrigger;
+ const SYNTH_T &synth;
};
#endif
diff --git a/src/Nio/AlsaEngine.cpp b/src/Nio/AlsaEngine.cpp
@@ -29,10 +29,10 @@ using namespace std;
#include "InMgr.h"
#include "AlsaEngine.h"
-AlsaEngine::AlsaEngine()
- :AudioOut()
+AlsaEngine::AlsaEngine(const SYNTH_T &synth)
+ :AudioOut(synth)
{
- audio.buffer = new short[synth->buffersize * 2];
+ audio.buffer = new short[synth.buffersize * 2];
name = "ALSA";
audio.handle = NULL;
@@ -296,7 +296,7 @@ bool AlsaEngine::openAudio()
/* Two channels (stereo) */
snd_pcm_hw_params_set_channels(audio.handle, audio.params, 2);
- audio.sampleRate = synth->samplerate;
+ audio.sampleRate = synth.samplerate;
snd_pcm_hw_params_set_rate_near(audio.handle, audio.params,
&audio.sampleRate, NULL);
@@ -321,7 +321,7 @@ bool AlsaEngine::openAudio()
/* latency = periodsize * periods / (rate * bytes_per_frame) */
snd_pcm_hw_params_set_buffer_size(audio.handle,
audio.params,
- synth->buffersize);
+ synth.buffersize);
//snd_pcm_hw_params_get_period_size(audio.params, &audio.frames, NULL);
//snd_pcm_hw_params_get_period_time(audio.params, &val, NULL);
@@ -353,7 +353,7 @@ void *AlsaEngine::processAudio()
while(audio.handle) {
audio.buffer = interleave(getNext());
snd_pcm_t *handle = audio.handle;
- int rc = snd_pcm_writei(handle, audio.buffer, synth->buffersize);
+ int rc = snd_pcm_writei(handle, audio.buffer, synth.buffersize);
if(rc == -EPIPE) {
/* EPIPE means underrun */
cerr << "underrun occurred" << endl;
diff --git a/src/Nio/AlsaEngine.h b/src/Nio/AlsaEngine.h
@@ -35,7 +35,7 @@
class AlsaEngine:public AudioOut, MidiIn
{
public:
- AlsaEngine();
+ AlsaEngine(const SYNTH_T &synth);
~AlsaEngine();
bool Start();
diff --git a/src/Nio/AudioOut.cpp b/src/Nio/AudioOut.cpp
@@ -30,8 +30,8 @@ using namespace std;
#include "../Misc/Master.h"
#include "AudioOut.h"
-AudioOut::AudioOut()
- :samplerate(synth->samplerate), bufferSize(synth->buffersize)
+AudioOut::AudioOut(const SYNTH_T &synth_)
+ :synth(synth_), samplerate(synth.samplerate), bufferSize(synth.buffersize)
{}
AudioOut::~AudioOut()
diff --git a/src/Nio/AudioOut.h b/src/Nio/AudioOut.h
@@ -30,7 +30,7 @@
class AudioOut:public virtual Engine
{
public:
- AudioOut();
+ AudioOut(const SYNTH_T &synth);
virtual ~AudioOut();
/**Sets the Sample Rate of this Output
@@ -54,6 +54,7 @@ class AudioOut:public virtual Engine
* (has nsamples sampled at a rate of samplerate)*/
const Stereo<float *> getNext();
+ const SYNTH_T &synth;
int samplerate;
int bufferSize;
};
diff --git a/src/Nio/EngineMgr.cpp b/src/Nio/EngineMgr.cpp
@@ -1,6 +1,7 @@
#include "EngineMgr.h"
#include <algorithm>
#include <iostream>
+#include <cassert>
#include "Nio.h"
#include "InMgr.h"
#include "OutMgr.h"
@@ -24,31 +25,32 @@
using namespace std;
-EngineMgr &EngineMgr::getInstance()
+EngineMgr &EngineMgr::getInstance(const SYNTH_T *synth)
{
- static EngineMgr instance;
+ static EngineMgr instance(synth);
return instance;
}
-EngineMgr::EngineMgr()
+EngineMgr::EngineMgr(const SYNTH_T *synth)
{
- Engine *defaultEng = new NulEngine();
+ assert(synth);
+ Engine *defaultEng = new NulEngine(*synth);
//conditional compiling mess (but contained)
engines.push_back(defaultEng);
#if OSS
- engines.push_back(new OssEngine());
- engines.push_back(new OssMultiEngine());
+ engines.push_back(new OssEngine(*synth));
+ engines.push_back(new OssMultiEngine(*synth));
#endif
#if ALSA
- engines.push_back(new AlsaEngine());
+ engines.push_back(new AlsaEngine(*synth));
#endif
#if JACK
- engines.push_back(new JackEngine());
- engines.push_back(new JackMultiEngine());
+ engines.push_back(new JackEngine(*synth));
+ engines.push_back(new JackMultiEngine(*synth));
#endif
#if PORTAUDIO
- engines.push_back(new PaEngine());
+ engines.push_back(new PaEngine(*synth));
#endif
defaultOut = dynamic_cast<AudioOut *>(defaultEng);
diff --git a/src/Nio/EngineMgr.h b/src/Nio/EngineMgr.h
@@ -9,11 +9,12 @@
class MidiIn;
class AudioOut;
class OutMgr;
+struct SYNTH_T;
/**Container/Owner of the long lived Engines*/
class EngineMgr
{
public:
- static EngineMgr &getInstance();
+ static EngineMgr &getInstance(const SYNTH_T *synth=NULL);
~EngineMgr();
/**Gets requested engine
@@ -38,6 +39,6 @@ class EngineMgr
AudioOut *defaultOut;
MidiIn *defaultIn;
private:
- EngineMgr();
+ EngineMgr(const SYNTH_T *synth);
};
#endif
diff --git a/src/Nio/InMgr.cpp b/src/Nio/InMgr.cpp
@@ -144,7 +144,7 @@ string InMgr::getSource() const
MidiIn *InMgr::getIn(string name)
{
- EngineMgr &eng = EngineMgr::getInstance();
+ EngineMgr &eng = EngineMgr::getInstance(NULL);
return dynamic_cast<MidiIn *>(eng.getEng(name));
}
diff --git a/src/Nio/JackEngine.cpp b/src/Nio/JackEngine.cpp
@@ -44,8 +44,8 @@ using namespace std;
extern char *instance_name;
-JackEngine::JackEngine()
- :AudioOut(), jackClient(NULL)
+JackEngine::JackEngine(const SYNTH_T &synth)
+ :AudioOut(synth), jackClient(NULL)
{
name = "JACK";
audio.jackSamplerate = 0;
diff --git a/src/Nio/JackEngine.h b/src/Nio/JackEngine.h
@@ -36,7 +36,7 @@ typedef jack_default_audio_sample_t jsample_t;
class JackEngine:public AudioOut, MidiIn
{
public:
- JackEngine();
+ JackEngine(const SYNTH_T &synth);
~JackEngine() { }
bool Start();
diff --git a/src/Nio/JackMultiEngine.cpp b/src/Nio/JackMultiEngine.cpp
@@ -28,7 +28,7 @@
#include <cassert>
#include "Nio.h"
-#include "Misc/Util.h"
+#include "../Misc/Util.h"
#include "../Misc/Master.h"
#include "../Misc/Part.h"
#include "../Misc/MiddleWare.h"
@@ -45,8 +45,8 @@ struct jack_multi
bool running;
};
-JackMultiEngine::JackMultiEngine(void)
- :impl(new jack_multi())
+JackMultiEngine::JackMultiEngine(const SYNTH_T &synth)
+ :AudioOut(synth), impl(new jack_multi())
{
impl->running = false;
impl->client = NULL;
@@ -115,9 +115,9 @@ bool JackMultiEngine::Start(void)
//verify that all sample rate and buffer_size are the same in jack.
//This insures that the connection can be made with no resampling or
//buffering
- if(synth->samplerate != jack_get_sample_rate(impl->client))
+ if(synth.samplerate != jack_get_sample_rate(impl->client))
errx(1, "jack must have the same sample rate!");
- if(synth->buffersize != (int) jack_get_buffer_size(impl->client))
+ if(synth.buffersize != (int) jack_get_buffer_size(impl->client))
errx(1, "jack must have the same buffer size");
jack_set_process_callback(impl->client, _processCallback, this);
@@ -147,14 +147,14 @@ int JackMultiEngine::processAudio(jack_nframes_t nframes)
//Get the wet samples from OutMgr
Stereo<float *> smp = getNext();
- memcpy(buffers[0], smp.l, synth->bufferbytes);
- memcpy(buffers[1], smp.r, synth->bufferbytes);
+ memcpy(buffers[0], smp.l, synth.bufferbytes);
+ memcpy(buffers[1], smp.r, synth.bufferbytes);
//Gather other samples from individual parts
Master &master = *middleware->spawnMaster();
for(int i = 0; i < NUM_MIDI_PARTS; ++i) {
- memcpy(buffers[2*i + 2], master.part[i]->partoutl, synth->bufferbytes);
- memcpy(buffers[2*i + 3], master.part[i]->partoutr, synth->bufferbytes);
+ memcpy(buffers[2*i + 2], master.part[i]->partoutl, synth.bufferbytes);
+ memcpy(buffers[2*i + 3], master.part[i]->partoutr, synth.bufferbytes);
}
return false;
diff --git a/src/Nio/JackMultiEngine.h b/src/Nio/JackMultiEngine.h
@@ -27,7 +27,7 @@
class JackMultiEngine:public AudioOut
{
public:
- JackMultiEngine(void);
+ JackMultiEngine(const SYNTH_T &synth);
~JackMultiEngine(void);
void setAudioEn(bool nval);
diff --git a/src/Nio/Nio.cpp b/src/Nio/Nio.cpp
@@ -29,11 +29,11 @@ bool Nio::pidInClientName = false;
string Nio::defaultSource = IN_DEFAULT;
string Nio::defaultSink = OUT_DEFAULT;
-void Nio::init(class Master *master)
+void Nio::init(const SYNTH_T &synth, class Master *master)
{
in = &InMgr::getInstance(); //Enable input wrapper
- out = &OutMgr::getInstance(); //Initialize the Output Systems
- eng = &EngineMgr::getInstance(); //Initialize The Engines
+ out = &OutMgr::getInstance(&synth); //Initialize the Output Systems
+ eng = &EngineMgr::getInstance(&synth); //Initialize The Engines
in->setMaster(master);
out->setMaster(master);
diff --git a/src/Nio/Nio.h b/src/Nio/Nio.h
@@ -5,13 +5,14 @@
class WavFile;
class Master;
+struct SYNTH_T;
/**Interface to Nio Subsystem
*
* Should be only externally included header */
namespace Nio
{
- void init(Master *master);
+ void init(const SYNTH_T &synth, Master *master);
bool start(void);
void stop(void);
diff --git a/src/Nio/NulEngine.cpp b/src/Nio/NulEngine.cpp
@@ -28,8 +28,8 @@
using namespace std;
-NulEngine::NulEngine()
- :AudioOut(), pThread(NULL)
+NulEngine::NulEngine(const SYNTH_T &synth_)
+ :AudioOut(synth_), pThread(NULL)
{
name = "NULL";
playing_until.tv_sec = 0;
@@ -62,8 +62,8 @@ void *NulEngine::AudioThread()
if(remaining < 0)
cerr << "WARNING - too late" << endl;
}
- playing_until.tv_usec += synth->buffersize * 1000000
- / synth->samplerate;
+ playing_until.tv_usec += synth.buffersize * 1000000
+ / synth.samplerate;
if(remaining < 0)
playing_until.tv_usec -= remaining;
playing_until.tv_sec += playing_until.tv_usec / 1000000;
diff --git a/src/Nio/NulEngine.h b/src/Nio/NulEngine.h
@@ -32,7 +32,7 @@
class NulEngine:public AudioOut, MidiIn
{
public:
- NulEngine();
+ NulEngine(const SYNTH_T &synth_);
~NulEngine();
bool Start();
diff --git a/src/Nio/OssEngine.cpp b/src/Nio/OssEngine.cpp
@@ -179,8 +179,8 @@ OssMidiParse(struct OssMidiParse &midi_parse,
return (0);
}
-OssEngine::OssEngine()
- :AudioOut(), audioThread(NULL), midiThread(NULL)
+OssEngine::OssEngine(const SYNTH_T &synth)
+ :AudioOut(synth), audioThread(NULL), midiThread(NULL)
{
name = "OSS";
@@ -188,8 +188,8 @@ OssEngine::OssEngine()
audio.handle = -1;
/* allocate worst case audio buffer */
- audio.smps.ps32 = new int[synth->buffersize * 2];
- memset(audio.smps.ps32, 0, sizeof(int) * synth->buffersize * 2);
+ audio.smps.ps32 = new int[synth.buffersize * 2];
+ memset(audio.smps.ps32, 0, sizeof(int) * synth.buffersize * 2);
memset(&midi.state, 0, sizeof(midi.state));
}
@@ -208,7 +208,7 @@ bool OssEngine::openAudio()
int snd_fragment;
int snd_stereo = 1; //stereo;
- int snd_samplerate = synth->samplerate;
+ int snd_samplerate = synth.samplerate;
const char *device = getenv("DSP_DEVICE");
if(device == NULL)
@@ -243,15 +243,15 @@ bool OssEngine::openAudio()
ioctl(audio.handle, SNDCTL_DSP_STEREO, &snd_stereo);
ioctl(audio.handle, SNDCTL_DSP_SPEED, &snd_samplerate);
- if (snd_samplerate != (int)synth->samplerate) {
+ if (snd_samplerate != (int)synth.samplerate) {
cerr << "ERROR - Cannot set samplerate for "
<< device << ". " << snd_samplerate
- << " != " << synth->samplerate << endl;
+ << " != " << synth.samplerate << endl;
goto error;
}
/* compute buffer size for 16-bit stereo samples */
- audio.buffersize = 4 * synth->buffersize;
+ audio.buffersize = 4 * synth.buffersize;
if (audio.is32bit)
audio.buffersize *= 2;
@@ -407,7 +407,7 @@ void *OssEngine::audioThreadCb()
const Stereo<float *> smps = getNext();
float l, r;
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
l = smps.l[i];
r = smps.r[i];
diff --git a/src/Nio/OssEngine.h b/src/Nio/OssEngine.h
@@ -45,7 +45,7 @@ struct OssMidiParse {
class OssEngine:public AudioOut, MidiIn
{
public:
- OssEngine();
+ OssEngine(const SYNTH_T &synth);
~OssEngine();
bool Start();
diff --git a/src/Nio/OssMultiEngine.cpp b/src/Nio/OssMultiEngine.cpp
@@ -43,7 +43,8 @@ extern MiddleWare *middleware;
using namespace std;
-OssMultiEngine :: OssMultiEngine()
+OssMultiEngine :: OssMultiEngine(const SYNTH_T &synth)
+ :AudioOut(synth)
{
/* setup variables */
name = "OSS-MULTI";
@@ -55,7 +56,7 @@ OssMultiEngine :: OssMultiEngine()
buffersize = 0;
/* compute worst case buffer size */
- maxbuffersize = NUM_MIDI_PARTS * sizeof(int) * synth->buffersize * 2;
+ maxbuffersize = NUM_MIDI_PARTS * sizeof(int) * synth.buffersize * 2;
/* allocate buffer */
smps.ps32 = new int[maxbuffersize / sizeof(int)];
memset(smps.ps32, 0, maxbuffersize);
@@ -118,19 +119,19 @@ OssMultiEngine :: openAudio()
}
channels = x;
- snd_samplerate = synth->samplerate;
+ snd_samplerate = synth.samplerate;
ioctl(handle, SNDCTL_DSP_SPEED, &snd_samplerate);
- if (snd_samplerate != (int)synth->samplerate) {
+ if (snd_samplerate != (int)synth.samplerate) {
cerr << "ERROR - Cannot set samplerate for "
<< device << ". " << snd_samplerate
- << " != " << synth->samplerate << endl;
+ << " != " << synth.samplerate << endl;
goto error;
}
/* compute buffer size for 16-bit samples */
- buffersize = 2 * synth->buffersize * channels;
+ buffersize = 2 * synth.buffersize * channels;
if (is32bit)
buffersize *= 2;
@@ -232,7 +233,7 @@ OssMultiEngine :: audioThreadCb()
Part *part = middleware->spawnMaster()->part[x / 2];
if (is32bit) {
- for (y = 0; y != synth->buffersize; y++) {
+ for (y = 0; y != synth.buffersize; y++) {
l = part->partoutl[y];
if (l < -1.0f)
l = -1.0f;
@@ -247,7 +248,7 @@ OssMultiEngine :: audioThreadCb()
smps.ps32[y * channels + x + 1] = (int)(r * 2147483647.0f);
}
} else {
- for (y = 0; y != synth->buffersize; y++) {
+ for (y = 0; y != synth.buffersize; y++) {
l = part->partoutl[y];
if (l < -1.0f)
l = -1.0f;
diff --git a/src/Nio/OssMultiEngine.h b/src/Nio/OssMultiEngine.h
@@ -29,7 +29,7 @@
class OssMultiEngine : public AudioOut
{
public:
- OssMultiEngine();
+ OssMultiEngine(const SYNTH_T &synth);
~OssMultiEngine();
bool Start();
diff --git a/src/Nio/OutMgr.cpp b/src/Nio/OutMgr.cpp
@@ -12,26 +12,26 @@
using namespace std;
-OutMgr &OutMgr::getInstance()
+OutMgr &OutMgr::getInstance(const SYNTH_T *synth)
{
- static OutMgr instance;
+ static OutMgr instance(synth);
return instance;
}
-OutMgr::OutMgr()
- :wave(new WavEngine()),
+OutMgr::OutMgr(const SYNTH_T *synth_)
+ :wave(new WavEngine(*synth_)),
priBuf(new float[4096],
new float[4096]), priBuffCurrent(priBuf),
- master(NULL)
+ master(NULL), stales(0), synth(*synth_)
{
+ assert(synth_);
currentOut = NULL;
- stales = 0;
//init samples
- outr = new float[synth->buffersize];
- outl = new float[synth->buffersize];
- memset(outl, 0, synth->bufferbytes);
- memset(outr, 0, synth->bufferbytes);
+ outr = new float[synth.buffersize];
+ outl = new float[synth.buffersize];
+ memset(outl, 0, synth.bufferbytes);
+ memset(outr, 0, synth.bufferbytes);
}
OutMgr::~OutMgr()
@@ -60,7 +60,7 @@ const Stereo<float *> OutMgr::tick(unsigned int frameSize)
int i=0;
while(frameSize > storedSmps()) {
if(!midi.empty()) {
- midi.flush(i*synth->buffersize, (i+1)*synth->buffersize);
+ midi.flush(i*synth.buffersize, (i+1)*synth.buffersize);
}
master->AudioOut(outl, outr);
addSmps(outl, outr);
@@ -143,27 +143,27 @@ static size_t resample(float *dest,
void OutMgr::addSmps(float *l, float *r)
{
//allow wave file to syphon off stream
- wave->push(Stereo<float *>(l, r), synth->buffersize);
+ wave->push(Stereo<float *>(l, r), synth.buffersize);
const int s_out = currentOut->getSampleRate(),
- s_sys = synth->samplerate;
+ s_sys = synth.samplerate;
if(s_out != s_sys) { //we need to resample
const size_t steps = resample(priBuffCurrent.l,
l,
s_sys,
s_out,
- synth->buffersize);
- resample(priBuffCurrent.r, r, s_sys, s_out, synth->buffersize);
+ synth.buffersize);
+ resample(priBuffCurrent.r, r, s_sys, s_out, synth.buffersize);
priBuffCurrent.l += steps;
priBuffCurrent.r += steps;
}
else { //just copy the samples
- memcpy(priBuffCurrent.l, l, synth->bufferbytes);
- memcpy(priBuffCurrent.r, r, synth->bufferbytes);
- priBuffCurrent.l += synth->buffersize;
- priBuffCurrent.r += synth->buffersize;
+ memcpy(priBuffCurrent.l, l, synth.bufferbytes);
+ memcpy(priBuffCurrent.r, r, synth.bufferbytes);
+ priBuffCurrent.l += synth.buffersize;
+ priBuffCurrent.r += synth.buffersize;
}
}
diff --git a/src/Nio/OutMgr.h b/src/Nio/OutMgr.h
@@ -8,10 +8,11 @@
class AudioOut;
+struct SYNTH_T;
class OutMgr
{
public:
- static OutMgr &getInstance();
+ static OutMgr &getInstance(const SYNTH_T *synth=NULL);
~OutMgr();
/**Execute a tick*/
@@ -44,7 +45,7 @@ class OutMgr
void setMaster(class Master *master_);
void applyOscEventRt(const char *msg);
private:
- OutMgr();
+ OutMgr(const SYNTH_T *synth);
void addSmps(float *l, float *r);
unsigned int storedSmps() const {return priBuffCurrent.l - priBuf.l; }
void removeStaleSmps();
@@ -62,6 +63,7 @@ class OutMgr
class Master *master;
int stales;
+ const SYNTH_T &synth;
};
#endif
diff --git a/src/Nio/PaEngine.cpp b/src/Nio/PaEngine.cpp
@@ -25,8 +25,8 @@
using namespace std;
-PaEngine::PaEngine()
- :stream(NULL)
+PaEngine::PaEngine(const SYNTH_T &synth)
+ :AudioOut(synth), stream(NULL)
{
name = "PA";
}
@@ -60,8 +60,8 @@ bool PaEngine::Start()
Pa_OpenStream(&stream,
NULL,
&outputParameters,
- synth->samplerate,
- synth->buffersize,
+ synth.samplerate,
+ synth.buffersize,
0,
PAprocess,
(void *) this);
diff --git a/src/Nio/PaEngine.h b/src/Nio/PaEngine.h
@@ -30,7 +30,7 @@
class PaEngine:public AudioOut
{
public:
- PaEngine();
+ PaEngine(const SYNTH_T &synth);
~PaEngine();
bool Start();
diff --git a/src/Nio/WavEngine.cpp b/src/Nio/WavEngine.cpp
@@ -25,8 +25,8 @@
using namespace std;
-WavEngine::WavEngine()
- :AudioOut(), file(NULL), buffer(synth->samplerate * 4), pThread(NULL)
+WavEngine::WavEngine(const SYNTH_T &synth_)
+ :AudioOut(synth_), file(NULL), buffer(synth.samplerate * 4), pThread(NULL)
{
work.init(PTHREAD_PROCESS_PRIVATE, 0);
}
@@ -110,10 +110,10 @@ void *WavEngine::_AudioThread(void *arg)
void *WavEngine::AudioThread()
{
- short *recordbuf_16bit = new short[2 * synth->buffersize];
+ short *recordbuf_16bit = new short[2 * synth.buffersize];
while(!work.wait() && pThread) {
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float left = 0.0f, right = 0.0f;
buffer.pop(left);
buffer.pop(right);
@@ -124,7 +124,7 @@ void *WavEngine::AudioThread()
-32768,
32767);
}
- file->writeStereoSamples(synth->buffersize, recordbuf_16bit);
+ file->writeStereoSamples(synth.buffersize, recordbuf_16bit);
}
delete[] recordbuf_16bit;
diff --git a/src/Nio/WavEngine.h b/src/Nio/WavEngine.h
@@ -32,7 +32,7 @@ class WavFile;
class WavEngine:public AudioOut
{
public:
- WavEngine();
+ WavEngine(const SYNTH_T &synth);
~WavEngine();
bool openAudio();
diff --git a/src/Output/DSSIaudiooutput.cpp b/src/Output/DSSIaudiooutput.cpp
@@ -585,7 +585,6 @@ DSSIaudiooutput *DSSIaudiooutput::getInstance(LADSPA_Handle instance)
return (DSSIaudiooutput *)(instance);
}
-SYNTH_T *synth;
/**
* The private sole constructor for the DSSIaudiooutput class.
@@ -596,8 +595,8 @@ SYNTH_T *synth;
*/
DSSIaudiooutput::DSSIaudiooutput(unsigned long sampleRate)
{
- synth = new SYNTH_T;
- synth->samplerate = sampleRate;
+ SYNTH_T synth;
+ synth.samplerate = sampleRate;
this->sampleRate = sampleRate;
this->banksInited = false;
@@ -605,12 +604,12 @@ DSSIaudiooutput::DSSIaudiooutput(unsigned long sampleRate)
config.init();
sprng(time(NULL));
- denormalkillbuf = new float [synth->buffersize];
- for(int i = 0; i < synth->buffersize; i++)
+ denormalkillbuf = new float [synth.buffersize];
+ for(int i = 0; i < synth.buffersize; i++)
denormalkillbuf[i] = (RND - 0.5f) * 1e-16;
- synth->alias();
- middleware = new MiddleWare();
+ synth.alias();
+ middleware = new MiddleWare(synth);
initBanks();
loadThread = new std::thread([this]() {
while(middleware) {
diff --git a/src/Params/ADnoteParameters.cpp b/src/Params/ADnoteParameters.cpp
@@ -276,7 +276,7 @@ const Ports &ADnoteGlobalParam::ports = globalPorts;
int ADnote_unison_sizes[] =
{1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 40, 50, 0};
-ADnoteParameters::ADnoteParameters(FFTwrapper *fft_)
+ADnoteParameters::ADnoteParameters(const SYNTH_T &synth, FFTwrapper *fft_)
:PresetsArray()
{
setpresettype("Padsynth");
@@ -284,7 +284,7 @@ ADnoteParameters::ADnoteParameters(FFTwrapper *fft_)
for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice)
- EnableVoice(nvoice);
+ EnableVoice(synth, nvoice);
defaults();
}
@@ -429,15 +429,15 @@ void ADnoteVoiceParam::defaults()
/*
* Init the voice parameters
*/
-void ADnoteParameters::EnableVoice(int nvoice)
+void ADnoteParameters::EnableVoice(const SYNTH_T &synth, int nvoice)
{
- VoicePar[nvoice].enable(fft, GlobalPar.Reson);
+ VoicePar[nvoice].enable(synth, fft, GlobalPar.Reson);
}
-void ADnoteVoiceParam::enable(FFTwrapper *fft, Resonance *Reson)
+void ADnoteVoiceParam::enable(const SYNTH_T &synth, FFTwrapper *fft, Resonance *Reson)
{
- OscilSmp = new OscilGen(fft, Reson);
- FMSmp = new OscilGen(fft, NULL);
+ OscilSmp = new OscilGen(synth, fft, Reson);
+ FMSmp = new OscilGen(synth, fft, NULL);
AmpEnvelope = new EnvelopeParams(64, 1);
AmpEnvelope->ADSRinit_dB(0, 100, 127, 100);
diff --git a/src/Params/ADnoteParameters.h b/src/Params/ADnoteParameters.h
@@ -117,7 +117,7 @@ struct ADnoteVoiceParam {
void add2XML(XMLwrapper *xml, bool fmoscilused);
void paste(ADnoteVoiceParam &p);
void defaults(void);
- void enable(FFTwrapper *fft, Resonance *Reson);
+ void enable(const SYNTH_T &synth, FFTwrapper *fft, Resonance *Reson);
void kill(void);
float getUnisonFrequencySpreadCents(void) const;
/** If the voice is enabled */
@@ -289,7 +289,7 @@ struct ADnoteVoiceParam {
class ADnoteParameters:public PresetsArray
{
public:
- ADnoteParameters(FFTwrapper *fft_);
+ ADnoteParameters(const SYNTH_T &synth, FFTwrapper *fft_);
~ADnoteParameters();
ADnoteGlobalParam GlobalPar;
@@ -313,7 +313,7 @@ class ADnoteParameters:public PresetsArray
void getfromXMLsection(XMLwrapper *xml, int n);
private:
- void EnableVoice(int nvoice);
+ void EnableVoice(const SYNTH_T &synth, int nvoice);
void KillVoice(int nvoice);
FFTwrapper *fft;
};
diff --git a/src/Params/Controller.cpp b/src/Params/Controller.cpp
@@ -60,12 +60,20 @@ const rtosc::Ports Controller::ports = {
};
-Controller::Controller()
+Controller::Controller(const SYNTH_T &synth_)
+ :synth(synth_)
{
defaults();
resetall();
}
+Controller &Controller::operator=(const Controller &c)
+{
+ //just pretend that undefined behavior doesn't exist...
+ memcpy(this, &c, sizeof(Controller));
+ return *this;
+}
+
Controller::~Controller()
{}
@@ -284,7 +292,7 @@ int Controller::initportamento(float oldfreq,
//printf("%f->%f : Time %f\n",oldfreq,newfreq,portamentotime);
- portamento.dx = synth->buffersize_f / (portamentotime * synth->samplerate_f);
+ portamento.dx = synth.buffersize_f / (portamentotime * synth.samplerate_f);
portamento.origfreqrap = oldfreq / newfreq;
float tmprap = ((portamento.origfreqrap > 1.0f) ?
diff --git a/src/Params/Controller.h b/src/Params/Controller.h
@@ -30,7 +30,8 @@
class Controller
{
public:
- Controller();
+ Controller(const SYNTH_T &synth);
+ Controller&operator=(const Controller &c);
~Controller();
void resetall();
@@ -215,6 +216,7 @@ class Controller
static const rtosc::Ports ports;
private:
+ const SYNTH_T &synth;
};
#endif
diff --git a/src/Params/FilterParams.cpp b/src/Params/FilterParams.cpp
@@ -282,85 +282,6 @@ float FilterParams::getfreqpos(float freq)
return (logf(freq) - logf(getfreqx(0.0f))) / logf(2.0f) / getoctavesfreq();
}
-
-/*
- * Get the freq. response of the formant filter
- */
-void FilterParams::formantfilterH(int nvowel, int nfreqs, float *freqs)
-{
- float c[3], d[3];
-
- for(int i = 0; i < nfreqs; ++i)
- freqs[i] = 0.0f;
-
- //for each formant...
- for(int nformant = 0; nformant < Pnumformants; ++nformant) {
- //compute formant parameters(frequency,amplitude,etc.)
- const float filter_freq = getformantfreq(Pvowels[nvowel].formants[nformant].freq);
- float filter_q = getformantq(Pvowels[nvowel].formants[nformant].q) * getq();
- if(Pstages > 0)
- filter_q = (filter_q > 1.0f ? powf(filter_q, 1.0f / (Pstages + 1)) : filter_q);
-
- const float filter_amp = getformantamp(Pvowels[nvowel].formants[nformant].amp);
-
-
- if(filter_freq <= (synth->samplerate / 2 - 100.0f)) {
- const float omega = 2 * PI * filter_freq / synth->samplerate_f;
- const float sn = sinf(omega);
- const float cs = cosf(omega);
- const float alpha = sn / (2 * filter_q);
- const float tmp = 1 + alpha;
- c[0] = alpha / tmp *sqrt(filter_q + 1);
- c[1] = 0;
- c[2] = -alpha / tmp *sqrt(filter_q + 1);
- d[1] = -2 * cs / tmp * (-1);
- d[2] = (1 - alpha) / tmp * (-1);
- }
- else
- continue;
-
-
- for(int i = 0; i < nfreqs; ++i) {
- const float freq = getfreqx(i / (float) nfreqs);
-
- //Discard frequencies above nyquist rate
- if(freq > synth->samplerate / 2) {
- for(int tmp = i; tmp < nfreqs; ++tmp)
- freqs[tmp] = 0.0f;
- break;
- }
-
- //Convert to normalized frequency
- const float fr = freq / synth->samplerate * PI * 2.0f;
-
- //Evaluate Complex domain ratio
- float x = c[0], y = 0.0f;
- for(int n = 1; n < 3; ++n) {
- x += cosf(n * fr) * c[n];
- y -= sinf(n * fr) * c[n];
- }
- float h = x * x + y * y;
- x = 1.0f;
- y = 0.0f;
- for(int n = 1; n < 3; ++n) {
- x -= cosf(n * fr) * d[n];
- y += sinf(n * fr) * d[n];
- }
- h = h / (x * x + y * y);
-
- freqs[i] += powf(h, (Pstages + 1.0f) / 2.0f) * filter_amp;
- }
- }
-
- //Convert to logarithmic data ignoring points that are too small
- for(int i = 0; i < nfreqs; ++i) {
- if(freqs[i] > 0.000000001f)
- freqs[i] = rap2dB(freqs[i]) + getgain();
- else
- freqs[i] = -90.0f;
- }
-}
-
/*
* Transforms a parameter to the real value
*/
diff --git a/src/Params/FilterParams.h b/src/Params/FilterParams.h
@@ -85,8 +85,6 @@ class FilterParams:public PresetsArray
float getfreqpos(float freq);
float getfreqx(float x);
- void formantfilterH(int nvowel, int nfreqs, float *freqs); //used by UI
-
float getformantfreq(unsigned char freq);
float getformantamp(unsigned char amp);
float getformantq(unsigned char q);
diff --git a/src/Params/PADnoteParameters.cpp b/src/Params/PADnoteParameters.cpp
@@ -125,7 +125,7 @@ static const rtosc::Ports localPorts =
{"nhr:", rProp(non-realtime) rDoc("Returns the harmonic shifts"),
NULL, [](const char *, rtosc::RtData &d) {
PADnoteParameters *p = ((PADnoteParameters*)d.obj);
- const unsigned n = synth->oscilsize / 2;
+ const unsigned n = p->synth.oscilsize / 2;
float *tmp = new float[n];
for(unsigned i=1; i<n; ++i)
tmp[i] = p->getNhr(i);
@@ -189,14 +189,15 @@ static const rtosc::Ports localPorts =
const rtosc::Ports &PADnoteParameters::ports = localPorts;
-PADnoteParameters::PADnoteParameters(FFTwrapper *fft_):Presets()
+PADnoteParameters::PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_)
+ :Presets(), synth(synth_)
{
setpresettype("Ppadsynth");
fft = fft_;
resonance = new Resonance();
- oscilgen = new OscilGen(fft_, resonance);
+ oscilgen = new OscilGen(synth, fft_, resonance);
oscilgen->ADvsPAD = true;
FreqEnvelope = new EnvelopeParams(0, 0);
@@ -586,23 +587,23 @@ void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,
int profilesize,
float bwadjust)
{
- float harmonics[synth->oscilsize];
+ float harmonics[synth.oscilsize];
memset(spectrum, 0, sizeof(float) * size);
- memset(harmonics, 0, sizeof(float) * synth->oscilsize);
+ memset(harmonics, 0, sizeof(float) * synth.oscilsize);
//get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
oscilgen->get(harmonics, basefreq, false);
//normalize
- normalize_max(harmonics, synth->oscilsize / 2);
+ normalize_max(harmonics, synth.oscilsize / 2);
//Constants across harmonics
const float power = Pbwscale_translate(Pbwscale);
const float bandwidthcents = setPbandwidth(Pbandwidth);
- for(int nh = 1; nh < synth->oscilsize / 2; ++nh) { //for each harmonic
+ for(int nh = 1; nh < synth.oscilsize / 2; ++nh) { //for each harmonic
const float realfreq = getNhr(nh) * basefreq;
- if(realfreq > synth->samplerate_f * 0.49999f)
+ if(realfreq > synth.samplerate_f * 0.49999f)
break;
if(realfreq < 20.0f)
break;
@@ -613,7 +614,7 @@ void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,
const float bw =
((powf(2.0f, bandwidthcents / 1200.0f) - 1.0f) * basefreq / bwadjust)
* powf(realfreq / basefreq, power);
- const int ibw = (int)((bw / (synth->samplerate_f * 0.5f) * size)) + 1;
+ const int ibw = (int)((bw / (synth.samplerate_f * 0.5f) * size)) + 1;
float amp = harmonics[nh - 1];
if(resonance->Penabled)
@@ -623,7 +624,7 @@ void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,
const float rap = sqrt((float)profilesize / (float)ibw);
const int cfreq =
(int) (realfreq
- / (synth->samplerate_f * 0.5f) * size) - ibw / 2;
+ / (synth.samplerate_f * 0.5f) * size) - ibw / 2;
for(int i = 0; i < ibw; ++i) {
const int src = i * rap * rap;
const int spfreq = i + cfreq;
@@ -636,7 +637,7 @@ void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,
}
else { //if the bandwidth is smaller than the profilesize
const float rap = sqrt((float)ibw / (float)profilesize);
- const float ibasefreq = realfreq / (synth->samplerate_f * 0.5f) * size;
+ const float ibasefreq = realfreq / (synth.samplerate_f * 0.5f) * size;
for(int i = 0; i < profilesize; ++i) {
const float idfreq = (i / (float)profilesize - 0.5f) * ibw;
const int spfreq = (int) (idfreq + ibasefreq);
@@ -660,21 +661,21 @@ void PADnoteParameters::generatespectrum_otherModes(float *spectrum,
int size,
float basefreq)
{
- float harmonics[synth->oscilsize];
+ float harmonics[synth.oscilsize];
memset(spectrum, 0, sizeof(float) * size);
- memset(harmonics, 0, sizeof(float) * synth->oscilsize);
+ memset(harmonics, 0, sizeof(float) * synth.oscilsize);
//get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
oscilgen->get(harmonics, basefreq, false);
//normalize
- normalize_max(harmonics, synth->oscilsize / 2);
+ normalize_max(harmonics, synth.oscilsize / 2);
- for(int nh = 1; nh < synth->oscilsize / 2; ++nh) { //for each harmonic
+ for(int nh = 1; nh < synth.oscilsize / 2; ++nh) { //for each harmonic
const float realfreq = getNhr(nh) * basefreq;
//take care of interpolation if frequency decreases
- if(realfreq > synth->samplerate_f * 0.49999f)
+ if(realfreq > synth.samplerate_f * 0.49999f)
break;
if(realfreq < 20.0f)
break;
@@ -683,7 +684,7 @@ void PADnoteParameters::generatespectrum_otherModes(float *spectrum,
float amp = harmonics[nh - 1];
if(resonance->Penabled)
amp *= resonance->getfreqresponse(realfreq);
- const int cfreq = realfreq / (synth->samplerate_f * 0.5f) * size;
+ const int cfreq = realfreq / (synth.samplerate_f * 0.5f) * size;
spectrum[cfreq] = amp + 1e-9;
}
@@ -844,7 +845,7 @@ void PADnoteParameters::export2wav(std::string basefilename)
char tmpstr[20];
snprintf(tmpstr, 20, "_%02d", k + 1);
std::string filename = basefilename + std::string(tmpstr) + ".wav";
- WavFile wav(filename, synth->samplerate, 1);
+ WavFile wav(filename, synth.samplerate, 1);
if(wav.good()) {
int nsmps = sample[k].size;
short int *smps = new short int[nsmps];
diff --git a/src/Params/PADnoteParameters.h b/src/Params/PADnoteParameters.h
@@ -42,7 +42,7 @@
class PADnoteParameters:public Presets
{
public:
- PADnoteParameters(FFTwrapper *fft_);
+ PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_);
~PADnoteParameters();
void defaults();
@@ -181,6 +181,8 @@ class PADnoteParameters:public Presets
void deletesample(int n);
FFTwrapper *fft;
+ public:
+ const SYNTH_T &synth;
};
diff --git a/src/Synth/ADnote.cpp b/src/Synth/ADnote.cpp
@@ -35,14 +35,13 @@
#include "OscilGen.h"
#include "ADnote.h"
-
ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars)
:SynthNote(spars), pars(*pars_)
{
- tmpwavel = memory.valloc<float>(synth->buffersize);
- tmpwaver = memory.valloc<float>(synth->buffersize);
- bypassl = memory.valloc<float>(synth->buffersize);
- bypassr = memory.valloc<float>(synth->buffersize);
+ tmpwavel = memory.valloc<float>(synth.buffersize);
+ tmpwaver = memory.valloc<float>(synth.buffersize);
+ bypassl = memory.valloc<float>(synth.buffersize);
+ bypassr = memory.valloc<float>(synth.buffersize);
ADnoteParameters &pars = *pars_;
portamento = spars.portamento;
@@ -82,7 +81,7 @@ ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars)
powf(10, 3.0f * pars.GlobalPar.PPunchTime / 127.0f) / 10000.0f; //0.1f .. 100 ms
float stretch = powf(440.0f / spars.frequency,
pars.GlobalPar.PPunchStretch / 64.0f);
- NoteGlobalPar.Punch.dt = 1.0f / (time * synth->samplerate_f * stretch);
+ NoteGlobalPar.Punch.dt = 1.0f / (time * synth.samplerate_f * stretch);
}
else
NoteGlobalPar.Punch.Enabled = 0;
@@ -165,7 +164,7 @@ ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars)
unison_vibratto[nvoice].amplitude =
(unison_real_spread - 1.0f) * unison_vibratto_a;
- float increments_per_second = synth->samplerate_f / synth->buffersize_f;
+ float increments_per_second = synth.samplerate_f / synth.buffersize_f;
const float vib_speed = pars.VoicePar[nvoice].Unison_vibratto_speed / 127.0f;
float vibratto_base_period = 0.25f * powf(2.0f, (1.0f - vib_speed) * 4.0f);
for(int k = 0; k < unison; ++k) {
@@ -265,7 +264,7 @@ ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars)
//the extra points contains the first point
NoteVoicePar[nvoice].OscilSmp =
- memory.valloc<float>(synth->oscilsize + OSCIL_SMP_EXTRA_SAMPLES);
+ memory.valloc<float>(synth.oscilsize + OSCIL_SMP_EXTRA_SAMPLES);
//Get the voice's oscil or external's voice oscil
int vc = nvoice;
@@ -280,21 +279,21 @@ ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars)
//I store the first elments to the last position for speedups
for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
- NoteVoicePar[nvoice].OscilSmp[synth->oscilsize
+ NoteVoicePar[nvoice].OscilSmp[synth.oscilsize
+ i] =
NoteVoicePar[nvoice].OscilSmp[i];
oscposhi_start +=
(int)((pars.VoicePar[nvoice].Poscilphase
- - 64.0f) / 128.0f * synth->oscilsize + synth->oscilsize * 4);
- oscposhi_start %= synth->oscilsize;
+ - 64.0f) / 128.0f * synth.oscilsize + synth.oscilsize * 4);
+ oscposhi_start %= synth.oscilsize;
for(int k = 0; k < unison; ++k) {
oscposhi[nvoice][k] = oscposhi_start;
//put random starting point for other subvoices
oscposhi_start =
(int)(RND * pars.VoicePar[nvoice].Unison_phase_randomness /
- 127.0f * (synth->oscilsize - 1));
+ 127.0f * (synth.oscilsize - 1));
}
NoteVoicePar[nvoice].FreqLfo = NULL;
@@ -380,7 +379,7 @@ ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars)
NoteVoicePar[nvoice].DelayTicks =
(int)((expf(pars.VoicePar[nvoice].PDelay / 127.0f
* logf(50.0f))
- - 1.0f) / synth->buffersize_f / 10.0f * synth->samplerate_f);
+ - 1.0f) / synth.buffersize_f / 10.0f * synth.samplerate_f);
}
max_unison = 1;
@@ -391,8 +390,8 @@ ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars)
tmpwave_unison = memory.valloc<float*>(max_unison);
for(int k = 0; k < max_unison; ++k) {
- tmpwave_unison[k] = memory.valloc<float>(synth->buffersize);
- memset(tmpwave_unison[k], 0, synth->bufferbytes);
+ tmpwave_unison[k] = memory.valloc<float>(synth.buffersize);
+ memset(tmpwave_unison[k], 0, synth.bufferbytes);
}
initparameters();
@@ -490,7 +489,7 @@ void ADnote::legatonote(LegatoParams lpars)
//I store the first elments to the last position for speedups
for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
- NoteVoicePar[nvoice].OscilSmp[synth->oscilsize
+ NoteVoicePar[nvoice].OscilSmp[synth.oscilsize
+ i] =
NoteVoicePar[nvoice].OscilSmp[i];
@@ -541,7 +540,7 @@ void ADnote::legatonote(LegatoParams lpars)
NoteVoicePar[nvoice].DelayTicks =
(int)((expf(pars.VoicePar[nvoice].PDelay / 127.0f
* logf(50.0f))
- - 1.0f) / synth->buffersize_f / 10.0f * synth->samplerate_f);
+ - 1.0f) / synth.buffersize_f / 10.0f * synth.samplerate_f);
}
/// initparameters();
@@ -623,7 +622,7 @@ void ADnote::legatonote(LegatoParams lpars)
pars.VoicePar[vc].FMSmp->newrandseed(prng());
for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
- NoteVoicePar[nvoice].FMSmp[synth->oscilsize + i] =
+ NoteVoicePar[nvoice].FMSmp[synth.oscilsize + i] =
NoteVoicePar[nvoice].FMSmp[i];
}
@@ -667,7 +666,7 @@ void ADnote::KillVoice(int nvoice)
memory.devalloc(unison_vibratto[nvoice].step);
memory.devalloc(unison_vibratto[nvoice].position);
- NoteVoicePar[nvoice].kill(memory);
+ NoteVoicePar[nvoice].kill(memory, synth);
}
/*
@@ -711,7 +710,7 @@ void ADnote::initparameters()
//ADnoteParameters &pars = *partparams;
// Global Parameters
- NoteGlobalPar.initparameters(pars.GlobalPar,
+ NoteGlobalPar.initparameters(pars.GlobalPar, synth,
memory, basefreq, velocity,
stereo);
@@ -748,34 +747,36 @@ void ADnote::initparameters()
newamplitude[nvoice] = 1.0f;
if(param.PAmpEnvelopeEnabled) {
- vce.AmpEnvelope = memory.alloc<Envelope>(*param.AmpEnvelope, basefreq);
+ vce.AmpEnvelope = memory.alloc<Envelope>(*param.AmpEnvelope, basefreq, synth.dt());
vce.AmpEnvelope->envout_dB(); //discard the first envelope sample
newamplitude[nvoice] *= vce.AmpEnvelope->envout_dB();
}
if(param.PAmpLfoEnabled) {
- vce.AmpLfo = memory.alloc<LFO>(*param.AmpLfo, basefreq);
+ vce.AmpLfo = memory.alloc<LFO>(*param.AmpLfo, basefreq, synth.dt());
newamplitude[nvoice] *= vce.AmpLfo->amplfoout();
}
/* Voice Frequency Parameters Init */
if(param.PFreqEnvelopeEnabled)
- vce.FreqEnvelope = memory.alloc<Envelope>(*param.FreqEnvelope, basefreq);
+ vce.FreqEnvelope = memory.alloc<Envelope>(*param.FreqEnvelope, basefreq, synth.dt());
if(param.PFreqLfoEnabled)
- vce.FreqLfo = memory.alloc<LFO>(*param.FreqLfo, basefreq);
+ vce.FreqLfo = memory.alloc<LFO>(*param.FreqLfo, basefreq, synth.dt());
/* Voice Filter Parameters Init */
if(param.PFilterEnabled != 0) {
- vce.VoiceFilterL = Filter::generate(memory, param.VoiceFilter);
- vce.VoiceFilterR = Filter::generate(memory, param.VoiceFilter);
+ vce.VoiceFilterL = Filter::generate(memory, param.VoiceFilter,
+ synth.samplerate, synth.buffersize);
+ vce.VoiceFilterR = Filter::generate(memory, param.VoiceFilter,
+ synth.samplerate, synth.buffersize);
}
if(param.PFilterEnvelopeEnabled)
- vce.FilterEnvelope = memory.alloc<Envelope>(*param.FilterEnvelope, basefreq);
+ vce.FilterEnvelope = memory.alloc<Envelope>(*param.FilterEnvelope, basefreq, synth.dt());
if(param.PFilterLfoEnabled)
- vce.FilterLfo = memory.alloc<LFO>(*param.FilterLfo, basefreq);
+ vce.FilterLfo = memory.alloc<LFO>(*param.FilterLfo, basefreq, synth.dt());
vce.FilterFreqTracking =
param.VoiceFilter->getfreqtracking(basefreq);
@@ -783,7 +784,7 @@ void ADnote::initparameters()
/* Voice Modulation Parameters Init */
if((vce.FMEnabled != NONE) && (vce.FMVoice < 0)) {
param.FMSmp->newrandseed(prng());
- vce.FMSmp = memory.valloc<float>(synth->oscilsize + OSCIL_SMP_EXTRA_SAMPLES);
+ vce.FMSmp = memory.valloc<float>(synth.oscilsize + OSCIL_SMP_EXTRA_SAMPLES);
//Perform Anti-aliasing only on MORPH or RING MODULATION
@@ -804,28 +805,28 @@ void ADnote::initparameters()
oscposhiFM[nvoice][k] = (oscposhi[nvoice][k]
+ pars.VoicePar[vc].FMSmp->get(
vce.FMSmp, tmp))
- % synth->oscilsize;
+ % synth.oscilsize;
for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
- vce.FMSmp[synth->oscilsize + i] = vce.FMSmp[i];
+ vce.FMSmp[synth.oscilsize + i] = vce.FMSmp[i];
int oscposhiFM_add =
(int)((param.PFMoscilphase
- - 64.0f) / 128.0f * synth->oscilsize
- + synth->oscilsize * 4);
+ - 64.0f) / 128.0f * synth.oscilsize
+ + synth.oscilsize * 4);
for(int k = 0; k < unison_size[nvoice]; ++k) {
oscposhiFM[nvoice][k] += oscposhiFM_add;
- oscposhiFM[nvoice][k] %= synth->oscilsize;
+ oscposhiFM[nvoice][k] %= synth.oscilsize;
}
}
if(param.PFMFreqEnvelopeEnabled)
- vce.FMFreqEnvelope = memory.alloc<Envelope>(*param.FMFreqEnvelope, basefreq);
+ vce.FMFreqEnvelope = memory.alloc<Envelope>(*param.FMFreqEnvelope, basefreq, synth.dt());
FMnewamplitude[nvoice] = vce.FMVolume * ctl.fmamp.relamp;
if(param.PFMAmpEnvelopeEnabled ) {
vce.FMAmpEnvelope =
- memory.alloc<Envelope>(*param.FMAmpEnvelope, basefreq);
+ memory.alloc<Envelope>(*param.FMAmpEnvelope, basefreq, synth.dt());
FMnewamplitude[nvoice] *= vce.FMAmpEnvelope->envout_dB();
}
}
@@ -836,12 +837,12 @@ void ADnote::initparameters()
for(int i = nvoice + 1; i < NUM_VOICES; ++i)
if((NoteVoicePar[i].FMVoice == nvoice) && (tmp[i] == 0)) {
NoteVoicePar[nvoice].VoiceOut =
- memory.valloc<float>(synth->buffersize);
+ memory.valloc<float>(synth.buffersize);
tmp[i] = 1;
}
if(NoteVoicePar[nvoice].VoiceOut)
- memset(NoteVoicePar[nvoice].VoiceOut, 0, synth->bufferbytes);
+ memset(NoteVoicePar[nvoice].VoiceOut, 0, synth.bufferbytes);
}
}
@@ -888,9 +889,9 @@ void ADnote::setfreq(int nvoice, float in_freq)
{
for(int k = 0; k < unison_size[nvoice]; ++k) {
float freq = fabs(in_freq) * unison_freq_rap[nvoice][k];
- float speed = freq * synth->oscilsize_f / synth->samplerate_f;
- if(speed > synth->oscilsize_f)
- speed = synth->oscilsize_f;
+ float speed = freq * synth.oscilsize_f / synth.samplerate_f;
+ if(speed > synth.oscilsize_f)
+ speed = synth.oscilsize_f;
F2I(speed, oscfreqhi[nvoice][k]);
oscfreqlo[nvoice][k] = speed - floor(speed);
@@ -904,9 +905,9 @@ void ADnote::setfreqFM(int nvoice, float in_freq)
{
for(int k = 0; k < unison_size[nvoice]; ++k) {
float freq = fabs(in_freq) * unison_freq_rap[nvoice][k];
- float speed = freq * synth->oscilsize_f / synth->samplerate_f;
- if(speed > synth->samplerate_f)
- speed = synth->samplerate_f;
+ float speed = freq * synth.oscilsize_f / synth.samplerate_f;
+ if(speed > synth.samplerate_f)
+ speed = synth.samplerate_f;
F2I(speed, oscfreqhiFM[nvoice][k]);
oscfreqloFM[nvoice][k] = speed - floor(speed);
@@ -1070,7 +1071,7 @@ void ADnote::computecurrentparameters()
}
}
}
- time += synth->buffersize_f / synth->samplerate_f;
+ time += synth.buffersize_f / synth.samplerate_f;
}
@@ -1080,18 +1081,18 @@ void ADnote::computecurrentparameters()
inline void ADnote::fadein(float *smps) const
{
int zerocrossings = 0;
- for(int i = 1; i < synth->buffersize; ++i)
+ for(int i = 1; i < synth.buffersize; ++i)
if((smps[i - 1] < 0.0f) && (smps[i] > 0.0f))
zerocrossings++; //this is only the possitive crossings
- float tmp = (synth->buffersize_f - 1.0f) / (zerocrossings + 1) / 3.0f;
+ float tmp = (synth.buffersize_f - 1.0f) / (zerocrossings + 1) / 3.0f;
if(tmp < 8.0f)
tmp = 8.0f;
int n;
F2I(tmp, n); //how many samples is the fade-in
- if(n > synth->buffersize)
- n = synth->buffersize;
+ if(n > synth.buffersize)
+ n = synth.buffersize;
for(int i = 0; i < n; ++i) { //fade-in
float tmp = 0.5f - cosf((float)i / (float) n * PI) * 0.5f;
smps[i] *= tmp;
@@ -1125,12 +1126,12 @@ inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int nvoice)
float *smps = NoteVoicePar[nvoice].OscilSmp;
float *tw = tmpwave_unison[k];
assert(oscfreqlo[nvoice][k] < 1.0f);
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
tw[i] = (smps[poshi] * ((1<<24) - poslo) + smps[poshi + 1] * poslo)/(1.0f*(1<<24));
poslo += freqlo;
poshi += freqhi + (poslo>>24);
poslo &= 0xffffff;
- poshi &= synth->oscilsize - 1;
+ poshi &= synth.oscilsize - 1;
}
oscposhi[nvoice][k] = poshi;
oscposlo[nvoice][k] = poslo/(1.0f*(1<<24));
@@ -1142,7 +1143,7 @@ inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int nvoice)
/*
* Computes the Oscillator (Without Modulation) - CubicInterpolation
*
- The differences from the Linear are to little to deserve to be used. This is because I am using a large synth->oscilsize (>512)
+ The differences from the Linear are to little to deserve to be used. This is because I am using a large synth.oscilsize (>512)
inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){
int i,poshi;
float poslo;
@@ -1151,7 +1152,7 @@ inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){
poslo=oscposlo[nvoice];
float *smps=NoteVoicePar[nvoice].OscilSmp;
float xm1,x0,x1,x2,a,b,c;
- for (i=0;i<synth->buffersize;i++){
+ for (i=0;i<synth.buffersize;i++){
xm1=smps[poshi];
x0=smps[poshi+1];
x1=smps[poshi+2];
@@ -1168,7 +1169,7 @@ inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){
poshi++;
};
poshi+=oscfreqhi[nvoice];
- poshi&=synth->oscilsize-1;
+ poshi&=synth.oscilsize-1;
};
oscposhi[nvoice]=poshi;
oscposlo[nvoice]=poslo;
@@ -1190,11 +1191,11 @@ inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice)
int FMVoice = NoteVoicePar[nvoice].FMVoice;
for(int k = 0; k < unison_size[nvoice]; ++k) {
float *tw = tmpwave_unison[k];
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
FMnewamplitude[nvoice],
i,
- synth->buffersize);
+ synth.buffersize);
tw[i] = tw[i]
* (1.0f - amp) + amp * NoteVoicePar[FMVoice].VoiceOut[i];
}
@@ -1208,11 +1209,11 @@ inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice)
float freqloFM = oscfreqloFM[nvoice][k];
float *tw = tmpwave_unison[k];
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
FMnewamplitude[nvoice],
i,
- synth->buffersize);
+ synth.buffersize);
tw[i] = tw[i] * (1.0f - amp) + amp
* (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1 - posloFM)
+ NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM);
@@ -1222,7 +1223,7 @@ inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice)
poshiFM++;
}
poshiFM += freqhiFM;
- poshiFM &= synth->oscilsize - 1;
+ poshiFM &= synth.oscilsize - 1;
}
oscposhiFM[nvoice][k] = poshiFM;
oscposloFM[nvoice][k] = posloFM;
@@ -1243,11 +1244,11 @@ inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice)
// if I use VoiceOut[] as modullator
for(int k = 0; k < unison_size[nvoice]; ++k) {
float *tw = tmpwave_unison[k];
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
FMnewamplitude[nvoice],
i,
- synth->buffersize);
+ synth.buffersize);
int FMVoice = NoteVoicePar[nvoice].FMVoice;
tw[i] *= (1.0f - amp) + amp * NoteVoicePar[FMVoice].VoiceOut[i];
}
@@ -1260,11 +1261,11 @@ inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice)
float freqloFM = oscfreqloFM[nvoice][k];
float *tw = tmpwave_unison[k];
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
FMnewamplitude[nvoice],
i,
- synth->buffersize);
+ synth.buffersize);
tw[i] *= (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0f - posloFM)
+ NoteVoicePar[nvoice].FMSmp[poshiFM
+ 1] * posloFM) * amp
@@ -1275,7 +1276,7 @@ inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice)
poshiFM++;
}
poshiFM += freqhiFM;
- poshiFM &= synth->oscilsize - 1;
+ poshiFM &= synth.oscilsize - 1;
}
oscposhiFM[nvoice][k] = poshiFM;
oscposloFM[nvoice][k] = posloFM;
@@ -1293,7 +1294,7 @@ inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,
for(int k = 0; k < unison_size[nvoice]; ++k) {
float *tw = tmpwave_unison[k];
const float *smps = NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut;
- memcpy(tw, smps, synth->bufferbytes);
+ memcpy(tw, smps, synth.bufferbytes);
}
} else {
//Compute the modulator and store it in tmpwave_unison[][]
@@ -1305,7 +1306,7 @@ inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,
float *tw = tmpwave_unison[k];
const float *smps = NoteVoicePar[nvoice].FMSmp;
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
tw[i] = (smps[poshiFM] * ((1<<24) - posloFM)
+ smps[poshiFM + 1] * posloFM) / (1.0f*(1<<24));
posloFM += freqloFM;
@@ -1314,7 +1315,7 @@ inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,
poshiFM++;
}
poshiFM += freqhiFM;
- poshiFM &= synth->oscilsize - 1;
+ poshiFM &= synth.oscilsize - 1;
}
oscposhiFM[nvoice][k] = poshiFM;
oscposloFM[nvoice][k] = posloFM/((1<<24)*1.0f);
@@ -1325,16 +1326,16 @@ inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,
FMnewamplitude[nvoice])) {
for(int k = 0; k < unison_size[nvoice]; ++k) {
float *tw = tmpwave_unison[k];
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tw[i] *= INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
FMnewamplitude[nvoice],
i,
- synth->buffersize);
+ synth.buffersize);
}
} else {
for(int k = 0; k < unison_size[nvoice]; ++k) {
float *tw = tmpwave_unison[k];
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tw[i] *= FMnewamplitude[nvoice];
}
}
@@ -1342,23 +1343,23 @@ inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,
//normalize: makes all sample-rates, oscil_sizes to produce same sound
if(FMmode != 0) { //Frequency modulation
- const float normalize = synth->oscilsize_f / 262144.0f * 44100.0f
- / synth->samplerate_f;
+ const float normalize = synth.oscilsize_f / 262144.0f * 44100.0f
+ / synth.samplerate_f;
for(int k = 0; k < unison_size[nvoice]; ++k) {
float *tw = tmpwave_unison[k];
float fmold = FMoldsmp[nvoice][k];
- for(int i = 0; i < synth->buffersize; ++i) {
- fmold = fmod(fmold + tw[i] * normalize, synth->oscilsize);
+ for(int i = 0; i < synth.buffersize; ++i) {
+ fmold = fmod(fmold + tw[i] * normalize, synth.oscilsize);
tw[i] = fmold;
}
FMoldsmp[nvoice][k] = fmold;
}
}
else { //Phase modulation
- const float normalize = synth->oscilsize_f / 262144.0f;
+ const float normalize = synth.oscilsize_f / 262144.0f;
for(int k = 0; k < unison_size[nvoice]; ++k) {
float *tw = tmpwave_unison[k];
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tw[i] *= normalize;
}
}
@@ -1372,7 +1373,7 @@ inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,
int freqhi = oscfreqhi[nvoice][k];
int freqlo = oscfreqlo[nvoice][k] * (1<<24);
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
int FMmodfreqhi = 0;
F2I(tw[i], FMmodfreqhi);
float FMmodfreqlo = tw[i]-FMmodfreqhi;//fmod(tw[i] /*+ 0.0000000001f*/, 1.0f);
@@ -1387,7 +1388,7 @@ inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,
carposhi++;
carposlo &= 0xffffff;//fmod(carposlo, 1.0f);
}
- carposhi &= (synth->oscilsize - 1);
+ carposhi &= (synth.oscilsize - 1);
tw[i] = (smps[carposhi] * ((1<<24) - carposlo)
+ smps[carposhi + 1] * carposlo)/(1.0f*(1<<24));
@@ -1399,7 +1400,7 @@ inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,
}
poshi += freqhi;
- poshi &= synth->oscilsize - 1;
+ poshi &= synth.oscilsize - 1;
}
oscposhi[nvoice][k] = poshi;
oscposlo[nvoice][k] = (poslo)/((1<<24)*1.0f);
@@ -1420,7 +1421,7 @@ inline void ADnote::ComputeVoiceNoise(int nvoice)
{
for(int k = 0; k < unison_size[nvoice]; ++k) {
float *tw = tmpwave_unison[k];
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tw[i] = RND * 2.0f - 1.0f;
}
}
@@ -1433,14 +1434,14 @@ inline void ADnote::ComputeVoiceNoise(int nvoice)
*/
int ADnote::noteout(float *outl, float *outr)
{
- memcpy(outl, denormalkillbuf, synth->bufferbytes);
- memcpy(outr, denormalkillbuf, synth->bufferbytes);
+ memcpy(outl, denormalkillbuf, synth.bufferbytes);
+ memcpy(outr, denormalkillbuf, synth.bufferbytes);
if(NoteEnabled == OFF)
return 0;
- memset(bypassl, 0, synth->bufferbytes);
- memset(bypassr, 0, synth->bufferbytes);
+ memset(bypassl, 0, synth.bufferbytes);
+ memset(bypassr, 0, synth.bufferbytes);
computecurrentparameters();
for(unsigned nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
@@ -1472,9 +1473,9 @@ int ADnote::noteout(float *outl, float *outr)
//mix subvoices into voice
- memset(tmpwavel, 0, synth->bufferbytes);
+ memset(tmpwavel, 0, synth.bufferbytes);
if(stereo)
- memset(tmpwaver, 0, synth->bufferbytes);
+ memset(tmpwaver, 0, synth.bufferbytes);
for(int k = 0; k < unison_size[nvoice]; ++k) {
float *tw = tmpwave_unison[k];
if(stereo) {
@@ -1512,13 +1513,13 @@ int ADnote::noteout(float *outl, float *outr)
rvol = -rvol;
}
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tmpwavel[i] += tw[i] * lvol;
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tmpwaver[i] += tw[i] * rvol;
}
else
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tmpwavel[i] += tw[i];
}
@@ -1529,31 +1530,31 @@ int ADnote::noteout(float *outl, float *outr)
float newam = newamplitude[nvoice] * unison_amplitude;
if(ABOVE_AMPLITUDE_THRESHOLD(oldam, newam)) {
- int rest = synth->buffersize;
+ int rest = synth.buffersize;
//test if the amplitude if raising and the difference is high
if((newam > oldam) && ((newam - oldam) > 0.25f)) {
rest = 10;
- if(rest > synth->buffersize)
- rest = synth->buffersize;
- for(int i = 0; i < synth->buffersize - rest; ++i)
+ if(rest > synth.buffersize)
+ rest = synth.buffersize;
+ for(int i = 0; i < synth.buffersize - rest; ++i)
tmpwavel[i] *= oldam;
if(stereo)
- for(int i = 0; i < synth->buffersize - rest; ++i)
+ for(int i = 0; i < synth.buffersize - rest; ++i)
tmpwaver[i] *= oldam;
}
// Amplitude interpolation
for(int i = 0; i < rest; ++i) {
float amp = INTERPOLATE_AMPLITUDE(oldam, newam, i, rest);
- tmpwavel[i + (synth->buffersize - rest)] *= amp;
+ tmpwavel[i + (synth.buffersize - rest)] *= amp;
if(stereo)
- tmpwaver[i + (synth->buffersize - rest)] *= amp;
+ tmpwaver[i + (synth.buffersize - rest)] *= amp;
}
}
else {
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tmpwavel[i] *= newam;
if(stereo)
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tmpwaver[i] *= newam;
}
@@ -1575,11 +1576,11 @@ int ADnote::noteout(float *outl, float *outr)
//check if the amplitude envelope is finished, if yes, the voice will be fadeout
if(NoteVoicePar[nvoice].AmpEnvelope)
if(NoteVoicePar[nvoice].AmpEnvelope->finished()) {
- for(int i = 0; i < synth->buffersize; ++i)
- tmpwavel[i] *= 1.0f - (float)i / synth->buffersize_f;
+ for(int i = 0; i < synth.buffersize; ++i)
+ tmpwavel[i] *= 1.0f - (float)i / synth.buffersize_f;
if(stereo)
- for(int i = 0; i < synth->buffersize; ++i)
- tmpwaver[i] *= 1.0f - (float)i / synth->buffersize_f;
+ for(int i = 0; i < synth.buffersize; ++i)
+ tmpwaver[i] *= 1.0f - (float)i / synth.buffersize_f;
}
//the voice is killed later
@@ -1587,11 +1588,11 @@ int ADnote::noteout(float *outl, float *outr)
// Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
if(NoteVoicePar[nvoice].VoiceOut) {
if(stereo)
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
NoteVoicePar[nvoice].VoiceOut[i] = tmpwavel[i]
+ tmpwaver[i];
else //mono
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
NoteVoicePar[nvoice].VoiceOut[i] = tmpwavel[i];
}
@@ -1599,19 +1600,19 @@ int ADnote::noteout(float *outl, float *outr)
// Add the voice that do not bypass the filter to out
if(NoteVoicePar[nvoice].filterbypass == 0) { //no bypass
if(stereo)
- for(int i = 0; i < synth->buffersize; ++i) { //stereo
+ for(int i = 0; i < synth.buffersize; ++i) { //stereo
outl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume
* NoteVoicePar[nvoice].Panning * 2.0f;
outr[i] += tmpwaver[i] * NoteVoicePar[nvoice].Volume
* (1.0f - NoteVoicePar[nvoice].Panning) * 2.0f;
}
else
- for(int i = 0; i < synth->buffersize; ++i) //mono
+ for(int i = 0; i < synth.buffersize; ++i) //mono
outl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume;
}
else { //bypass the filter
if(stereo)
- for(int i = 0; i < synth->buffersize; ++i) { //stereo
+ for(int i = 0; i < synth.buffersize; ++i) { //stereo
bypassl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume
* NoteVoicePar[nvoice].Panning * 2.0f;
bypassr[i] += tmpwaver[i] * NoteVoicePar[nvoice].Volume
@@ -1619,7 +1620,7 @@ int ADnote::noteout(float *outl, float *outr)
- NoteVoicePar[nvoice].Panning) * 2.0f;
}
else
- for(int i = 0; i < synth->buffersize; ++i) //mono
+ for(int i = 0; i < synth.buffersize; ++i) //mono
bypassl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume;
}
// chech if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
@@ -1633,36 +1634,36 @@ int ADnote::noteout(float *outl, float *outr)
NoteGlobalPar.GlobalFilterL->filterout(&outl[0]);
if(stereo == 0) { //set the right channel=left channel
- memcpy(outr, outl, synth->bufferbytes);
- memcpy(bypassr, bypassl, synth->bufferbytes);
+ memcpy(outr, outl, synth.bufferbytes);
+ memcpy(bypassr, bypassl, synth.bufferbytes);
}
else
NoteGlobalPar.GlobalFilterR->filterout(&outr[0]);
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
outl[i] += bypassl[i];
outr[i] += bypassr[i];
}
if(ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude, globalnewamplitude))
// Amplitude Interpolation
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude,
globalnewamplitude,
i,
- synth->buffersize);
+ synth.buffersize);
outl[i] *= tmpvol * NoteGlobalPar.Panning;
outr[i] *= tmpvol * (1.0f - NoteGlobalPar.Panning);
}
else
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
outl[i] *= globalnewamplitude * NoteGlobalPar.Panning;
outr[i] *= globalnewamplitude * (1.0f - NoteGlobalPar.Panning);
}
//Apply the punch
if(NoteGlobalPar.Punch.Enabled != 0)
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float punchamp = NoteGlobalPar.Punch.initialvalue
* NoteGlobalPar.Punch.t + 1.0f;
outl[i] *= punchamp;
@@ -1682,8 +1683,8 @@ int ADnote::noteout(float *outl, float *outr)
// Check if the global amplitude is finished.
// If it does, disable the note
if(NoteGlobalPar.AmpEnvelope->finished()) {
- for(int i = 0; i < synth->buffersize; ++i) { //fade-out
- float tmp = 1.0f - (float)i / synth->buffersize_f;
+ for(int i = 0; i < synth.buffersize; ++i) { //fade-out
+ float tmp = 1.0f - (float)i / synth.buffersize_f;
outl[i] *= tmp;
outr[i] *= tmp;
}
@@ -1732,7 +1733,7 @@ void ADnote::Voice::releasekey()
FMAmpEnvelope->releasekey();
}
-void ADnote::Voice::kill(Allocator &memory)
+void ADnote::Voice::kill(Allocator &memory, const SYNTH_T &synth)
{
memory.devalloc(OscilSmp);
memory.dealloc(FreqEnvelope);
@@ -1750,7 +1751,7 @@ void ADnote::Voice::kill(Allocator &memory)
memory.devalloc(FMSmp);
if(VoiceOut)
- memset(VoiceOut, 0, synth->bufferbytes);
+ memset(VoiceOut, 0, synth.bufferbytes);
//the buffer can't be safely deleted as it may be
//an input to another voice
@@ -1770,27 +1771,30 @@ void ADnote::Global::kill(Allocator &memory)
}
void ADnote::Global::initparameters(const ADnoteGlobalParam ¶m,
+ const SYNTH_T &synth,
class Allocator &memory,
float basefreq, float velocity,
bool stereo)
{
- FreqEnvelope = memory.alloc<Envelope>(*param.FreqEnvelope, basefreq);
- FreqLfo = memory.alloc<LFO>(*param.FreqLfo, basefreq);
+ FreqEnvelope = memory.alloc<Envelope>(*param.FreqEnvelope, basefreq, synth.dt());
+ FreqLfo = memory.alloc<LFO>(*param.FreqLfo, basefreq, synth.dt());
- AmpEnvelope = memory.alloc<Envelope>(*param.AmpEnvelope, basefreq);
- AmpLfo = memory.alloc<LFO>(*param.AmpLfo, basefreq);
+ AmpEnvelope = memory.alloc<Envelope>(*param.AmpEnvelope, basefreq, synth.dt());
+ AmpLfo = memory.alloc<LFO>(*param.AmpLfo, basefreq, synth.dt());
Volume = 4.0f * powf(0.1f, 3.0f * (1.0f - param.PVolume / 96.0f)) //-60 dB .. 0 dB
* VelF(velocity, param.PAmpVelocityScaleFunction); //sensing
- GlobalFilterL = Filter::generate(memory, param.GlobalFilter);
+ GlobalFilterL = Filter::generate(memory, param.GlobalFilter,
+ synth.samplerate, synth.buffersize);
if(stereo)
- GlobalFilterR = Filter::generate(memory, param.GlobalFilter);
+ GlobalFilterR = Filter::generate(memory, param.GlobalFilter,
+ synth.samplerate, synth.buffersize);
else
GlobalFilterR = NULL;
- FilterEnvelope = memory.alloc<Envelope>(*param.FilterEnvelope, basefreq);
- FilterLfo = memory.alloc<LFO>(*param.FilterLfo, basefreq);
+ FilterEnvelope = memory.alloc<Envelope>(*param.FilterEnvelope, basefreq, synth.dt());
+ FilterLfo = memory.alloc<LFO>(*param.FilterLfo, basefreq, synth.dt());
FilterQ = param.GlobalFilter->getq();
FilterFreqTracking = param.GlobalFilter->getfreqtracking(basefreq);
}
diff --git a/src/Synth/ADnote.h b/src/Synth/ADnote.h
@@ -118,6 +118,7 @@ class ADnote:public SynthNote
struct Global {
void kill(Allocator &memory);
void initparameters(const ADnoteGlobalParam ¶m,
+ const SYNTH_T &synth,
class Allocator &memory,
float basefreq, float velocity,
bool stereo);
@@ -165,7 +166,7 @@ class ADnote:public SynthNote
/***********************************************************/
struct Voice {
void releasekey();
- void kill(Allocator &memory);
+ void kill(Allocator &memory, const SYNTH_T &synth);
/* If the voice is enabled */
ONOFFTYPE Enabled;
diff --git a/src/Synth/Envelope.cpp b/src/Synth/Envelope.cpp
@@ -24,7 +24,7 @@
#include "Envelope.h"
#include "../Params/EnvelopeParams.h"
-Envelope::Envelope(EnvelopeParams &pars, float basefreq)
+Envelope::Envelope(EnvelopeParams &pars, float basefreq, float bufferdt)
{
envpoints = pars.Penvpoints;
if(envpoints > MAX_ENVELOPE_POINTS)
@@ -37,8 +37,6 @@ Envelope::Envelope(EnvelopeParams &pars, float basefreq)
if(!pars.Pfreemode)
pars.converttofree();
- const float bufferdt = synth->buffersize_f / synth->samplerate_f;
-
int mode = pars.Envmode;
//for amplitude envelopes
diff --git a/src/Synth/Envelope.h b/src/Synth/Envelope.h
@@ -31,7 +31,7 @@ class Envelope
public:
/**Constructor*/
- Envelope(class EnvelopeParams &pars, float basefreq);
+ Envelope(class EnvelopeParams &pars, float basefreq, float dt);
/**Destructor*/
~Envelope();
void releasekey();
diff --git a/src/Synth/LFO.cpp b/src/Synth/LFO.cpp
@@ -28,7 +28,8 @@
#include <cstdio>
#include <cmath>
-LFO::LFO(const LFOParams &lfopars, float basefreq)
+LFO::LFO(const LFOParams &lfopars, float basefreq, float dt_)
+ :dt(dt_)
{
int stretch = lfopars.Pstretch;
if(stretch == 0)
@@ -39,7 +40,7 @@ LFO::LFO(const LFOParams &lfopars, float basefreq)
float lfofreq =
(powf(2, lfopars.Pfreq * 10.0f) - 1.0f) / 12.0f * lfostretch;
- incx = fabs(lfofreq) * synth->buffersize_f / synth->samplerate_f;
+ incx = fabs(lfofreq) * dt;
if(!lfopars.Pcontinous) {
if(lfopars.Pstartphase == 0)
@@ -150,7 +151,7 @@ float LFO::lfoout()
}
}
else
- lfodelay -= synth->buffersize_f / synth->samplerate_f;
+ lfodelay -= dt;
return out;
}
diff --git a/src/Synth/LFO.h b/src/Synth/LFO.h
@@ -34,7 +34,7 @@ class LFO
* @param lfopars pointer to a LFOParams object
* @param basefreq base frequency of LFO
*/
- LFO(const LFOParams &lfopars, float basefreq);
+ LFO(const LFOParams &lfopars, float basefreq, float dt);
/**Deconstructor*/
~LFO();
float lfoout();
@@ -46,6 +46,7 @@ class LFO
float lfointensity;
float lfornd, lfofreqrnd;
float lfodelay;
+ const float dt;
/**\todo see if an enum would be better here*/
char lfotype;
int freqrndenabled;
diff --git a/src/Synth/OscilGen.cpp b/src/Synth/OscilGen.cpp
@@ -99,7 +99,8 @@ const rtosc::Ports OscilGen::ports = {
}},
{"base-spectrum:", rProp(non-realtime) rDoc("Returns spectrum of base waveshape"),
NULL, [](const char *, rtosc::RtData &d) {
- const unsigned n = synth->oscilsize / 2;
+ OscilGen &o = *((OscilGen*)d.obj);
+ const unsigned n = o.synth.oscilsize / 2;
float *spc = new float[n];
memset(spc, 0, 4*n);
((OscilGen*)d.obj)->getspectrum(n,spc,1);
@@ -108,7 +109,8 @@ const rtosc::Ports OscilGen::ports = {
}},
{"base-waveform:", rProp(non-realtime) rDoc("Returns base waveshape points"),
NULL, [](const char *, rtosc::RtData &d) {
- const unsigned n = synth->oscilsize;
+ OscilGen &o = *((OscilGen*)d.obj);
+ const unsigned n = o.synth.oscilsize;
float *smps = new float[n];
memset(smps, 0, 4*n);
((OscilGen*)d.obj)->getcurrentbasefunction(smps);
@@ -117,7 +119,8 @@ const rtosc::Ports OscilGen::ports = {
}},
{"spectrum:", rProp(non-realtime) rDoc("Returns spectrum of waveform"),
NULL, [](const char *, rtosc::RtData &d) {
- const unsigned n = synth->oscilsize / 2;
+ OscilGen &o = *((OscilGen*)d.obj);
+ const unsigned n = o.synth.oscilsize / 2;
float *spc = new float[n];
memset(spc, 0, 4*n);
((OscilGen*)d.obj)->getspectrum(n,spc,0);
@@ -126,10 +129,10 @@ const rtosc::Ports OscilGen::ports = {
}},
{"waveform:", rProp(non-realtime) rDoc("Returns waveform points"),
NULL, [](const char *, rtosc::RtData &d) {
- const unsigned n = synth->oscilsize;
+ OscilGen &o = *((OscilGen*)d.obj);
+ const unsigned n = o.synth.oscilsize;
float *smps = new float[n];
memset(smps, 0, 4*n);
- OscilGen &o = *((OscilGen*)d.obj);
//printf("%d\n", o->needPrepare());
o.get(smps,-1.0);
//printf("wave: %f %f %f %f\n", smps[0], smps[1], smps[2], smps[3]);
@@ -140,7 +143,7 @@ const rtosc::Ports OscilGen::ports = {
NULL, [](const char *, rtosc::RtData &d) {
//fprintf(stderr, "prepare: got a message from '%s'\n", m);
OscilGen &o = *(OscilGen*)d.obj;
- fft_t *data = new fft_t[synth->oscilsize / 2];
+ fft_t *data = new fft_t[o.synth.oscilsize / 2];
o.prepare(data);
//fprintf(stderr, "sending '%p' of fft data\n", data);
d.reply("/forward", "sb", d.loc, sizeof(fft_t*), &data);
@@ -167,9 +170,9 @@ const rtosc::Ports OscilGen::ports = {
//operations on FFTfreqs
-inline void clearAll(fft_t *freqs)
+inline void clearAll(fft_t *freqs, int oscilsize)
{
- memset(freqs, 0, synth->oscilsize / 2 * sizeof(fft_t));
+ memset(freqs, 0, oscilsize / 2 * sizeof(fft_t));
}
inline void clearDC(fft_t *freqs)
@@ -200,10 +203,10 @@ inline float arg(const fft_t *freqs, off_t x)
* Take frequency spectrum and ensure values are normalized based upon
* magnitude to 0<=x<=1
*/
-void normalize(fft_t *freqs)
+void normalize(fft_t *freqs, int oscilsize)
{
float normMax = 0.0f;
- for(int i = 0; i < synth->oscilsize / 2; ++i) {
+ for(int i = 0; i < oscilsize / 2; ++i) {
//magnitude squared
const float norm = normal(freqs, i);
if(normMax < norm)
@@ -214,15 +217,15 @@ void normalize(fft_t *freqs)
if(max < 1e-8) //data is all ~zero, do not amplify noise
return;
- for(int i = 0; i < synth->oscilsize / 2; ++i)
+ for(int i = 0; i < oscilsize / 2; ++i)
freqs[i] /= max;
}
//Full RMS normalize
-void rmsNormalize(fft_t *freqs)
+void rmsNormalize(fft_t *freqs, int oscilsize)
{
float sum = 0.0f;
- for(int i = 1; i < synth->oscilsize / 2; ++i)
+ for(int i = 1; i < oscilsize / 2; ++i)
sum += normal(freqs, i);
if(sum < 0.000001f)
@@ -230,13 +233,14 @@ void rmsNormalize(fft_t *freqs)
const float gain = 1.0f / sqrt(sum);
- for(int i = 1; i < synth->oscilsize / 2; ++i)
+ for(int i = 1; i < oscilsize / 2; ++i)
freqs[i] *= gain;
}
#define DIFF(par) (old ## par != P ## par)
-OscilGen::OscilGen(FFTwrapper *fft_, Resonance *res_):Presets()
+OscilGen::OscilGen(const SYNTH_T &synth_, FFTwrapper *fft_, Resonance *res_)
+ :Presets(), synth(synth_)
{
//assert(fft_);
@@ -245,10 +249,10 @@ OscilGen::OscilGen(FFTwrapper *fft_, Resonance *res_):Presets()
res = res_;
- tmpsmps = new float[synth->oscilsize];
- outoscilFFTfreqs = new fft_t[synth->oscilsize / 2];
- oscilFFTfreqs = new fft_t[synth->oscilsize / 2];
- basefuncFFTfreqs = new fft_t[synth->oscilsize / 2];
+ tmpsmps = new float[synth.oscilsize];
+ outoscilFFTfreqs = new fft_t[synth.oscilsize / 2];
+ oscilFFTfreqs = new fft_t[synth.oscilsize / 2];
+ basefuncFFTfreqs = new fft_t[synth.oscilsize / 2];
pendingfreqs = oscilFFTfreqs;
randseed = 1;
@@ -329,8 +333,8 @@ void OscilGen::defaults()
Padaptiveharmonicsbasefreq = 128;
Padaptiveharmonicspar = 50;
- clearAll(oscilFFTfreqs);
- clearAll(basefuncFFTfreqs);
+ clearAll(oscilFFTfreqs, synth.oscilsize);
+ clearAll(basefuncFFTfreqs, synth.oscilsize);
oscilprepared = 0;
oldfilterpars = 0;
oldsapars = 0;
@@ -340,15 +344,15 @@ void OscilGen::defaults()
void OscilGen::convert2sine()
{
float mag[MAX_AD_HARMONICS], phase[MAX_AD_HARMONICS];
- float oscil[synth->oscilsize];
- fft_t *freqs = new fft_t[synth->oscilsize / 2];
+ float oscil[synth.oscilsize];
+ fft_t *freqs = new fft_t[synth.oscilsize / 2];
get(oscil, -1.0f);
- FFTwrapper *fft = new FFTwrapper(synth->oscilsize);
+ FFTwrapper *fft = new FFTwrapper(synth.oscilsize);
fft->smps2freqs(oscil, freqs);
delete (fft);
- normalize(freqs);
+ normalize(freqs, synth.oscilsize);
mag[0] = 0;
phase[0] = 0;
@@ -417,8 +421,8 @@ void OscilGen::getbasefunction(float *smps)
base_func func = getBaseFunction(Pcurrentbasefunc);
- for(i = 0; i < synth->oscilsize; ++i) {
- float t = i * 1.0f / synth->oscilsize;
+ for(i = 0; i < synth.oscilsize; ++i) {
+ float t = i * 1.0f / synth.oscilsize;
switch(Pbasefuncmodulation) {
case 1:
@@ -447,7 +451,7 @@ void OscilGen::getbasefunction(float *smps)
if(func)
smps[i] = func(t, par);
else
- smps[i] = -sinf(2.0f * PI * i / synth->oscilsize);
+ smps[i] = -sinf(2.0f * PI * i / synth.oscilsize);
}
}
@@ -464,10 +468,10 @@ void OscilGen::oscilfilter(fft_t *freqs)
const float par2 = Pfilterpar2 / 127.0f;
filter_func filter = getFilter(Pfiltertype);
- for(int i = 1; i < synth->oscilsize / 2; ++i)
+ for(int i = 1; i < synth.oscilsize / 2; ++i)
freqs[i] *= filter(i, par, par2);
- normalize(freqs);
+ normalize(freqs, synth.oscilsize);
}
@@ -482,7 +486,7 @@ void OscilGen::changebasefunction(void)
clearDC(basefuncFFTfreqs);
}
else //in this case basefuncFFTfreqs are not used
- clearAll(basefuncFFTfreqs);
+ clearAll(basefuncFFTfreqs, synth.oscilsize);
oscilprepared = 0;
oldbasefunc = Pcurrentbasefunc;
oldbasepar = Pbasefuncpar;
@@ -519,17 +523,17 @@ void OscilGen::waveshape(fft_t *freqs)
clearDC(freqs);
//reduce the amplitude of the freqs near the nyquist
- for(int i = 1; i < synth->oscilsize / 8; ++i) {
- float gain = i / (synth->oscilsize / 8.0f);
- freqs[synth->oscilsize / 2 - i] *= gain;
+ for(int i = 1; i < synth.oscilsize / 8; ++i) {
+ float gain = i / (synth.oscilsize / 8.0f);
+ freqs[synth.oscilsize / 2 - i] *= gain;
}
fft->freqs2smps(freqs, tmpsmps);
//Normalize
- normalize(tmpsmps, synth->oscilsize);
+ normalize(tmpsmps, synth.oscilsize);
//Do the waveshaping
- waveShapeSmps(synth->oscilsize, tmpsmps, Pwaveshapingfunction, Pwaveshaping);
+ waveShapeSmps(synth.oscilsize, tmpsmps, Pwaveshapingfunction, Pwaveshaping);
fft->smps2freqs(tmpsmps, freqs); //perform FFT
}
@@ -573,25 +577,25 @@ void OscilGen::modulation(fft_t *freqs)
clearDC(freqs); //remove the DC
//reduce the amplitude of the freqs near the nyquist
- for(int i = 1; i < synth->oscilsize / 8; ++i) {
- const float tmp = i / (synth->oscilsize / 8.0f);
- freqs[synth->oscilsize / 2 - i] *= tmp;
+ for(int i = 1; i < synth.oscilsize / 8; ++i) {
+ const float tmp = i / (synth.oscilsize / 8.0f);
+ freqs[synth.oscilsize / 2 - i] *= tmp;
}
fft->freqs2smps(freqs, tmpsmps);
const int extra_points = 2;
- float *in = new float[synth->oscilsize + extra_points];
+ float *in = new float[synth.oscilsize + extra_points];
//Normalize
- normalize(tmpsmps, synth->oscilsize);
+ normalize(tmpsmps, synth.oscilsize);
- for(int i = 0; i < synth->oscilsize; ++i)
+ for(int i = 0; i < synth.oscilsize; ++i)
in[i] = tmpsmps[i];
for(int i = 0; i < extra_points; ++i)
- in[i + synth->oscilsize] = tmpsmps[i];
+ in[i + synth.oscilsize] = tmpsmps[i];
//Do the modulation
- for(int i = 0; i < synth->oscilsize; ++i) {
- float t = i * 1.0f / synth->oscilsize;
+ for(int i = 0; i < synth.oscilsize; ++i) {
+ float t = i * 1.0f / synth.oscilsize;
switch(Pmodulation) {
case 1:
@@ -610,7 +614,7 @@ void OscilGen::modulation(fft_t *freqs)
break;
}
- t = (t - floor(t)) * synth->oscilsize;
+ t = (t - floor(t)) * synth.oscilsize;
const int poshi = (int) t;
const float poslo = t - floor(t);
@@ -648,9 +652,9 @@ void OscilGen::spectrumadjust(fft_t *freqs)
}
- normalize(freqs);
+ normalize(freqs, synth.oscilsize);
- for(int i = 0; i < synth->oscilsize / 2; ++i) {
+ for(int i = 0; i < synth.oscilsize / 2; ++i) {
float mag = abs(oscilFFTfreqs, i);
float phase = M_PI_2 - arg(oscilFFTfreqs, i);
@@ -681,7 +685,7 @@ void OscilGen::shiftharmonics(fft_t *freqs)
fft_t h;
if(harmonicshift > 0)
- for(int i = synth->oscilsize / 2 - 2; i >= 0; i--) {
+ for(int i = synth.oscilsize / 2 - 2; i >= 0; i--) {
int oldh = i - harmonicshift;
if(oldh < 0)
h = 0.0f;
@@ -690,9 +694,9 @@ void OscilGen::shiftharmonics(fft_t *freqs)
freqs[i + 1] = h;
}
else
- for(int i = 0; i < synth->oscilsize / 2 - 1; ++i) {
+ for(int i = 0; i < synth.oscilsize / 2 - 1; ++i) {
int oldh = i + abs(harmonicshift);
- if(oldh >= (synth->oscilsize / 2 - 1))
+ if(oldh >= (synth.oscilsize / 2 - 1))
h = 0.0f;
else {
h = freqs[oldh + 1];
@@ -754,7 +758,7 @@ void OscilGen::prepare(fft_t *freqs)
hmag[i] = 0.0f;
- clearAll(freqs);
+ clearAll(freqs, synth.oscilsize);
if(Pcurrentbasefunc == 0) //the sine case
for(int i = 0; i < MAX_AD_HARMONICS - 1; ++i) {
freqs[i + 1] =
@@ -765,9 +769,9 @@ void OscilGen::prepare(fft_t *freqs)
for(int j = 0; j < MAX_AD_HARMONICS; ++j) {
if(Phmag[j] == 64)
continue;
- for(int i = 1; i < synth->oscilsize / 2; ++i) {
+ for(int i = 1; i < synth.oscilsize / 2; ++i) {
int k = i * (j + 1);
- if(k >= synth->oscilsize / 2)
+ if(k >= synth.oscilsize / 2)
break;
freqs[k] += basefuncFFTfreqs[i] * FFTpolar<fftw_real>(
hmag[j],
@@ -812,10 +816,10 @@ void OscilGen::adaptiveharmonic(fft_t *f, float freq)
if(freq < 1.0f)
freq = 440.0f;
- fft_t *inf = new fft_t[synth->oscilsize / 2];
- for(int i = 0; i < synth->oscilsize / 2; ++i)
+ fft_t *inf = new fft_t[synth.oscilsize / 2];
+ for(int i = 0; i < synth.oscilsize / 2; ++i)
inf[i] = f[i];
- clearAll(f);
+ clearAll(f, synth.oscilsize);
clearDC(inf);
float basefreq = 30.0f * powf(10.0f, Padaptiveharmonicsbasefreq / 128.0f);
@@ -831,11 +835,11 @@ void OscilGen::adaptiveharmonic(fft_t *f, float freq)
down = true;
}
- for(int i = 0; i < synth->oscilsize / 2 - 2; ++i) {
+ for(int i = 0; i < synth.oscilsize / 2 - 2; ++i) {
const int high = (int)(i * rap);
const float low = fmod(i * rap, 1.0f);
- if(high >= (synth->oscilsize / 2 - 2))
+ if(high >= (synth.oscilsize / 2 - 2))
break;
if(down) {
@@ -946,36 +950,36 @@ short int OscilGen::get(float *smps, float freqHz, int resonance)
int outpos =
(int)((RND * 2.0f
- - 1.0f) * synth->oscilsize_f * (Prand - 64.0f) / 64.0f);
- outpos = (outpos + 2 * synth->oscilsize) % synth->oscilsize;
+ - 1.0f) * synth.oscilsize_f * (Prand - 64.0f) / 64.0f);
+ outpos = (outpos + 2 * synth.oscilsize) % synth.oscilsize;
- clearAll(outoscilFFTfreqs);
+ clearAll(outoscilFFTfreqs, synth.oscilsize);
- int nyquist = (int)(0.5f * synth->samplerate_f / fabs(freqHz)) + 2;
+ int nyquist = (int)(0.5f * synth.samplerate_f / fabs(freqHz)) + 2;
if(ADvsPAD)
- nyquist = (int)(synth->oscilsize / 2);
- if(nyquist > synth->oscilsize / 2)
- nyquist = synth->oscilsize / 2;
+ nyquist = (int)(synth.oscilsize / 2);
+ if(nyquist > synth.oscilsize / 2)
+ nyquist = synth.oscilsize / 2;
//Process harmonics
{
int realnyquist = nyquist;
if(Padaptiveharmonics != 0)
- nyquist = synth->oscilsize / 2;
+ nyquist = synth.oscilsize / 2;
for(int i = 1; i < nyquist - 1; ++i)
outoscilFFTfreqs[i] = input[i];
adaptiveharmonic(outoscilFFTfreqs, freqHz);
adaptiveharmonicpostprocess(&outoscilFFTfreqs[1],
- synth->oscilsize / 2 - 1);
+ synth.oscilsize / 2 - 1);
nyquist = realnyquist;
}
if(Padaptiveharmonics) //do the antialiasing in the case of adaptive harmonics
- for(int i = nyquist; i < synth->oscilsize / 2; ++i)
+ for(int i = nyquist; i < synth.oscilsize / 2; ++i)
outoscilFFTfreqs[i] = fft_t(0.0f, 0.0f);
// Randomness (each harmonic), the block type is computed
@@ -1015,14 +1019,14 @@ short int OscilGen::get(float *smps, float freqHz, int resonance)
if((freqHz > 0.1f) && (resonance != 0))
res->applyres(nyquist - 1, outoscilFFTfreqs, freqHz);
- rmsNormalize(outoscilFFTfreqs);
+ rmsNormalize(outoscilFFTfreqs, synth.oscilsize);
if((ADvsPAD) && (freqHz > 0.1f)) //in this case the smps will contain the freqs
- for(int i = 1; i < synth->oscilsize / 2; ++i)
+ for(int i = 1; i < synth.oscilsize / 2; ++i)
smps[i - 1] = abs(outoscilFFTfreqs, i);
else {
fft->freqs2smps(outoscilFFTfreqs, smps);
- for(int i = 0; i < synth->oscilsize; ++i)
+ for(int i = 0; i < synth.oscilsize; ++i)
smps[i] *= 0.25f; //correct the amplitude
}
@@ -1042,7 +1046,7 @@ short int OscilGen::get(float *smps, float freqHz, int resonance)
//
// clearAll(outoscilFFTfreqs);
//
-// const int nyquist = (synth->oscilsize / 2);
+// const int nyquist = (synth.oscilsize / 2);
//
// //Process harmonics
// for(int i = 1; i < nyquist - 1; ++i)
@@ -1063,8 +1067,8 @@ short int OscilGen::get(float *smps, float freqHz, int resonance)
*/
void OscilGen::getspectrum(int n, float *spc, int what)
{
- if(n > synth->oscilsize / 2)
- n = synth->oscilsize / 2;
+ if(n > synth.oscilsize / 2)
+ n = synth.oscilsize / 2;
for(int i = 1; i < n; ++i) {
if(what == 0)
@@ -1081,7 +1085,7 @@ void OscilGen::getspectrum(int n, float *spc, int what)
for(int i = 0; i < n; ++i)
outoscilFFTfreqs[i] = fft_t(spc[i], spc[i]);
memset(outoscilFFTfreqs + n, 0,
- (synth->oscilsize / 2 - n) * sizeof(fft_t));
+ (synth.oscilsize / 2 - n) * sizeof(fft_t));
adaptiveharmonic(outoscilFFTfreqs, 0.0f);
adaptiveharmonicpostprocess(outoscilFFTfreqs, n - 1);
for(int i = 0; i < n; ++i)
@@ -1095,7 +1099,7 @@ void OscilGen::getspectrum(int n, float *spc, int what)
*/
void OscilGen::useasbase()
{
- for(int i = 0; i < synth->oscilsize / 2; ++i)
+ for(int i = 0; i < synth.oscilsize / 2; ++i)
basefuncFFTfreqs[i] = oscilFFTfreqs[i];
oldbasefunc = Pcurrentbasefunc = 127;
@@ -1188,10 +1192,10 @@ void OscilGen::add2XML(XMLwrapper *xml)
xml->endbranch();
if(Pcurrentbasefunc == 127) {
- normalize(basefuncFFTfreqs);
+ normalize(basefuncFFTfreqs, synth.oscilsize);
xml->beginbranch("BASE_FUNCTION");
- for(int i = 1; i < synth->oscilsize / 2; ++i) {
+ for(int i = 1; i < synth.oscilsize / 2; ++i) {
float xc = basefuncFFTfreqs[i].real();
float xs = basefuncFFTfreqs[i].imag();
if((fabs(xs) > 1e-6f) && (fabs(xc) > 1e-6f)) {
@@ -1286,7 +1290,7 @@ void OscilGen::getfromXML(XMLwrapper *xml)
if(xml->enterbranch("BASE_FUNCTION")) {
- for(int i = 1; i < synth->oscilsize / 2; ++i)
+ for(int i = 1; i < synth.oscilsize / 2; ++i)
if(xml->enterbranch("BF_HARMONIC", i)) {
basefuncFFTfreqs[i] =
std::complex<float>(xml->getparreal("cos", 0.0f),
@@ -1296,7 +1300,7 @@ void OscilGen::getfromXML(XMLwrapper *xml)
xml->exitbranch();
clearDC(basefuncFFTfreqs);
- normalize(basefuncFFTfreqs);
+ normalize(basefuncFFTfreqs, synth.oscilsize);
}
}
diff --git a/src/Synth/OscilGen.h b/src/Synth/OscilGen.h
@@ -30,7 +30,7 @@
class OscilGen:public Presets
{
public:
- OscilGen(FFTwrapper *fft_, Resonance *res_);
+ OscilGen(const SYNTH_T &synth, FFTwrapper *fft_, Resonance *res_);
~OscilGen();
/**computes the full spectrum of oscil from harmonics,phases and basefunc*/
@@ -177,6 +177,8 @@ class OscilGen:public Presets
Resonance *res;
unsigned int randseed;
+ public:
+ const SYNTH_T &synth;
};
typedef float (*filter_func)(unsigned int, float, float);
diff --git a/src/Synth/PADnote.cpp b/src/Synth/PADnote.cpp
@@ -125,16 +125,16 @@ void PADnote::setup(float freq,
powf(10, 3.0f * pars.PPunchTime / 127.0f) / 10000.0f; //0.1f .. 100 ms
float stretch = powf(440.0f / freq, pars.PPunchStretch / 64.0f);
NoteGlobalPar.Punch.dt = 1.0f
- / (time * synth->samplerate_f * stretch);
+ / (time * synth.samplerate_f * stretch);
}
else
NoteGlobalPar.Punch.Enabled = 0;
- NoteGlobalPar.FreqEnvelope = memory.alloc<Envelope>(*pars.FreqEnvelope, basefreq);
- NoteGlobalPar.FreqLfo = memory.alloc<LFO>(*pars.FreqLfo, basefreq);
+ NoteGlobalPar.FreqEnvelope = memory.alloc<Envelope>(*pars.FreqEnvelope, basefreq, synth.dt());
+ NoteGlobalPar.FreqLfo = memory.alloc<LFO>(*pars.FreqLfo, basefreq, synth.dt());
- NoteGlobalPar.AmpEnvelope = memory.alloc<Envelope>(*pars.AmpEnvelope, basefreq);
- NoteGlobalPar.AmpLfo = memory.alloc<LFO>(*pars.AmpLfo, basefreq);
+ NoteGlobalPar.AmpEnvelope = memory.alloc<Envelope>(*pars.AmpEnvelope, basefreq, synth.dt());
+ NoteGlobalPar.AmpLfo = memory.alloc<LFO>(*pars.AmpLfo, basefreq, synth.dt());
}
NoteGlobalPar.Volume = 4.0f
@@ -148,11 +148,13 @@ void PADnote::setup(float freq,
* NoteGlobalPar.AmpLfo->amplfoout();
if(!legato) {
- NoteGlobalPar.GlobalFilterL = Filter::generate(memory, pars.GlobalFilter);
- NoteGlobalPar.GlobalFilterR = Filter::generate(memory, pars.GlobalFilter);
+ NoteGlobalPar.GlobalFilterL = Filter::generate(memory, pars.GlobalFilter,
+ synth.samplerate, synth.buffersize);
+ NoteGlobalPar.GlobalFilterR = Filter::generate(memory, pars.GlobalFilter,
+ synth.samplerate, synth.buffersize);
- NoteGlobalPar.FilterEnvelope = memory.alloc<Envelope>(*pars.FilterEnvelope, basefreq);
- NoteGlobalPar.FilterLfo = memory.alloc<LFO>(*pars.FilterLfo, basefreq);
+ NoteGlobalPar.FilterEnvelope = memory.alloc<Envelope>(*pars.FilterEnvelope, basefreq, synth.dt());
+ NoteGlobalPar.FilterLfo = memory.alloc<LFO>(*pars.FilterLfo, basefreq, synth.dt());
}
NoteGlobalPar.FilterQ = pars.GlobalFilter->getq();
NoteGlobalPar.FilterFreqTracking = pars.GlobalFilter->getfreqtracking(
@@ -190,18 +192,18 @@ PADnote::~PADnote()
inline void PADnote::fadein(float *smps)
{
int zerocrossings = 0;
- for(int i = 1; i < synth->buffersize; ++i)
+ for(int i = 1; i < synth.buffersize; ++i)
if((smps[i - 1] < 0.0f) && (smps[i] > 0.0f))
zerocrossings++; //this is only the possitive crossings
- float tmp = (synth->buffersize_f - 1.0f) / (zerocrossings + 1) / 3.0f;
+ float tmp = (synth.buffersize_f - 1.0f) / (zerocrossings + 1) / 3.0f;
if(tmp < 8.0f)
tmp = 8.0f;
int n;
F2I(tmp, n); //how many samples is the fade-in
- if(n > synth->buffersize)
- n = synth->buffersize;
+ if(n > synth.buffersize)
+ n = synth.buffersize;
for(int i = 0; i < n; ++i) { //fade-in
float tmp = 0.5f - cosf((float)i / (float) n * PI) * 0.5f;
smps[i] *= tmp;
@@ -257,7 +259,7 @@ int PADnote::Compute_Linear(float *outl,
return 1;
}
int size = pars.sample[nsample].size;
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
poshi_l += freqhi;
poshi_r += freqhi;
poslo += freqlo;
@@ -288,7 +290,7 @@ int PADnote::Compute_Cubic(float *outl,
}
int size = pars.sample[nsample].size;
float xm1, x0, x1, x2, a, b, c;
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
poshi_l += freqhi;
poshi_r += freqhi;
poslo += freqlo;
@@ -331,7 +333,7 @@ int PADnote::noteout(float *outl, float *outr)
computecurrentparameters();
float *smps = pars.sample[nsample].smp;
if(smps == NULL) {
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
outl[i] = 0.0f;
outr[i] = 0.0f;
}
@@ -362,7 +364,7 @@ int PADnote::noteout(float *outl, float *outr)
//Apply the punch
if(NoteGlobalPar.Punch.Enabled != 0)
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float punchamp = NoteGlobalPar.Punch.initialvalue
* NoteGlobalPar.Punch.t + 1.0f;
outl[i] *= punchamp;
@@ -376,16 +378,16 @@ int PADnote::noteout(float *outl, float *outr)
if(ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude, globalnewamplitude))
// Amplitude Interpolation
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude,
globalnewamplitude,
i,
- synth->buffersize);
+ synth.buffersize);
outl[i] *= tmpvol * NoteGlobalPar.Panning;
outr[i] *= tmpvol * (1.0f - NoteGlobalPar.Panning);
}
else
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
outl[i] *= globalnewamplitude * NoteGlobalPar.Panning;
outr[i] *= globalnewamplitude * (1.0f - NoteGlobalPar.Panning);
}
@@ -397,8 +399,8 @@ int PADnote::noteout(float *outl, float *outr)
// Check if the global amplitude is finished.
// If it does, disable the note
if(NoteGlobalPar.AmpEnvelope->finished()) {
- for(int i = 0; i < synth->buffersize; ++i) { //fade-out
- float tmp = 1.0f - (float)i / synth->buffersize_f;
+ for(int i = 0; i < synth.buffersize; ++i) { //fade-out
+ float tmp = 1.0f - (float)i / synth.buffersize_f;
outl[i] *= tmp;
outr[i] *= tmp;
}
diff --git a/src/Synth/SUBnote.cpp b/src/Synth/SUBnote.cpp
@@ -254,11 +254,11 @@ void SUBnote::computefiltercoefs(bpfilter &filter,
float bw,
float gain)
{
- if(freq > synth->samplerate_f / 2.0f - 200.0f)
- freq = synth->samplerate_f / 2.0f - 200.0f;
+ if(freq > synth.samplerate_f / 2.0f - 200.0f)
+ freq = synth.samplerate_f / 2.0f - 200.0f;
- float omega = 2.0f * PI * freq / synth->samplerate_f;
+ float omega = 2.0f * PI * freq / synth.samplerate_f;
float sn = sinf(omega);
float cs = cosf(omega);
float alpha = sn * sinh(LOG_2 / 2.0f * bw * omega / sn);
@@ -297,11 +297,11 @@ void SUBnote::initfilter(bpfilter &filter,
if(start == 1)
a *= RND;
filter.yn1 = a * cosf(p);
- filter.yn2 = a * cosf(p + freq * 2.0f * PI / synth->samplerate_f);
+ filter.yn2 = a * cosf(p + freq * 2.0f * PI / synth.samplerate_f);
//correct the error of computation the start amplitude
//at very high frequencies
- if(freq > synth->samplerate_f * 0.96f) {
+ if(freq > synth.samplerate_f * 0.96f) {
filter.yn1 = 0.0f;
filter.yn2 = 0.0f;
}
@@ -335,11 +335,11 @@ inline void SubFilterB(const float coeff[4], float &src, float work[4])
//in quite a bit of wasted time
void SUBnote::filter(bpfilter &filter, float *smps)
{
- assert(synth->buffersize % 8 == 0);
+ assert(synth.buffersize % 8 == 0);
float coeff[4] = {filter.b0, filter.b2, -filter.a1, -filter.a2};
float work[4] = {filter.xn1, filter.xn2, filter.yn1, filter.yn2};
- for(int i = 0; i < synth->buffersize; i += 8) {
+ for(int i = 0; i < synth.buffersize; i += 8) {
SubFilterA(coeff, smps[i + 0], work);
SubFilterB(coeff, smps[i + 1], work);
SubFilterA(coeff, smps[i + 2], work);
@@ -360,21 +360,23 @@ void SUBnote::filter(bpfilter &filter, float *smps)
*/
void SUBnote::initparameters(float freq)
{
- AmpEnvelope = memory.alloc<Envelope>(*pars.AmpEnvelope, freq);
+ AmpEnvelope = memory.alloc<Envelope>(*pars.AmpEnvelope, freq, synth.dt());
if(pars.PFreqEnvelopeEnabled)
- FreqEnvelope = memory.alloc<Envelope>(*pars.FreqEnvelope, freq);
+ FreqEnvelope = memory.alloc<Envelope>(*pars.FreqEnvelope, freq, synth.dt());
else
FreqEnvelope = NULL;
if(pars.PBandWidthEnvelopeEnabled)
- BandWidthEnvelope = memory.alloc<Envelope>(*pars.BandWidthEnvelope, freq);
+ BandWidthEnvelope = memory.alloc<Envelope>(*pars.BandWidthEnvelope, freq, synth.dt());
else
BandWidthEnvelope = NULL;
if(pars.PGlobalFilterEnabled) {
globalfiltercenterq = pars.GlobalFilter->getq();
- GlobalFilterL = Filter::generate(memory, pars.GlobalFilter);
+ GlobalFilterL = Filter::generate(memory, pars.GlobalFilter,
+ synth.samplerate, synth.buffersize);
if(stereo)
- GlobalFilterR = Filter::generate(memory, pars.GlobalFilter);
- GlobalFilterEnvelope = memory.alloc<Envelope>(*pars.GlobalFilterEnvelope, freq);
+ GlobalFilterR = Filter::generate(memory, pars.GlobalFilter,
+ synth.samplerate, synth.buffersize);
+ GlobalFilterEnvelope = memory.alloc<Envelope>(*pars.GlobalFilterEnvelope, freq, synth.dt());
GlobalFilterFreqTracking = pars.GlobalFilter->getfreqtracking(basefreq);
}
computecurrentparameters();
@@ -388,7 +390,7 @@ float SUBnote::computerolloff(float freq)
const float lower_limit = 10.0f;
const float lower_width = 10.0f;
const float upper_width = 200.0f;
- float upper_limit = synth->samplerate / 2.0f;
+ float upper_limit = synth.samplerate / 2.0f;
if (freq > lower_limit + lower_width &&
freq < upper_limit - upper_width)
@@ -489,23 +491,23 @@ void SUBnote::computecurrentparameters()
*/
int SUBnote::noteout(float *outl, float *outr)
{
- memcpy(outl, denormalkillbuf, synth->bufferbytes);
- memcpy(outr, denormalkillbuf, synth->bufferbytes);
+ memcpy(outl, denormalkillbuf, synth.bufferbytes);
+ memcpy(outr, denormalkillbuf, synth.bufferbytes);
if(NoteEnabled == OFF)
return 0;
- float tmprnd[synth->buffersize];
- float tmpsmp[synth->buffersize];
+ float tmprnd[synth.buffersize];
+ float tmpsmp[synth.buffersize];
//left channel
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tmprnd[i] = RND * 2.0f - 1.0f;
for(int n = 0; n < numharmonics; ++n) {
float rolloff = overtone_rolloff[n];
- memcpy(tmpsmp, tmprnd, synth->bufferbytes);
+ memcpy(tmpsmp, tmprnd, synth.bufferbytes);
for(int nph = 0; nph < numstages; ++nph)
filter(lfilter[nph + n * numstages], tmpsmp);
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
outl[i] += tmpsmp[i] * rolloff;
}
@@ -514,26 +516,26 @@ int SUBnote::noteout(float *outl, float *outr)
//right channel
if(stereo) {
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
tmprnd[i] = RND * 2.0f - 1.0f;
for(int n = 0; n < numharmonics; ++n) {
float rolloff = overtone_rolloff[n];
- memcpy(tmpsmp, tmprnd, synth->bufferbytes);
+ memcpy(tmpsmp, tmprnd, synth.bufferbytes);
for(int nph = 0; nph < numstages; ++nph)
filter(rfilter[nph + n * numstages], tmpsmp);
- for(int i = 0; i < synth->buffersize; ++i)
+ for(int i = 0; i < synth.buffersize; ++i)
outr[i] += tmpsmp[i] * rolloff;
}
if(GlobalFilterR != NULL)
GlobalFilterR->filterout(&outr[0]);
}
else
- memcpy(outr, outl, synth->bufferbytes);
+ memcpy(outr, outl, synth.bufferbytes);
if(firsttick != 0) {
int n = 10;
- if(n > synth->buffersize)
- n = synth->buffersize;
+ if(n > synth.buffersize)
+ n = synth.buffersize;
for(int i = 0; i < n; ++i) {
float ampfadein = 0.5f - 0.5f * cosf(
(float) i / (float) n * PI);
@@ -545,16 +547,16 @@ int SUBnote::noteout(float *outl, float *outr)
if(ABOVE_AMPLITUDE_THRESHOLD(oldamplitude, newamplitude))
// Amplitude interpolation
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
float tmpvol = INTERPOLATE_AMPLITUDE(oldamplitude,
newamplitude,
i,
- synth->buffersize);
+ synth.buffersize);
outl[i] *= tmpvol * panning;
outr[i] *= tmpvol * (1.0f - panning);
}
else
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
outl[i] *= newamplitude * panning;
outr[i] *= newamplitude * (1.0f - panning);
}
@@ -567,8 +569,8 @@ int SUBnote::noteout(float *outl, float *outr)
// Check if the note needs to be computed more
if(AmpEnvelope->finished() != 0) {
- for(int i = 0; i < synth->buffersize; ++i) { //fade-out
- float tmp = 1.0f - (float)i / synth->buffersize_f;
+ for(int i = 0; i < synth.buffersize; ++i) { //fade-out
+ float tmp = 1.0f - (float)i / synth.buffersize_f;
outl[i] *= tmp;
outr[i] *= tmp;
}
diff --git a/src/Synth/SynthNote.cpp b/src/Synth/SynthNote.cpp
@@ -3,17 +3,18 @@
#include <cstring>
SynthNote::SynthNote(SynthParams &pars)
- :legato(pars.frequency, pars.velocity, pars.portamento,
+ :legato(pars.synth, pars.frequency, pars.velocity, pars.portamento,
pars.note, pars.quiet),
- memory(pars.memory), ctl(pars.ctl)
+ memory(pars.memory), ctl(pars.ctl), synth(pars.synth)
{}
-SynthNote::Legato::Legato(float freq, float vel, int port,
+SynthNote::Legato::Legato(const SYNTH_T &synth_, float freq, float vel, int port,
int note, bool quiet)
+ :synth(synth_)
{
// Initialise some legato-specific vars
msg = LM_Norm;
- fade.length = (int)(synth->samplerate_f * 0.005f); // 0.005f seems ok.
+ fade.length = (int)(synth.samplerate_f * 0.005f); // 0.005f seems ok.
if(fade.length < 1)
fade.length = 1; // (if something's fishy)
fade.step = (1.0f / fade.length);
@@ -57,15 +58,15 @@ void SynthNote::Legato::apply(SynthNote ¬e, float *outl, float *outr)
{
if(silent) // Silencer
if(msg != LM_FadeIn) {
- memset(outl, 0, synth->bufferbytes);
- memset(outr, 0, synth->bufferbytes);
+ memset(outl, 0, synth.bufferbytes);
+ memset(outr, 0, synth.bufferbytes);
}
switch(msg) {
case LM_CatchUp: // Continue the catch-up...
if(decounter == -10)
decounter = fade.length;
//Yea, could be done without the loop...
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
decounter--;
if(decounter < 1) {
// Catching-up done, we can finally set
@@ -83,7 +84,7 @@ void SynthNote::Legato::apply(SynthNote ¬e, float *outl, float *outr)
if(decounter == -10)
decounter = fade.length;
silent = false;
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
decounter--;
if(decounter < 1) {
decounter = -10;
@@ -98,10 +99,10 @@ void SynthNote::Legato::apply(SynthNote ¬e, float *outl, float *outr)
case LM_FadeOut: // Fade-out, then set the catch-up
if(decounter == -10)
decounter = fade.length;
- for(int i = 0; i < synth->buffersize; ++i) {
+ for(int i = 0; i < synth.buffersize; ++i) {
decounter--;
if(decounter < 1) {
- for(int j = i; j < synth->buffersize; ++j) {
+ for(int j = i; j < synth.buffersize; ++j) {
outl[j] = 0.0f;
outr[j] = 0.0f;
}
diff --git a/src/Synth/SynthNote.h b/src/Synth/SynthNote.h
@@ -29,6 +29,7 @@ struct SynthParams
{
Allocator &memory; //Memory Allocator for the Note to use
Controller &ctl;
+ const SYNTH_T &synth;
float frequency; //Note base frequency
float velocity; //Velocity of the Note
bool portamento;//True if portamento is used for this note
@@ -71,7 +72,7 @@ class SynthNote
class Legato
{
public:
- Legato(float freq, float vel, int port,
+ Legato(const SYNTH_T &synth_, float freq, float vel, int port,
int note, bool quiet);
void apply(SynthNote ¬e, float *outl, float *outr);
@@ -91,6 +92,7 @@ class SynthNote
bool portamento;
int midinote;
} param;
+ const SYNTH_T &synth;
public: /* Some get routines for legatonote calls (aftertouch feature)*/
float getFreq() {return param.freq; }
@@ -102,8 +104,9 @@ class SynthNote
} legato;
//Realtime Safe Memory Allocator For notes
- class Allocator &memory;
+ class Allocator &memory;
const Controller &ctl;
+ const SYNTH_T &synth;
};
#endif
diff --git a/src/Tests/AdNoteTest.h b/src/Tests/AdNoteTest.h
@@ -75,7 +75,7 @@ class AdNoteTest:public CxxTest::TestSuite
fft = new FFTwrapper(synth->oscilsize);
//prepare the default settings
- ADnoteParameters *defaultPreset = new ADnoteParameters(fft);
+ ADnoteParameters *defaultPreset = new ADnoteParameters(*synth, fft);
//Assert defaults
TS_ASSERT(!defaultPreset->VoicePar[1].Enabled);
@@ -99,12 +99,12 @@ class AdNoteTest:public CxxTest::TestSuite
- controller = new Controller();
+ controller = new Controller(*synth);
//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, freq, 120, 0, testnote, false};
+ SynthParams pars{memory, *controller, *synth, freq, 120, 0, testnote, false};
note = new ADnote(defaultPreset, pars);
@@ -112,11 +112,6 @@ class AdNoteTest:public CxxTest::TestSuite
delete wrap;
}
- void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh()
- {
- master = new Master();
- }
-
void tearDown() {
delete note;
delete controller;
diff --git a/src/Tests/ControllerTest.h b/src/Tests/ControllerTest.h
@@ -30,7 +30,7 @@ class ControllerTest:public CxxTest::TestSuite
public:
void setUp() {
synth = new SYNTH_T;
- testCtl = new Controller();
+ testCtl = new Controller(*synth);
}
void tearDown() {
diff --git a/src/Tests/InstrumentStats.cpp b/src/Tests/InstrumentStats.cpp
@@ -65,7 +65,7 @@ void setup() {
denormalkillbuf = new float[synth->buffersize];
for(int i = 0; i < synth->buffersize; ++i)
denormalkillbuf[i] = 0;
- p = new Part(alloc, µtonal, &fft);
+ p = new Part(alloc, *synth, µtonal, &fft);
}
void xml(string s)
diff --git a/src/Tests/OscilGenTest.h b/src/Tests/OscilGenTest.h
@@ -57,7 +57,7 @@ class OscilGenTest:public CxxTest::TestSuite
//prepare the default settings
fft = new FFTwrapper(synth->oscilsize);
- oscil = new OscilGen(fft, NULL);
+ oscil = new OscilGen(*synth, fft, NULL);
//Assert defaults [TODO]
diff --git a/src/Tests/PadNoteTest.h b/src/Tests/PadNoteTest.h
@@ -81,7 +81,7 @@ class PadNoteTest:public CxxTest::TestSuite
fft = new FFTwrapper(synth->oscilsize);
//prepare the default settings
- pars = new PADnoteParameters(fft);
+ pars = new PADnoteParameters(*synth, fft);
//Assert defaults
@@ -109,12 +109,12 @@ class PadNoteTest:public CxxTest::TestSuite
- controller = new Controller();
+ controller = new Controller(*synth);
//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, freq, 120, 0, testnote, false};
+ SynthParams pars_{memory, *controller, *synth, freq, 120, 0, testnote, false};
note = new PADnote(pars, pars_);
}
diff --git a/src/Tests/PluginTest.h b/src/Tests/PluginTest.h
@@ -63,7 +63,7 @@ class PluginTest:public CxxTest::TestSuite
denormalkillbuf[i] = 0;
for(int i = 0; i < 16; ++i)
- master[i] = new Master();
+ master[i] = new Master(*synth);
}
void tearDown() {
diff --git a/src/Tests/SubNoteTest.h b/src/Tests/SubNoteTest.h
@@ -82,23 +82,18 @@ class SubNoteTest:public CxxTest::TestSuite
TS_ASSERT(wrap->enterbranch("SUB_SYNTH_PARAMETERS"));
defaultPreset->getfromXML(wrap);
- controller = new Controller();
+ controller = new Controller(*synth);
//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, freq, 120, 0, testnote, false};
+ SynthParams pars{memory, *controller, *synth, freq, 120, 0, testnote, false};
note = new SUBnote(defaultPreset, pars);
delete wrap;
delete defaultPreset;
}
- void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh()
- {
- master = new Master();
- }
-
void tearDown() {
delete controller;
delete note;
diff --git a/src/Tests/UnisonTest.h b/src/Tests/UnisonTest.h
@@ -70,12 +70,12 @@ class AdNoteTest:public CxxTest::TestSuite
fft = new FFTwrapper(BUF);
//prepare the default settings
- params = new ADnoteParameters(fft);
+ params = new ADnoteParameters(*synth, fft);
//sawtooth to make things a bit more interesting
params->VoicePar[0].OscilSmp->Pcurrentbasefunc = 3;
- controller = new Controller();
+ controller = new Controller(*synth);
//lets go with.... 50! as a nice note
testnote = 50;
@@ -103,7 +103,7 @@ class AdNoteTest:public CxxTest::TestSuite
params->VoicePar[0].Unison_vibratto_speed = e;
params->VoicePar[0].Unison_invert_phase = f;
- SynthParams pars{memory, *controller, freq, 120, 0, testnote, false};
+ SynthParams pars{memory, *controller, *synth, freq, 120, 0, testnote, false};
note = new ADnote(params, pars);
note->noteout(outL, outR);
TS_ASSERT_DELTA(outL[80], values[0], 1e-5);
diff --git a/src/globals.h b/src/globals.h
@@ -287,6 +287,10 @@ struct SYNTH_T {
int bufferbytes;
float oscilsize_f;
+ float dt(void) const
+ {
+ return buffersize_f / samplerate_f;
+ }
inline void alias(void)
{
halfsamplerate_f = (samplerate_f = samplerate) / 2.0f;
@@ -296,6 +300,4 @@ struct SYNTH_T {
}
static float numRandom(void); //defined in Util.cpp for now
};
-
-extern SYNTH_T *synth;
#endif
diff --git a/src/main.cpp b/src/main.cpp
@@ -59,7 +59,6 @@ MiddleWare *middleware;
using namespace std;
Master *master;
-SYNTH_T *synth;
int swaplr = 0; //1 for left-right swapping
int Pexitprogram = 0; //if the UI set this to 1, the program will exit
@@ -92,15 +91,15 @@ void sigterm_exit(int /*sig*/)
/*
* Program initialisation
*/
-void initprogram(int prefered_port)
+void initprogram(SYNTH_T synth, int prefered_port)
{
- middleware = new MiddleWare(prefered_port);
+ middleware = new MiddleWare(synth, prefered_port);
master = middleware->spawnMaster();
master->swaplr = swaplr;
signal(SIGINT, sigterm_exit);
signal(SIGTERM, sigterm_exit);
- Nio::init(master);
+ Nio::init(master->synth, master);
}
/*
@@ -129,7 +128,7 @@ void exitprogram()
int main(int argc, char *argv[])
{
main_thread = pthread_self();
- synth = new SYNTH_T;
+ SYNTH_T synth;
config.init();
int noui = 0;
cerr
@@ -145,14 +144,14 @@ int main(int argc, char *argv[])
cerr << "Try 'zynaddsubfx --help' for command-line options." << endl;
/* Get the settings from the Config*/
- synth->samplerate = config.cfg.SampleRate;
- synth->buffersize = config.cfg.SoundBufferSize;
- synth->oscilsize = config.cfg.OscilSize;
+ synth.samplerate = config.cfg.SampleRate;
+ synth.buffersize = config.cfg.SoundBufferSize;
+ synth.oscilsize = config.cfg.OscilSize;
swaplr = config.cfg.SwapStereo;
- Nio::preferedSampleRate(synth->samplerate);
+ Nio::preferedSampleRate(synth.samplerate);
- synth->alias(); //build aliases
+ synth.alias(); //build aliases
sprng(time(NULL));
@@ -266,16 +265,16 @@ int main(int argc, char *argv[])
GETOP(loadinstrument);
break;
case 'r':
- GETOPNUM(synth->samplerate);
- if(synth->samplerate < 4000) {
+ GETOPNUM(synth.samplerate);
+ if(synth.samplerate < 4000) {
cerr << "ERROR:Incorrect sample rate: " << optarguments
<< endl;
exit(1);
}
break;
case 'b':
- GETOPNUM(synth->buffersize);
- if(synth->buffersize < 2) {
+ GETOPNUM(synth.buffersize);
+ if(synth.buffersize < 2) {
cerr << "ERROR:Incorrect buffer size: " << optarguments
<< endl;
exit(1);
@@ -283,17 +282,17 @@ int main(int argc, char *argv[])
break;
case 'o':
if(optarguments)
- synth->oscilsize = tmp = atoi(optarguments);
- if(synth->oscilsize < MAX_AD_HARMONICS * 2)
- synth->oscilsize = MAX_AD_HARMONICS * 2;
- synth->oscilsize =
+ synth.oscilsize = tmp = atoi(optarguments);
+ if(synth.oscilsize < MAX_AD_HARMONICS * 2)
+ synth.oscilsize = MAX_AD_HARMONICS * 2;
+ synth.oscilsize =
(int) powf(2,
- ceil(logf(synth->oscilsize - 1.0f) / logf(2.0f)));
- if(tmp != synth->oscilsize)
+ ceil(logf(synth.oscilsize - 1.0f) / logf(2.0f)));
+ if(tmp != synth.oscilsize)
cerr
<<
- "synth->oscilsize is wrong (must be 2^n) or too small. Adjusting to "
- << synth->oscilsize << "." << endl;
+ "synth.oscilsize is wrong (must be 2^n) or too small. Adjusting to "
+ << synth.oscilsize << "." << endl;
break;
case 'S':
swaplr = 1;
@@ -343,7 +342,7 @@ int main(int argc, char *argv[])
}
}
- synth->alias();
+ synth.alias();
if(exitwithversion) {
cout << "Version: " << VERSION << endl;
@@ -377,11 +376,11 @@ int main(int argc, char *argv[])
}
//produce denormal buf
- denormalkillbuf = new float [synth->buffersize];
- for(int i = 0; i < synth->buffersize; ++i)
+ denormalkillbuf = new float [synth.buffersize];
+ for(int i = 0; i < synth.buffersize; ++i)
denormalkillbuf[i] = (RND - 0.5f) * 1e-16;
- initprogram(prefered_port);
+ initprogram(synth, prefered_port);
if(!loadfile.empty()) {
int tmp = master->loadXML(loadfile.c_str());
@@ -417,11 +416,10 @@ int main(int argc, char *argv[])
cerr.precision(1);
cerr << std::fixed;
- cerr << "\nSample Rate = \t\t" << synth->samplerate << endl;
- cerr << "Sound Buffer Size = \t" << synth->buffersize << " samples" << endl;
- cerr << "Internal latency = \t" << synth->buffersize_f * 1000.0f
- / synth->samplerate_f << " ms" << endl;
- cerr << "ADsynth Oscil.Size = \t" << synth->oscilsize << " samples" << endl;
+ cerr << "\nSample Rate = \t\t" << synth.samplerate << endl;
+ cerr << "Sound Buffer Size = \t" << synth.buffersize << " samples" << endl;
+ cerr << "Internal latency = \t" << synth.dt() * 1000.0f << " ms" << endl;
+ cerr << "ADsynth Oscil.Size = \t" << synth.oscilsize << " samples" << endl;
if(!execAfterInit.empty()) {
cout << "Executing user supplied command: " << execAfterInit << endl;