You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
1.6 KiB
63 lines
1.6 KiB
#ifndef __VOICE_H__
|
|
#define __VOICE_H__
|
|
|
|
#include "globals.h"
|
|
#include "preset.h"
|
|
|
|
#include "dsp/oscillator.h"
|
|
#include "dsp/filter.h"
|
|
#include "dsp/adsr.h"
|
|
|
|
class Voice {
|
|
public:
|
|
typedef struct {
|
|
Oscillator::Mode osc1Mode;
|
|
Oscillator::Mode osc2Mode;
|
|
float oscMix;
|
|
float oscDetune;
|
|
float osc2Pitch;
|
|
|
|
Filter::Settings filter;
|
|
|
|
ADSR::Envelope ampEnv;
|
|
ADSR::Envelope modEnv;
|
|
|
|
float modEnvFltGain;
|
|
float keyTrack;
|
|
float lfoStep;
|
|
float lfoPitchMod;
|
|
float lfoFltMod;
|
|
} Settings;
|
|
|
|
private:
|
|
Settings const * settings;
|
|
|
|
ADSR adsrAmp;
|
|
ADSR adsrMod;
|
|
Oscillator osc1;
|
|
Oscillator osc2;
|
|
Filter filter;
|
|
|
|
public:
|
|
int note;
|
|
|
|
void reset();
|
|
void assign(Settings const * settings);
|
|
void noteOn(int note);
|
|
void noteOff();
|
|
inline bool isIdle() { return adsrAmp.isIdle(); }
|
|
|
|
inline float tick(float pitchAdd, float fltFreqAdd) {
|
|
const float osc1PhaseStep = noteToFreq(note + pitchAdd - settings->oscDetune) * PIx2 / SAMPLE_RATE;
|
|
const float osc2PhaseStep = noteToFreq(note + pitchAdd + settings->oscDetune + settings->osc2Pitch) * PIx2 / SAMPLE_RATE;
|
|
float out = 0;
|
|
out += (1 - settings->oscMix) * osc1.tick(osc1PhaseStep);
|
|
out += settings->oscMix * osc2.tick(osc2PhaseStep);
|
|
const float keyTrackVal = settings->keyTrack * noteToFltFreq(note);
|
|
out = filter.tick(out, settings->modEnvFltGain * adsrMod.tick() + keyTrackVal + fltFreqAdd);
|
|
out *= adsrAmp.tick();
|
|
return out;
|
|
}
|
|
};
|
|
|
|
#endif |