mirror of https://github.com/probonopd/MiniDexed
parent
75f4333831
commit
9b1ea33966
@ -0,0 +1,117 @@ |
||||
#ifndef _EFFECT_LPF_H |
||||
#define _EFFECT_LPF_H |
||||
|
||||
#include "effect_base.h" |
||||
|
||||
class AudioEffectLPF : public AudioEffect |
||||
{ |
||||
public: |
||||
static constexpr float32_t MIN_CUTOFF = 0.00001f; |
||||
static constexpr float32_t MAX_CUTOFF = 8000.0f; |
||||
static constexpr float32_t MIN_RES = 0.0f; |
||||
static constexpr float32_t MAX_RES = 1.0f; |
||||
|
||||
AudioEffectLPF(float32_t samplerate) : AudioEffect(samplerate) |
||||
{ |
||||
// Setup init values
|
||||
this->setCutoff(2000.0f); |
||||
this->setResonance(MIN_RES); |
||||
} |
||||
virtual ~AudioEffectLPF() |
||||
{ |
||||
} |
||||
|
||||
virtual unsigned getId() |
||||
{ |
||||
return EFFECT_LPF; |
||||
} |
||||
|
||||
/**
|
||||
* Set the static cutoff frequency of the filter. |
||||
* Cutoff frequency must be between MIN_CUTOFF and MAX_CUTOFF. |
||||
* Envelope signal varies the cutoff frequency from this static value. |
||||
*/
|
||||
void setCutoff(float32_t cutoff) |
||||
{ |
||||
// Check limits
|
||||
cutoff = (cutoff < MIN_CUTOFF) ? MIN_CUTOFF : cutoff; |
||||
cutoff = (cutoff > MAX_CUTOFF) ? MAX_CUTOFF : cutoff; |
||||
|
||||
this->cutoff = cutoff; |
||||
recalculate(); |
||||
} |
||||
|
||||
/**
|
||||
* Set the resonance of the filter. |
||||
* Valid values are between 0.0 and 1.0 where |
||||
* 0.0 is no resonance and 1.0 is full resonance or oscillation. |
||||
*/
|
||||
void setResonance(float32_t resonance) |
||||
{ |
||||
// Check limits
|
||||
resonance = (resonance < MIN_RES) ? MIN_RES : resonance; |
||||
resonance = (resonance > MAX_RES) ? MAX_RES : resonance; |
||||
|
||||
this->resonance = resonance; |
||||
recalculate(); |
||||
} |
||||
|
||||
protected: |
||||
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len) |
||||
{ |
||||
for (int i = 0; i < len; i++) { |
||||
// Get a sample to process
|
||||
float32_t s = inblockL[i]; |
||||
|
||||
// Return processed sample from filter
|
||||
outblockL[i] = processSample(s); |
||||
} |
||||
} |
||||
|
||||
private: |
||||
float32_t cutoff; |
||||
float32_t resonance; |
||||
float32_t x, r, p, k, y1, y2, y3, y4, oldx, oldy1, oldy2, oldy3; |
||||
|
||||
/**
|
||||
* Recalculate filter parameters on changes to cutoff or resonance |
||||
*/ |
||||
void recalculate() |
||||
{ |
||||
float32_t f = (cutoff + cutoff) / this->samplerate; |
||||
p = f * (1.8 - (0.8 * f)); |
||||
k = p + p - 1.0; |
||||
|
||||
float32_t t = (1.0 - p) * 1.386249; |
||||
float32_t t2 = 12.0 + t * t; |
||||
r = resonance * (t2 + 6.0 * t) / (t2 - 6.0 * t); |
||||
} |
||||
|
||||
/**
|
||||
* Process a single sample through the filter |
||||
*/ |
||||
float32_t processSample(float32_t input) |
||||
{ |
||||
// Process input
|
||||
//x = ((float32_t) input/ F32_MAX) - r * y4;
|
||||
x = input - r * y4; |
||||
|
||||
// Four cascaded one pole filters (bilinear transform)
|
||||
y1 = x * p + oldx * p - k * y1; |
||||
y2 = y1 * p + oldy1 * p - k * y2; |
||||
y3 = y2 * p + oldy2 * p - k * y3; |
||||
y4 = y3 * p + oldy3 * p - k * y4; |
||||
|
||||
// Clipper band limited sigmoid
|
||||
y4 -= (y4 * y4 * y4) / 6.0; |
||||
|
||||
oldx = x; |
||||
oldy1 = y1; |
||||
oldy2 = y2; |
||||
oldy3 = y3; |
||||
//return (float32_t) (y4 * F32_MAX);
|
||||
return y4; |
||||
} |
||||
}; |
||||
|
||||
#endif // _EFFECT_LPF_H
|
@ -1,8 +1,38 @@ |
||||
#ifndef _EFFECTS_H |
||||
#define _EFFECTS_H |
||||
|
||||
#include <string> |
||||
#include "effect_base.h" |
||||
#include "effect_chorus.h" |
||||
#include "effect_delay.h" |
||||
#include "effect_lpf.h" |
||||
|
||||
inline AudioEffect* newAudioEffect(unsigned type, float32_t samplerate) |
||||
{ |
||||
switch (type) |
||||
{ |
||||
case EFFECT_CHORUS: |
||||
return new AudioEffectChorus(samplerate); |
||||
case EFFECT_DELAY: |
||||
return new AudioEffectDelay(samplerate); |
||||
case EFFECT_LPF: |
||||
return new AudioEffectLPF(samplerate); |
||||
case EFFECT_NONE: |
||||
default: |
||||
return new AudioEffectNone(samplerate); |
||||
} |
||||
} |
||||
|
||||
inline std::string getFXTypeName(int nValue) |
||||
{ |
||||
switch (nValue) |
||||
{ |
||||
case EFFECT_CHORUS: return "Juno Chorus"; |
||||
case EFFECT_DELAY: return "Delay"; |
||||
case EFFECT_LPF: return "LP Filter"; |
||||
case EFFECT_NONE: |
||||
default: return "None"; |
||||
} |
||||
} |
||||
|
||||
#endif // _EFFECTS_H
|
Loading…
Reference in new issue