2
0
Fork 0
OB-Xd/Source/Engine/ObxdOscillatorB.h

254 lines
5.3 KiB
C++
Executable File
Raw Blame History

/*
==============================================================================
This file is part of Obxd synthesizer.
Copyright <20> 2013-2014 Filatov Vadim
Contact author via email :
justdat_@_e1.ru
This file may be licensed under the terms of of the
GNU General Public License Version 2 (the ``GPL'').
Software distributed under the License is distributed
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
express or implied. See the GPL for the specific language
governing rights and limitations.
You should have received a copy of the GPL along with this
program. If not, go to http://www.gnu.org/licenses/gpl.html
or write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
==============================================================================
*/
#pragma once
#include "ObxdVoice.h"
#include "SynthEngine.h"
#include "AudioUtils.h"
#include "BlepData.h"
#include "DelayLine.h"
#include "SawOsc.h"
#include "PulseOsc.h"
#include "TriangleOsc.h"
class ObxdOscillatorB
{
private:
float SampleRate;
float pitch1;
float pitch2;
float sampleRateInv;
float x1,x2;
float osc1Factor;
float osc2Factor;
float pw1w,pw2w;
//blep const
const int n;
const int hsam;
//delay line implements fixed sample delay
DelayLine<Samples> del1,del2;
DelayLine<Samples> xmodd;
DelayLineBoolean<Samples> syncd;
DelayLine<Samples> syncFracd;
DelayLine<Samples> cvd;
Random wn;
SawOsc o1s,o2s;
PulseOsc o1p,o2p;
TriangleOsc o1t,o2t;
public:
float tune;//+-1
int oct;
float dirt;
float notePlaying;
float totalDetune;
float osc2Det;
float pulseWidth;
float pw1,pw2;
bool quantizeCw;
float o1mx,o2mx;
float nmx;
float pto1,pto2;
//osc pitches
float osc1Saw,osc2Saw,
osc1Pul,osc2Pul;
float osc1p,osc2p;
bool hardSync;
float xmod;
ObxdOscillatorB() :
n(Samples*2),
hsam(Samples),
o1s(),o2s(),
o1p(),o2p(),
o1t(),o2t()
{
dirt = 0.1;
totalDetune = 0;
wn = Random(Random::getSystemRandom().nextInt64());
osc1Factor = wn.nextFloat()-0.5;
osc2Factor = wn.nextFloat()-0.5;
nmx=0;
oct=0;
tune=0;
pw1w=pw2w=0;
pto1=pto2=0;
pw1=pw2=0;
xmod = 0;
hardSync = false;
osc1p=osc2p=10;
osc1Saw=osc2Saw=osc1Pul=osc2Pul=false;
osc2Det = 0;
notePlaying = 30;
pulseWidth = 0;
o1mx=o2mx=0;
x1=wn.nextFloat();
x2=wn.nextFloat();
//del1 = new DelayLine(hsam);
//del2 = new DelayLine(hsam);
//xmodd = new DelayLine(hsam);
//syncd = new DelayLineBoolean(hsam);
//syncFracd = new DelayLine(hsam);
//cvd = new DelayLine(hsam);
}
~ObxdOscillatorB()
{
//delete del1;
//delete del2;
//delete xmodd;
//delete cvd;
//delete syncd;
//delete syncFracd;
}
void setDecimation()
{
o1p.setDecimation();
o1t.setDecimation();
o1s.setDecimation();
o2p.setDecimation();
o2t.setDecimation();
o2s.setDecimation();
}
void removeDecimation()
{
o1p.removeDecimation();
o1t.removeDecimation();
o1s.removeDecimation();
o2p.removeDecimation();
o2t.removeDecimation();
o2s.removeDecimation();
}
void setSampleRate(float sr)
{
SampleRate = sr;
sampleRateInv = 1.0f / SampleRate;
}
inline float ProcessSample()
{
float noiseGen = wn.nextFloat()-0.5;
pitch1 = getPitch(dirt * noiseGen + notePlaying + (quantizeCw?((int)(osc1p)):osc1p)+ pto1 + tune + oct+totalDetune*osc1Factor);
bool hsr = false;
float hsfrac=0;
float fs = jmin(pitch1*(sampleRateInv),0.45f);
x1+=fs;
hsfrac = 0;
float osc1mix=0.0f;
float pwcalc =jlimit<float>(0.1f,1.0f,(pulseWidth + pw1)*0.5f + 0.5f);
if(osc1Pul)
o1p.processMaster(x1,fs,pwcalc,pw1w);
if(osc1Saw)
o1s.processMaster(x1,fs);
else if(!osc1Pul)
o1t.processMaster(x1,fs);
if(x1 >= 1.0f)
{
x1-=1.0f;
hsfrac = x1/fs;
hsr = true;
}
pw1w = pwcalc;
hsr &= hardSync;
//Delaying our hard sync gate signal and frac
hsr = syncd.feedReturn(hsr) != 0.0f;
hsfrac = syncFracd.feedReturn(hsfrac);
if(osc1Pul)
osc1mix += o1p.getValue(x1,pwcalc) + o1p.aliasReduction();
if(osc1Saw)
osc1mix += o1s.getValue(x1) + o1s.aliasReduction();
else if(!osc1Pul)
osc1mix = o1t.getValue(x1) + o1t.aliasReduction();
//Pitch control needs additional delay buffer to compensate
//This will give us less aliasing on xmod
//Hard sync gate signal delayed too
noiseGen = wn.nextFloat()-0.5;
pitch2 = getPitch(cvd.feedReturn(dirt *noiseGen + notePlaying + osc2Det + (quantizeCw?((int)(osc2p)):osc2p) + pto2+ osc1mix *xmod + tune + oct +totalDetune*osc2Factor));
fs = jmin(pitch2 * (sampleRateInv),0.45f);
pwcalc = jlimit<float>(0.1f,1.0f,(pulseWidth + pw2)*0.5f + 0.5f);
float osc2mix=0.0f;
x2 +=fs;
if(osc2Pul)
o2p.processSlave(x2,fs,hsr,hsfrac,pwcalc,pw2w);
if(osc2Saw)
o2s.processSlave(x2,fs,hsr,hsfrac);
else if(!osc2Pul)
o2t.processSlave(x2,fs,hsr,hsfrac);
if(x2 >= 1.0f)
x2-=1.0;
pw2w=pwcalc;
//On hard sync reset slave phase is affected that way
if(hsr)
{
float fracMaster = (fs * hsfrac);
x2 =fracMaster;
}
//Delaying osc1 signal
//And getting delayed back
osc1mix = xmodd.feedReturn(osc1mix);
if(osc2Pul)
osc2mix += o2p.getValue(x2,pwcalc) + o2p.aliasReduction();
if(osc2Saw)
osc2mix += o2s.getValue(x2) + o2s.aliasReduction();
else if(!osc2Pul)
osc2mix = o2t.getValue(x2) + o2t.aliasReduction();
//mixing
float res =o1mx*osc1mix + o2mx *osc2mix + (noiseGen)*(nmx*1.3 + 0.0006);
return res*3;
}
};