mirror of https://github.com/probonopd/MiniDexed
parent
afa72d21aa
commit
d98c7cf701
@ -0,0 +1,63 @@ |
||||
#include "effect.h" |
||||
|
||||
AudioEffect::AudioEffect(float32_t samplerate) |
||||
{ |
||||
this->samplerate = samplerate; |
||||
} |
||||
|
||||
AudioEffect::~AudioEffect() |
||||
{ |
||||
} |
||||
|
||||
void AudioEffect::setBypass(bool bypass) |
||||
{ |
||||
this->bypass = bypass; |
||||
} |
||||
|
||||
bool AudioEffect::getBypass() |
||||
{ |
||||
return bypass; |
||||
} |
||||
|
||||
unsigned AudioEffect::getId() |
||||
{ |
||||
return EFFECT_NONE; |
||||
} |
||||
|
||||
void AudioEffect::process(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len) |
||||
{ |
||||
if (bypass) { |
||||
return; |
||||
} |
||||
doProcess(inblockL, inblockR, outblockL, outblockR, len); |
||||
} |
||||
|
||||
void AudioEffect::doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len) { |
||||
for (uint16_t i=0; i < len; i++)
|
||||
{ |
||||
outblockL[i] = inblockL[i]; |
||||
outblockR[i] = inblockR[i]; |
||||
} |
||||
} |
||||
|
||||
AudioEffectNone::AudioEffectNone(float32_t samplerate) : AudioEffect(samplerate) |
||||
{ |
||||
} |
||||
|
||||
AudioEffectNone::~AudioEffectNone() |
||||
{ |
||||
} |
||||
|
||||
void AudioEffectNone::doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len) |
||||
{ |
||||
for (uint16_t i=0; i < len; i++)
|
||||
{ |
||||
outblockL[i] = inblockL[i]; |
||||
outblockR[i] = inblockR[i]; |
||||
} |
||||
} |
||||
|
||||
unsigned AudioEffectNone::getId() |
||||
{ |
||||
return EFFECT_NONE; |
||||
} |
@ -0,0 +1,42 @@ |
||||
#ifndef _EFFECT_H |
||||
#define _EFFECT_H |
||||
|
||||
#include <stdint.h> |
||||
#include <arm_math.h> |
||||
#include "common.h" |
||||
|
||||
#define EFFECT_NONE 0 |
||||
#define EFFECT_CHORUS 1 |
||||
#define EFFECT_DELAY 2 |
||||
|
||||
class AudioEffect |
||||
{ |
||||
public: |
||||
AudioEffect(float32_t samplerate); |
||||
virtual ~AudioEffect(); |
||||
|
||||
void setBypass(bool bypass); |
||||
bool getBypass(); |
||||
|
||||
virtual unsigned getId(); |
||||
|
||||
void process(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len); |
||||
protected: |
||||
bool bypass = false; |
||||
float32_t samplerate; |
||||
|
||||
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len); |
||||
}; |
||||
|
||||
class AudioEffectNone : public AudioEffect |
||||
{ |
||||
public: |
||||
AudioEffectNone(float32_t samplerate); |
||||
virtual ~AudioEffectNone(); |
||||
|
||||
virtual unsigned getId(); |
||||
protected: |
||||
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len); |
||||
}; |
||||
|
||||
#endif // _EFFECT_H
|
@ -0,0 +1,73 @@ |
||||
#include <circle/logger.h> |
||||
#include "effect_chorus.h" |
||||
|
||||
LOGMODULE ("fx chorus"); |
||||
|
||||
AudioEffectChorus::AudioEffectChorus(float32_t samplerate) : AudioEffect(samplerate) |
||||
{ |
||||
engine = new ChorusEngine(samplerate); |
||||
|
||||
engine->setEnablesChorus(true, true); |
||||
engine->setChorus1LfoRate(5.0f / 10.0f); |
||||
engine->setChorus2LfoRate(8.3f / 10.0f); |
||||
} |
||||
|
||||
AudioEffectChorus::~AudioEffectChorus() |
||||
{ |
||||
delete engine; |
||||
} |
||||
|
||||
unsigned AudioEffectChorus::getId() |
||||
{ |
||||
return EFFECT_CHORUS; |
||||
} |
||||
|
||||
void AudioEffectChorus::doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len) |
||||
{ |
||||
for (uint16_t i=0; i < len; i++)
|
||||
{ |
||||
outblockL[i] = inblockL[i]; |
||||
outblockR[i] = inblockR[i]; |
||||
engine->process(&outblockL[i], &outblockR[i]); |
||||
} |
||||
} |
||||
|
||||
unsigned AudioEffectChorus::getChorusI() |
||||
{ |
||||
return engine->isChorus1Enabled; |
||||
} |
||||
|
||||
void AudioEffectChorus::setChorusI(unsigned enable) |
||||
{ |
||||
engine->setEnablesChorus(enable == 1, engine->isChorus2Enabled); |
||||
} |
||||
|
||||
unsigned AudioEffectChorus::getChorusII() |
||||
{ |
||||
return engine->isChorus2Enabled; |
||||
} |
||||
|
||||
void AudioEffectChorus::setChorusII(unsigned enable) |
||||
{ |
||||
engine->setEnablesChorus(engine->isChorus1Enabled, enable == 1); |
||||
} |
||||
|
||||
unsigned AudioEffectChorus::getChorusIRate() |
||||
{ |
||||
return (int) roundf(engine->chorus1L->rate * 100); |
||||
} |
||||
|
||||
void AudioEffectChorus::setChorusIRate(unsigned int rate) |
||||
{ |
||||
engine->setChorus1LfoRate(((float) rate) / 100.0f); |
||||
} |
||||
|
||||
unsigned AudioEffectChorus::getChorusIIRate() |
||||
{ |
||||
return (int) roundf(engine->chorus2L->rate * 100); |
||||
} |
||||
|
||||
void AudioEffectChorus::setChorusIIRate(unsigned int rate) |
||||
{ |
||||
engine->setChorus2LfoRate(((float) rate) / 100.0f); |
||||
} |
@ -0,0 +1,33 @@ |
||||
#ifndef _EFFECT_CHORUS_H |
||||
#define _EFFECT_CHORUS_H |
||||
|
||||
#include "effect.h" |
||||
#include "ykchorus/ChorusEngine.h" |
||||
|
||||
class AudioEffectChorus : public AudioEffect |
||||
{ |
||||
public: |
||||
AudioEffectChorus(float32_t samplerate); |
||||
virtual ~AudioEffectChorus(); |
||||
|
||||
virtual unsigned getId(); |
||||
|
||||
unsigned getChorusI(); |
||||
void setChorusI(unsigned enable); |
||||
|
||||
unsigned getChorusII(); |
||||
void setChorusII(unsigned enable); |
||||
|
||||
unsigned getChorusIRate(); |
||||
void setChorusIRate(unsigned int rate); |
||||
|
||||
unsigned getChorusIIRate(); |
||||
void setChorusIIRate(unsigned int rate); |
||||
protected: |
||||
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len); |
||||
|
||||
private: |
||||
ChorusEngine *engine; |
||||
}; |
||||
|
||||
#endif // _EFFECT_CHORUS_H
|
@ -0,0 +1,26 @@ |
||||
#include <circle/logger.h> |
||||
#include "effect_delay.h" |
||||
|
||||
LOGMODULE ("fx chorus"); |
||||
|
||||
AudioEffectDelay::AudioEffectDelay(float32_t samplerate) : AudioEffect(samplerate) |
||||
{
|
||||
} |
||||
|
||||
AudioEffectDelay::~AudioEffectDelay() |
||||
{ |
||||
} |
||||
|
||||
unsigned AudioEffectDelay::getId() |
||||
{ |
||||
return EFFECT_DELAY; |
||||
} |
||||
|
||||
void AudioEffectDelay::doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len) |
||||
{ |
||||
for (uint16_t i=0; i < len; i++)
|
||||
{ |
||||
outblockL[i] = inblockL[i]; |
||||
outblockR[i] = inblockR[i]; |
||||
} |
||||
} |
@ -0,0 +1,26 @@ |
||||
#ifndef _EFFECT_DELAY_H |
||||
#define _EFFECT_DELAY_H |
||||
|
||||
#include "effect.h" |
||||
|
||||
class AudioEffectDelay : public AudioEffect |
||||
{ |
||||
public: |
||||
AudioEffectDelay(float32_t samplerate); |
||||
virtual ~AudioEffectDelay(); |
||||
|
||||
virtual unsigned getId(); |
||||
protected: |
||||
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len); |
||||
// private:
|
||||
// const size_t MaxSampleDelayTime;
|
||||
// unsigned write_pos_L_;
|
||||
// unsigned write_pos_R_;
|
||||
// float32_t* buffer_L_;
|
||||
// float32_t* buffer_R_;
|
||||
// float32_t delay_time_L_; // Left delay time in seconds (0.0 - 2.0)
|
||||
// float32_t delay_time_R_; // Right delay time in seconds (0.0 - 2.0)
|
||||
// float32_t feedback_; // Feedback (0.0 - 1.0)
|
||||
}; |
||||
|
||||
#endif // _EFFECT_DELAY_H
|
@ -0,0 +1,143 @@ |
||||
/*
|
||||
============================================================================== |
||||
This file is part of Tal-NoiseMaker by Patrick Kunz. |
||||
|
||||
Copyright(c) 2005-2010 Patrick Kunz, TAL |
||||
Togu Audio Line, Inc. |
||||
http://kunz.corrupt.ch
|
||||
|
||||
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. |
||||
============================================================================== |
||||
*/ |
||||
|
||||
#if !defined(__Chorus_h) |
||||
#define __Chorus_h |
||||
|
||||
#include "OnePoleLP.h" |
||||
#include "math.h" |
||||
|
||||
class Chorus { |
||||
public: |
||||
float *delayLineStart; |
||||
float *delayLineEnd; |
||||
float *writePtr; |
||||
|
||||
int delayLineLength; |
||||
float rate; |
||||
float delayLineOutput; |
||||
|
||||
float sampleRate; |
||||
float delayTime; |
||||
|
||||
// Runtime variables
|
||||
float offset, diff, frac, *ptr, *ptr2; |
||||
|
||||
int readPos; |
||||
|
||||
OnePoleLP *lp; |
||||
float z1; |
||||
float mult, sign; |
||||
|
||||
// lfo
|
||||
float lfoPhase, lfoStepSize, lfoSign; |
||||
|
||||
Chorus(float sampleRate, float phase, float rate, float delayTime) { |
||||
this->rate = rate; |
||||
this->sampleRate = sampleRate; |
||||
this->delayTime = delayTime; |
||||
z1 = 0.0f; |
||||
sign = 0; |
||||
lfoPhase = phase * 2.0f - 1.0f; |
||||
lfoStepSize = (4.0f * rate / sampleRate); |
||||
lfoSign = 1.0f; |
||||
|
||||
// Compute required buffer size for desired delay and allocate it
|
||||
// Add extra point to aid in interpolation later
|
||||
delayLineLength = ((int)floorf(delayTime * sampleRate * 0.001f) * 2); |
||||
delayLineStart = new float[delayLineLength]; |
||||
|
||||
// Set up pointers for delay line
|
||||
delayLineEnd = delayLineStart + delayLineLength; |
||||
writePtr = delayLineStart; |
||||
|
||||
// Zero out the buffer (silence)
|
||||
do { |
||||
*writePtr = 0.0f; |
||||
} |
||||
while (++writePtr < delayLineEnd); |
||||
|
||||
// Set read pointer to end of delayline. Setting it to the end
|
||||
// ensures the interpolation below works correctly to produce
|
||||
// the first non-zero sample.
|
||||
writePtr = delayLineStart + delayLineLength -1; |
||||
delayLineOutput = 0.0f; |
||||
lp = new OnePoleLP(); |
||||
} |
||||
|
||||
~Chorus() { |
||||
delete[] delayLineStart; |
||||
delete lp; |
||||
} |
||||
|
||||
void setLfoRate(float rate) { |
||||
this->rate = rate; |
||||
lfoStepSize = (4.0f * rate / sampleRate); |
||||
} |
||||
|
||||
float process(float *sample) { |
||||
// Get delay time
|
||||
offset = (nextLFO() * 0.3f + 0.4f) * delayTime * sampleRate * 0.001f; |
||||
|
||||
// Compute the largest read pointer based on the offset. If ptr
|
||||
// is before the first delayline location, wrap around end point
|
||||
ptr = writePtr - (int)floorf(offset); |
||||
if (ptr < delayLineStart) |
||||
ptr += delayLineLength; |
||||
|
||||
ptr2 = ptr - 1; |
||||
if (ptr2 < delayLineStart) |
||||
ptr2 += delayLineLength; |
||||
|
||||
frac = offset - (int)floorf(offset); |
||||
delayLineOutput = *ptr2 + *ptr * (1 - frac) - (1 - frac) * z1; |
||||
z1 = delayLineOutput; |
||||
|
||||
// Low pass
|
||||
lp->tick(&delayLineOutput, 0.95f); |
||||
|
||||
// Write the input sample and any feedback to delayline
|
||||
*writePtr = *sample; |
||||
|
||||
// Increment buffer index and wrap if necesary
|
||||
if (++writePtr >= delayLineEnd) { |
||||
writePtr = delayLineStart; |
||||
} |
||||
return delayLineOutput; |
||||
} |
||||
|
||||
inline float nextLFO() { |
||||
if (lfoPhase >= 1.0f) |
||||
{ |
||||
lfoSign = -1.0f; |
||||
} |
||||
else if (lfoPhase <= -1.0f) |
||||
{ |
||||
lfoSign = +1.0f; |
||||
} |
||||
lfoPhase += lfoStepSize * lfoSign; |
||||
return lfoPhase; |
||||
} |
||||
}; |
||||
|
||||
#endif |
@ -0,0 +1,114 @@ |
||||
/*
|
||||
============================================================================== |
||||
This file is part of Tal-NoiseMaker by Patrick Kunz. |
||||
|
||||
Copyright(c) 2005-2010 Patrick Kunz, TAL |
||||
Togu Audio Line, Inc. |
||||
http://kunz.corrupt.ch
|
||||
|
||||
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. |
||||
============================================================================== |
||||
*/ |
||||
|
||||
#if !defined(__ChorusEngine_h) |
||||
#define __ChorusEngine_h |
||||
|
||||
#include "Chorus.h" |
||||
#include "DCBlock.h" |
||||
|
||||
|
||||
class ChorusEngine { |
||||
public: |
||||
Chorus *chorus1L; |
||||
Chorus *chorus1R; |
||||
Chorus *chorus2L; |
||||
Chorus *chorus2R; |
||||
|
||||
DCBlock *dcBlock1L; |
||||
DCBlock *dcBlock1R; |
||||
DCBlock *dcBlock2L; |
||||
DCBlock *dcBlock2R; |
||||
|
||||
bool isChorus1Enabled; |
||||
bool isChorus2Enabled; |
||||
|
||||
ChorusEngine(float sampleRate) { |
||||
dcBlock1L = new DCBlock(); |
||||
dcBlock1R = new DCBlock(); |
||||
dcBlock2L = new DCBlock(); |
||||
dcBlock2R = new DCBlock(); |
||||
|
||||
setUpChorus(sampleRate); |
||||
} |
||||
|
||||
~ChorusEngine() { |
||||
delete chorus1L; |
||||
delete chorus1R; |
||||
delete chorus2L; |
||||
delete chorus2R; |
||||
delete dcBlock1L; |
||||
delete dcBlock1R; |
||||
delete dcBlock2L; |
||||
delete dcBlock2R; |
||||
} |
||||
|
||||
void setSampleRate(float sampleRate) { |
||||
setUpChorus(sampleRate); |
||||
} |
||||
|
||||
void setEnablesChorus(bool isChorus1Enabled, bool isChorus2Enabled) { |
||||
this->isChorus1Enabled = isChorus1Enabled; |
||||
this->isChorus2Enabled = isChorus2Enabled; |
||||
} |
||||
|
||||
void setChorus1LfoRate(float rate) { |
||||
chorus1L->setLfoRate(rate); |
||||
chorus1R->setLfoRate(rate); |
||||
} |
||||
|
||||
void setChorus2LfoRate(float rate) { |
||||
chorus2L->setLfoRate(rate); |
||||
chorus2R->setLfoRate(rate); |
||||
} |
||||
|
||||
void setUpChorus(float sampleRate) { |
||||
chorus1L = new Chorus(sampleRate, 1.0f, 0.5f, 7.0f); |
||||
chorus1R = new Chorus(sampleRate, 0.0f, 0.5f, 7.0f); |
||||
chorus2L = new Chorus(sampleRate, 0.0f, 0.83f, 7.0f); |
||||
chorus2R = new Chorus(sampleRate, 1.0f, 0.83f, 7.0f); |
||||
} |
||||
|
||||
inline void process(float *sampleL, float *sampleR) { |
||||
float resultR = 0.0f; |
||||
float resultL = 0.0f; |
||||
if (isChorus1Enabled) |
||||
{ |
||||
resultL += chorus1L->process(sampleL); |
||||
resultR += chorus1R->process(sampleR); |
||||
dcBlock1L->tick(&resultL, 0.01f); |
||||
dcBlock1R->tick(&resultR, 0.01f); |
||||
} |
||||
if (isChorus2Enabled) |
||||
{ |
||||
resultL += chorus2L->process(sampleL); |
||||
resultR += chorus2R->process(sampleR); |
||||
dcBlock2L->tick(&resultL, 0.01f); |
||||
dcBlock2R->tick(&resultR, 0.01f); |
||||
} |
||||
*sampleL = *sampleL + resultL * 1.4f; |
||||
*sampleR = *sampleR + resultR * 1.4f; |
||||
} |
||||
}; |
||||
|
||||
#endif |
@ -0,0 +1,45 @@ |
||||
/*
|
||||
============================================================================== |
||||
This file is part of Tal-NoiseMaker by Patrick Kunz. |
||||
|
||||
Copyright(c) 2005-2010 Patrick Kunz, TAL |
||||
Togu Audio Line, Inc. |
||||
http://kunz.corrupt.ch
|
||||
|
||||
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. |
||||
============================================================================== |
||||
*/ |
||||
|
||||
#if !defined(__DCBlock_h) |
||||
#define __DCBlock_h |
||||
|
||||
class DCBlock { |
||||
public: |
||||
float inputs, outputs, lastOutput; |
||||
|
||||
DCBlock() { |
||||
lastOutput = inputs = outputs = 0.0f; |
||||
} |
||||
|
||||
~DCBlock() {} |
||||
|
||||
inline void tick(float *sample, float cutoff) { |
||||
outputs = *sample - inputs + (0.999f - cutoff * 0.4f) * outputs; |
||||
inputs = *sample; |
||||
lastOutput = outputs; |
||||
*sample = lastOutput; |
||||
} |
||||
}; |
||||
|
||||
#endif |
@ -0,0 +1,44 @@ |
||||
/*
|
||||
============================================================================== |
||||
This file is part of Tal-NoiseMaker by Patrick Kunz. |
||||
|
||||
Copyright(c) 2005-2010 Patrick Kunz, TAL |
||||
Togu Audio Line, Inc. |
||||
http://kunz.corrupt.ch
|
||||
|
||||
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. |
||||
============================================================================== |
||||
*/ |
||||
|
||||
#if !defined(__OnePoleLP_h) |
||||
#define __OnePoleLP_h |
||||
|
||||
class OnePoleLP { |
||||
public: |
||||
float inputs, outputs, lastOutput; |
||||
|
||||
OnePoleLP() { |
||||
lastOutput = inputs = outputs = 0.0f; |
||||
} |
||||
|
||||
~OnePoleLP() {} |
||||
|
||||
void tick(float *sample, float cutoff) { |
||||
float p = (cutoff * 0.98f) * (cutoff * 0.98f) * (cutoff * 0.98f) * (cutoff * 0.98f); |
||||
outputs = (1.0f - p) * (*sample) + p * outputs; |
||||
*sample = outputs; |
||||
} |
||||
}; |
||||
|
||||
#endif |
Loading…
Reference in new issue