fixed filter issues
This commit is contained in:
@@ -15,7 +15,7 @@ void Filter::setSampleRate(float sampleRate) {
|
||||
|
||||
void Filter::setParams(Type type, float frequency, float q) {
|
||||
type_ = type;
|
||||
frequency_ = frequency;
|
||||
frequency_ = std::min(frequency, sampleRate_ / 2.0f * 0.999f);
|
||||
q_ = q;
|
||||
calculateCoefficients();
|
||||
}
|
||||
@@ -23,11 +23,11 @@ void Filter::setParams(Type type, float frequency, float q) {
|
||||
float Filter::biquadProcess(float in) {
|
||||
|
||||
// calculate filtered sample
|
||||
float out = a0_ * in + z1_;
|
||||
float out = b0_ * in + z1_;
|
||||
|
||||
// update states
|
||||
z1_ = a1_ * in - b1_ * out + z2_;
|
||||
z2_ = a2_ * in - b2_ * out;
|
||||
z1_ = b1_ * in - a1_ * out + z2_;
|
||||
z2_ = b2_ * in - a2_ * out;
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -73,11 +73,11 @@ void Filter::calculateCoefficients() {
|
||||
}
|
||||
|
||||
// Normalize
|
||||
a0_ = b0 / a0;
|
||||
a1_ = b1 / a0;
|
||||
a2_ = b2 / a0;
|
||||
b1_ = a1 / a0;
|
||||
b2_ = a2 / a0;
|
||||
b0_ = b0 / a0;
|
||||
b1_ = b1 / a0;
|
||||
b2_ = b2 / a0;
|
||||
a1_ = a1 / a0;
|
||||
a2_ = a2 / a0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ private:
|
||||
float q_ = 0.707f;
|
||||
|
||||
// biquad filter structure
|
||||
float a0_, a1_, a2_, b1_, b2_;
|
||||
float a1_, a2_, b0_, b1_, b2_;
|
||||
float z1_, z2_;
|
||||
|
||||
};
|
||||
@@ -87,8 +87,9 @@ void Synth::process(float* out, uint32_t nFrames, uint32_t sampleRate) {
|
||||
gainEnvelope_.set(getParam(ParamId::Osc1VolumeEnvA), getParam(ParamId::Osc1VolumeEnvD), getParam(ParamId::Osc1VolumeEnvS), getParam(ParamId::Osc1VolumeEnvR));
|
||||
cutoffEnvelope_.set(getParam(ParamId::FilterCutoffEnvA), getParam(ParamId::FilterCutoffEnvD), getParam(ParamId::FilterCutoffEnvS), getParam(ParamId::FilterCutoffEnvR));
|
||||
resonanceEnvelope_.set(getParam(ParamId::FilterResonanceEnvA), getParam(ParamId::FilterResonanceEnvD), getParam(ParamId::FilterResonanceEnvS), getParam(ParamId::FilterResonanceEnvR));
|
||||
float gain = gainEnvelope_.process();
|
||||
filter_.setParams(Filter::Type::BiquadLowpass, cutoffEnvelope_.process(), resonanceEnvelope_.process());
|
||||
float gainEnv = gainEnvelope_.process();
|
||||
float cutoffEnv = cutoffEnvelope_.process();
|
||||
float resonanceEnv = resonanceEnvelope_.process();
|
||||
// TODO: envelope is shared between all notes so this sequence involves a note change but only one envelope attack:
|
||||
// NOTE_A_ON > NOTE_B_ON > NOTE_A_OFF and note B starts playing part-way through note A's envelope
|
||||
|
||||
@@ -106,6 +107,8 @@ void Synth::process(float* out, uint32_t nFrames, uint32_t sampleRate) {
|
||||
float pitchOffset = 0.5f;
|
||||
float phaseInc = pitchOffset * 2.0f * M_PI * frequency_ / static_cast<float>(sampleRate);
|
||||
|
||||
float gain = gainEnv * getParam(ParamId::Osc1Volume);
|
||||
|
||||
// sample generation
|
||||
// TODO: wavetables
|
||||
// TODO: wavetables should be scaled by their RMS for equal loudness (prelim standard = 0.707)
|
||||
@@ -132,6 +135,8 @@ void Synth::process(float* out, uint32_t nFrames, uint32_t sampleRate) {
|
||||
}
|
||||
|
||||
// filter sample
|
||||
float cutoffFreq = cutoffEnv * pow(2.0f, getParam(ParamId::FilterCutoff)) * frequency_;
|
||||
filter_.setParams(Filter::Type::BiquadLowpass, cutoffFreq, resonanceEnv * getParam(ParamId::FilterResonance));
|
||||
sampleOut = filter_.biquadProcess(sampleOut);
|
||||
|
||||
// write to buffer
|
||||
|
||||
Reference in New Issue
Block a user