mirror of https://github.com/probonopd/MiniDexed
parent
f0e2593e81
commit
aae85e5f85
@ -0,0 +1,179 @@ |
|||||||
|
/*
|
||||||
|
* Phaser Port |
||||||
|
* Ported from https://github.com/ssj71/rkrlv2
|
||||||
|
*
|
||||||
|
* Javier Nonis (https://github.com/jnonis) - 2024
|
||||||
|
*/ |
||||||
|
#ifndef _EFFECT_APHASER_H |
||||||
|
#define _EFFECT_APHASER_H |
||||||
|
|
||||||
|
#include "effect_base.h" |
||||||
|
#include "rkrlv2/APhaser.h" |
||||||
|
|
||||||
|
class AudioEffectAPhaser : public AudioEffect |
||||||
|
{ |
||||||
|
public: |
||||||
|
enum Param |
||||||
|
{ |
||||||
|
BYPASS, |
||||||
|
WETDRY, |
||||||
|
PAN, |
||||||
|
PH_FREQ, |
||||||
|
PH_RND, |
||||||
|
TYPE, |
||||||
|
STDL, |
||||||
|
PH_DEPTH, |
||||||
|
FB, |
||||||
|
STAGES, |
||||||
|
LRCR, |
||||||
|
SUB, |
||||||
|
PHASE, |
||||||
|
UNKNOWN |
||||||
|
}; |
||||||
|
|
||||||
|
AudioEffectAPhaser(float32_t samplerate) : AudioEffect(samplerate) |
||||||
|
{ |
||||||
|
this->phaser = new Analog_Phaser(0, 0, (double) samplerate); |
||||||
|
this->init_params = true; |
||||||
|
|
||||||
|
this->phaser->setpreset(0); |
||||||
|
/*
|
||||||
|
this->setParameter(AudioEffectAPhaser::Param::WETDRY, 64); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::PAN, 64); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::PH_FREQ, 11); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::PH_RND, 0); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::TYPE, 0); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::STDL, 64); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::PH_DEPTH, 110); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::FB, 64); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::STAGES, 4); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::LRCR, 0); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::SUB, 0); |
||||||
|
this->setParameter(AudioEffectAPhaser::Param::PHASE, 20); |
||||||
|
*/ |
||||||
|
} |
||||||
|
|
||||||
|
virtual ~AudioEffectAPhaser() |
||||||
|
{ |
||||||
|
delete this->phaser; |
||||||
|
} |
||||||
|
|
||||||
|
virtual unsigned getId() |
||||||
|
{ |
||||||
|
return EFFECT_APHASER; |
||||||
|
} |
||||||
|
|
||||||
|
virtual void setParameter(unsigned param, unsigned value) |
||||||
|
{ |
||||||
|
switch (param) |
||||||
|
{ |
||||||
|
case AudioEffectAPhaser::Param::BYPASS: |
||||||
|
this->setBypass(value == 1); |
||||||
|
this->phaser->cleanup(); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::WETDRY: |
||||||
|
this->phaser->changepar(0, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::PAN: |
||||||
|
this->phaser->changepar(1, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::PH_FREQ: |
||||||
|
this->phaser->changepar(2, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::PH_RND: |
||||||
|
this->phaser->changepar(3, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::TYPE: |
||||||
|
this->phaser->changepar(4, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::STDL: |
||||||
|
this->phaser->changepar(5, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::PH_DEPTH: |
||||||
|
this->phaser->changepar(6, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::FB: |
||||||
|
this->phaser->changepar(7, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::STAGES: |
||||||
|
this->phaser->changepar(8, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::LRCR: |
||||||
|
this->phaser->changepar(9, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::SUB: |
||||||
|
this->phaser->changepar(10, value); |
||||||
|
break; |
||||||
|
case AudioEffectAPhaser::Param::PHASE: |
||||||
|
this->phaser->changepar(11, value); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
virtual unsigned getParameter(unsigned param) |
||||||
|
{ |
||||||
|
switch (param) |
||||||
|
{ |
||||||
|
case AudioEffectAPhaser::Param::BYPASS: |
||||||
|
return this->getBypass() ? 1 : 0; |
||||||
|
case AudioEffectAPhaser::Param::WETDRY: |
||||||
|
return this->phaser->getpar(0); |
||||||
|
case AudioEffectAPhaser::Param::PAN: |
||||||
|
return this->phaser->getpar(1); |
||||||
|
case AudioEffectAPhaser::Param::PH_FREQ: |
||||||
|
return this->phaser->getpar(2); |
||||||
|
case AudioEffectAPhaser::Param::PH_RND: |
||||||
|
return this->phaser->getpar(3); |
||||||
|
case AudioEffectAPhaser::Param::TYPE: |
||||||
|
return this->phaser->getpar(4); |
||||||
|
case AudioEffectAPhaser::Param::STDL: |
||||||
|
return this->phaser->getpar(5); |
||||||
|
case AudioEffectAPhaser::Param::PH_DEPTH: |
||||||
|
return this->phaser->getpar(6); |
||||||
|
case AudioEffectAPhaser::Param::FB: |
||||||
|
return this->phaser->getpar(7); |
||||||
|
case AudioEffectAPhaser::Param::STAGES: |
||||||
|
return this->phaser->getpar(8); |
||||||
|
case AudioEffectAPhaser::Param::LRCR: |
||||||
|
return this->phaser->getpar(9); |
||||||
|
case AudioEffectAPhaser::Param::SUB: |
||||||
|
return this->phaser->getpar(10); |
||||||
|
case AudioEffectAPhaser::Param::PHASE: |
||||||
|
return this->phaser->getpar(11); |
||||||
|
default: |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected: |
||||||
|
virtual size_t getParametersSize() |
||||||
|
{ |
||||||
|
return AudioEffectAPhaser::Param::UNKNOWN; |
||||||
|
} |
||||||
|
|
||||||
|
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len) |
||||||
|
{ |
||||||
|
// LFO effects require period be set before setting other params
|
||||||
|
if(this->init_params) |
||||||
|
{ |
||||||
|
this->phaser->PERIOD = len; |
||||||
|
this->phaser->lfo->updateparams(len); |
||||||
|
this->init_params = false; // so we only do this once
|
||||||
|
} |
||||||
|
|
||||||
|
// now set out ports and global period size
|
||||||
|
this->phaser->efxoutl = outblockL; |
||||||
|
this->phaser->efxoutr = outblockR; |
||||||
|
|
||||||
|
//now run
|
||||||
|
this->phaser->out((float*) inblockL, (float*) inblockR, len); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
Analog_Phaser* phaser; |
||||||
|
bool init_params; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // _EFFECT_PHASER_H
|
@ -0,0 +1,179 @@ |
|||||||
|
/*
|
||||||
|
* Phaser Port |
||||||
|
* Ported from https://github.com/ssj71/rkrlv2
|
||||||
|
*
|
||||||
|
* Javier Nonis (https://github.com/jnonis) - 2024
|
||||||
|
*/ |
||||||
|
#ifndef _EFFECT_PHASER_H |
||||||
|
#define _EFFECT_PHASER_H |
||||||
|
|
||||||
|
#include "effect_base.h" |
||||||
|
#include "rkrlv2/Phaser.h" |
||||||
|
|
||||||
|
class AudioEffectPhaser : public AudioEffect |
||||||
|
{ |
||||||
|
public: |
||||||
|
enum Param |
||||||
|
{ |
||||||
|
BYPASS, |
||||||
|
WETDRY, |
||||||
|
PAN, |
||||||
|
PH_FREQ, |
||||||
|
PH_RND, |
||||||
|
TYPE, |
||||||
|
STDL, |
||||||
|
PH_DEPTH, |
||||||
|
FB, |
||||||
|
STAGES, |
||||||
|
LRCR, |
||||||
|
SUB, |
||||||
|
PHASE, |
||||||
|
UNKNOWN |
||||||
|
}; |
||||||
|
|
||||||
|
AudioEffectPhaser(float32_t samplerate) : AudioEffect(samplerate) |
||||||
|
{ |
||||||
|
this->phaser = new Phaser(0, 0, (double) samplerate); |
||||||
|
this->init_params = true; |
||||||
|
|
||||||
|
this->phaser->setpreset(0); |
||||||
|
/*
|
||||||
|
this->setParameter(AudioEffectPhaser::Param::WETDRY, 64); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::PAN, 64); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::PH_FREQ, 11); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::PH_RND, 0); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::TYPE, 0); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::STDL, 64); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::PH_DEPTH, 110); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::FB, 64); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::STAGES, 4); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::LRCR, 0); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::SUB, 0); |
||||||
|
this->setParameter(AudioEffectPhaser::Param::PHASE, 20); |
||||||
|
*/ |
||||||
|
} |
||||||
|
|
||||||
|
virtual ~AudioEffectPhaser() |
||||||
|
{ |
||||||
|
delete this->phaser; |
||||||
|
} |
||||||
|
|
||||||
|
virtual unsigned getId() |
||||||
|
{ |
||||||
|
return EFFECT_PHASER; |
||||||
|
} |
||||||
|
|
||||||
|
virtual void setParameter(unsigned param, unsigned value) |
||||||
|
{ |
||||||
|
switch (param) |
||||||
|
{ |
||||||
|
case AudioEffectPhaser::Param::BYPASS: |
||||||
|
this->setBypass(value == 1); |
||||||
|
this->phaser->cleanup(); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::WETDRY: |
||||||
|
this->phaser->changepar(0, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::PAN: |
||||||
|
this->phaser->changepar(1, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::PH_FREQ: |
||||||
|
this->phaser->changepar(2, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::PH_RND: |
||||||
|
this->phaser->changepar(3, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::TYPE: |
||||||
|
this->phaser->changepar(4, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::STDL: |
||||||
|
this->phaser->changepar(5, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::PH_DEPTH: |
||||||
|
this->phaser->changepar(6, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::FB: |
||||||
|
this->phaser->changepar(7, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::STAGES: |
||||||
|
this->phaser->changepar(8, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::LRCR: |
||||||
|
this->phaser->changepar(9, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::SUB: |
||||||
|
this->phaser->changepar(10, value); |
||||||
|
break; |
||||||
|
case AudioEffectPhaser::Param::PHASE: |
||||||
|
this->phaser->changepar(11, value); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
virtual unsigned getParameter(unsigned param) |
||||||
|
{ |
||||||
|
switch (param) |
||||||
|
{ |
||||||
|
case AudioEffectPhaser::Param::BYPASS: |
||||||
|
return this->getBypass() ? 1 : 0; |
||||||
|
case AudioEffectPhaser::Param::WETDRY: |
||||||
|
return this->phaser->getpar(0); |
||||||
|
case AudioEffectPhaser::Param::PAN: |
||||||
|
return this->phaser->getpar(1); |
||||||
|
case AudioEffectPhaser::Param::PH_FREQ: |
||||||
|
return this->phaser->getpar(2); |
||||||
|
case AudioEffectPhaser::Param::PH_RND: |
||||||
|
return this->phaser->getpar(3); |
||||||
|
case AudioEffectPhaser::Param::TYPE: |
||||||
|
return this->phaser->getpar(4); |
||||||
|
case AudioEffectPhaser::Param::STDL: |
||||||
|
return this->phaser->getpar(5); |
||||||
|
case AudioEffectPhaser::Param::PH_DEPTH: |
||||||
|
return this->phaser->getpar(6); |
||||||
|
case AudioEffectPhaser::Param::FB: |
||||||
|
return this->phaser->getpar(7); |
||||||
|
case AudioEffectPhaser::Param::STAGES: |
||||||
|
return this->phaser->getpar(8); |
||||||
|
case AudioEffectPhaser::Param::LRCR: |
||||||
|
return this->phaser->getpar(9); |
||||||
|
case AudioEffectPhaser::Param::SUB: |
||||||
|
return this->phaser->getpar(10); |
||||||
|
case AudioEffectPhaser::Param::PHASE: |
||||||
|
return this->phaser->getpar(11); |
||||||
|
default: |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected: |
||||||
|
virtual size_t getParametersSize() |
||||||
|
{ |
||||||
|
return AudioEffectPhaser::Param::UNKNOWN; |
||||||
|
} |
||||||
|
|
||||||
|
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len) |
||||||
|
{ |
||||||
|
// LFO effects require period be set before setting other params
|
||||||
|
if(this->init_params) |
||||||
|
{ |
||||||
|
this->phaser->PERIOD = len; |
||||||
|
this->phaser->lfo->updateparams(len); |
||||||
|
this->init_params = false; // so we only do this once
|
||||||
|
} |
||||||
|
|
||||||
|
// now set out ports and global period size
|
||||||
|
this->phaser->efxoutl = outblockL; |
||||||
|
this->phaser->efxoutr = outblockR; |
||||||
|
|
||||||
|
//now run
|
||||||
|
this->phaser->out((float*) inblockL, (float*) inblockR, len); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
Phaser* phaser; |
||||||
|
bool init_params; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // _EFFECT_PHASER_H
|
@ -0,0 +1,440 @@ |
|||||||
|
/*
|
||||||
|
APhaser.C - Approximate digital model of an analog JFET phaser. |
||||||
|
Analog modeling implemented by Ryan Billing aka Transmogrifox. |
||||||
|
November, 2009 |
||||||
|
|
||||||
|
Credit to: |
||||||
|
///////////////////
|
||||||
|
ZynAddSubFX - a software synthesizer |
||||||
|
|
||||||
|
Phaser.C - Phaser effect |
||||||
|
Copyright (C) 2002-2005 Nasca Octavian Paul |
||||||
|
Author: Nasca Octavian Paul |
||||||
|
|
||||||
|
Modified for rakarrack by Josep Andreu |
||||||
|
|
||||||
|
DSP analog modeling theory & practice largely influenced by various CCRMA publications, particularly works by Julius O. Smith. |
||||||
|
////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify |
||||||
|
it under the terms of version 2 of the GNU General Public License |
||||||
|
as published by the Free Software Foundation. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License (version 2) for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License (version 2) |
||||||
|
along with this program; if not, write to the Free Software Foundation, |
||||||
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||||
|
|
||||||
|
*/ |
||||||
|
#include <math.h> |
||||||
|
#include "APhaser.h" |
||||||
|
#include <stdio.h> |
||||||
|
//#include "FPreset.h"
|
||||||
|
#define PHASER_LFO_SHAPE 2 |
||||||
|
#define ONE_ 0.99999f // To prevent LFO ever reaching 1.0 for filter stability purposes
|
||||||
|
#define ZERO_ 0.00001f // Same idea as above.
|
||||||
|
|
||||||
|
Analog_Phaser::Analog_Phaser (float * efxoutl_, float * efxoutr_, double sample_rate) |
||||||
|
{ |
||||||
|
float fSAMPLE_RATE = sample_rate; |
||||||
|
|
||||||
|
efxoutl = efxoutl_; |
||||||
|
efxoutr = efxoutr_; |
||||||
|
|
||||||
|
lxn1 = (float *) malloc(sizeof(float)* MAX_PHASER_STAGES); |
||||||
|
|
||||||
|
lyn1 = (float *) malloc(sizeof(float)* MAX_PHASER_STAGES); |
||||||
|
|
||||||
|
rxn1 = (float *) malloc(sizeof(float)* MAX_PHASER_STAGES); |
||||||
|
|
||||||
|
ryn1 = (float *) malloc(sizeof(float)* MAX_PHASER_STAGES); |
||||||
|
|
||||||
|
offset = (float *) malloc(sizeof(float)* MAX_PHASER_STAGES); //model mismatch between JFET devices
|
||||||
|
offset[0] = -0.2509303f; |
||||||
|
offset[1] = 0.9408924f; |
||||||
|
offset[2] = 0.998f; |
||||||
|
offset[3] = -0.3486182f; |
||||||
|
offset[4] = -0.2762545f; |
||||||
|
offset[5] = -0.5215785f; |
||||||
|
offset[6] = 0.2509303f; |
||||||
|
offset[7] = -0.9408924f; |
||||||
|
offset[8] = -0.998f; |
||||||
|
offset[9] = 0.3486182f; |
||||||
|
offset[10] = 0.2762545f; |
||||||
|
offset[11] = 0.5215785f; |
||||||
|
|
||||||
|
barber = 0; //Deactivate barber pole phasing by default
|
||||||
|
|
||||||
|
mis = 1.0f; |
||||||
|
Rmin = 625.0f; // 2N5457 typical on resistance at Vgs = 0
|
||||||
|
Rmax = 22000.0f; // Resistor parallel to FET
|
||||||
|
Rmx = Rmin/Rmax; |
||||||
|
Rconst = 1.0f + Rmx; // Handle parallel resistor relationship
|
||||||
|
C = 0.00000005f; // 50 nF
|
||||||
|
CFs = 2.0f*fSAMPLE_RATE*C; |
||||||
|
|
||||||
|
lfo = new EffectLFO(sample_rate); |
||||||
|
|
||||||
|
Ppreset = 0; |
||||||
|
PERIOD = 255; //make best guess for init;
|
||||||
|
setpreset (Ppreset);//this will get done before out is run
|
||||||
|
cleanup (); |
||||||
|
}; |
||||||
|
|
||||||
|
Analog_Phaser::~Analog_Phaser () |
||||||
|
{ |
||||||
|
free(lxn1); |
||||||
|
free(lyn1); |
||||||
|
free(rxn1); |
||||||
|
free(ryn1); |
||||||
|
free(offset); |
||||||
|
delete lfo; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Effect output |
||||||
|
*/ |
||||||
|
void |
||||||
|
Analog_Phaser::out (float * smpsl, float * smpsr, uint32_t period) |
||||||
|
{ |
||||||
|
unsigned int i; |
||||||
|
int j; |
||||||
|
float lfol, lfor, lgain, rgain, bl, br, gl, gr, rmod, lmod, d, hpfr, hpfl; |
||||||
|
invperiod = 1.0f / (float)PERIOD;//had to move this to run
|
||||||
|
lgain = 0.0; |
||||||
|
rgain = 0.0; |
||||||
|
|
||||||
|
//initialize hpf
|
||||||
|
hpfl = 0.0; |
||||||
|
hpfr = 0.0; |
||||||
|
|
||||||
|
lfo->effectlfoout (&lfol, &lfor); |
||||||
|
lmod = lfol*width + depth; |
||||||
|
rmod = lfor*width + depth; |
||||||
|
|
||||||
|
if (lmod > ONE_) |
||||||
|
lmod = ONE_; |
||||||
|
else if (lmod < ZERO_) |
||||||
|
lmod = ZERO_; |
||||||
|
if (rmod > ONE_) |
||||||
|
rmod = ONE_; |
||||||
|
else if (rmod < ZERO_) |
||||||
|
rmod = ZERO_; |
||||||
|
|
||||||
|
if (Phyper != 0) { |
||||||
|
lmod *= lmod; //Triangle wave squared is approximately sin on bottom, tri on top
|
||||||
|
rmod *= rmod; //Result is exponential sweep more akin to filter in synth with exponential generator circuitry.
|
||||||
|
}; |
||||||
|
|
||||||
|
lmod = sqrtf(1.0f - lmod); //gl,gr is Vp - Vgs. Typical FET drain-source resistance follows constant/[1-sqrt(Vp - Vgs)]
|
||||||
|
rmod = sqrtf(1.0f - rmod); |
||||||
|
|
||||||
|
rdiff = (rmod - oldrgain) * invperiod; |
||||||
|
ldiff = (lmod - oldlgain) * invperiod; |
||||||
|
|
||||||
|
gl = oldlgain; |
||||||
|
gr = oldrgain; |
||||||
|
|
||||||
|
oldlgain = lmod; |
||||||
|
oldrgain = rmod; |
||||||
|
|
||||||
|
float v1, v2; |
||||||
|
if (outvolume < 0.5f) |
||||||
|
{ |
||||||
|
v1 = 1.0f; |
||||||
|
v2 = outvolume * 2.0f; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
v1 = (1.0f - outvolume) * 2.0f; |
||||||
|
v2 = 1.0f; |
||||||
|
} |
||||||
|
|
||||||
|
for (i = 0; i < period; i++) { |
||||||
|
|
||||||
|
gl += ldiff; // Linear interpolation between LFO samples
|
||||||
|
gr += rdiff; |
||||||
|
|
||||||
|
float lxn = smpsl[i]; |
||||||
|
float rxn = smpsr[i]; |
||||||
|
|
||||||
|
|
||||||
|
if (barber) { |
||||||
|
gl = fmodf((gl + 0.25f) , ONE_); |
||||||
|
gr = fmodf((gr + 0.25f) , ONE_); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
//Left channel
|
||||||
|
for (j = 0; j < Pstages; j++) { |
||||||
|
//Phasing routine
|
||||||
|
mis = 1.0f + offsetpct*offset[j]; |
||||||
|
d = (1.0f + 2.0f*(0.25f + gl)*hpfl*hpfl*distortion) * mis; //This is symmetrical. FET is not, so this deviates slightly, however sym dist. is better sounding than a real FET.
|
||||||
|
Rconst = 1.0f + mis*Rmx; |
||||||
|
bl = (Rconst - gl )/ (d*Rmin); // This is 1/R. R is being modulated to control filter fc.
|
||||||
|
lgain = (CFs - bl)/(CFs + bl); |
||||||
|
|
||||||
|
lyn1[j] = lgain * (lxn + lyn1[j]) - lxn1[j]; |
||||||
|
lyn1[j] += DENORMAL_GUARD; |
||||||
|
hpfl = lyn1[j] + (1.0f-lgain)*lxn1[j]; //high pass filter -- Distortion depends on the high-pass part of the AP stage.
|
||||||
|
|
||||||
|
lxn1[j] = lxn; |
||||||
|
lxn = lyn1[j]; |
||||||
|
if (j==1) lxn += fbl; //Insert feedback after first phase stage
|
||||||
|
}; |
||||||
|
|
||||||
|
//Right channel
|
||||||
|
for (j = 0; j < Pstages; j++) { |
||||||
|
//Phasing routine
|
||||||
|
mis = 1.0f + offsetpct*offset[j]; |
||||||
|
d = (1.0f + 2.0f*(0.25f + gr)*hpfr*hpfr*distortion) * mis; // distortion
|
||||||
|
Rconst = 1.0f + mis*Rmx; |
||||||
|
br = (Rconst - gr )/ (d*Rmin); |
||||||
|
rgain = (CFs - br)/(CFs + br); |
||||||
|
|
||||||
|
ryn1[j] = rgain * (rxn + ryn1[j]) - rxn1[j]; |
||||||
|
ryn1[j] += DENORMAL_GUARD; |
||||||
|
hpfr = ryn1[j] + (1.0f-rgain)*rxn1[j]; //high pass filter
|
||||||
|
|
||||||
|
rxn1[j] = rxn; |
||||||
|
rxn = ryn1[j]; |
||||||
|
if (j==1) rxn += fbr; //Insert feedback after first phase stage
|
||||||
|
}; |
||||||
|
|
||||||
|
fbl = lxn * fb; |
||||||
|
fbr = rxn * fb; |
||||||
|
|
||||||
|
if (Poutsub != 0) { |
||||||
|
lxn *= -1.0f; |
||||||
|
rxn *= -1.0f; |
||||||
|
} |
||||||
|
|
||||||
|
efxoutl[i] = smpsl[i] * v1 + lxn * v2; |
||||||
|
efxoutr[i] = smpsr[i] * v1 + rxn * v2; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup the effect |
||||||
|
*/ |
||||||
|
void |
||||||
|
Analog_Phaser::cleanup () |
||||||
|
{ |
||||||
|
fbl = 0.0; |
||||||
|
fbr = 0.0; |
||||||
|
oldlgain = 0.0; |
||||||
|
oldrgain = 0.0; |
||||||
|
for (int i = 0; i < Pstages; i++) { |
||||||
|
lxn1[i] = 0.0; |
||||||
|
|
||||||
|
lyn1[i] = 0.0; |
||||||
|
|
||||||
|
rxn1[i] = 0.0; |
||||||
|
|
||||||
|
ryn1[i] = 0.0; |
||||||
|
|
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Parameter control |
||||||
|
*/ |
||||||
|
void |
||||||
|
Analog_Phaser::setwidth (int Pwidth) |
||||||
|
{ |
||||||
|
this->Pwidth = Pwidth; |
||||||
|
width = ((float)Pwidth / 127.0f); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
void |
||||||
|
Analog_Phaser::setfb (int Pfb) |
||||||
|
{ |
||||||
|
this->Pfb = Pfb; |
||||||
|
fb = (float) (Pfb - 64) / 64.2f; |
||||||
|
}; |
||||||
|
|
||||||
|
void |
||||||
|
Analog_Phaser::setvolume (int Pvolume) |
||||||
|
{ |
||||||
|
this->Pvolume = Pvolume; |
||||||
|
// outvolume is needed in calling program
|
||||||
|
outvolume = (float)Pvolume / 127.0f; |
||||||
|
}; |
||||||
|
|
||||||
|
void |
||||||
|
Analog_Phaser::setdistortion (int Pdistortion) |
||||||
|
{ |
||||||
|
this->Pdistortion = Pdistortion; |
||||||
|
distortion = (float)Pdistortion / 127.0f; |
||||||
|
}; |
||||||
|
|
||||||
|
void |
||||||
|
Analog_Phaser::setoffset (int Poffset) |
||||||
|
{ |
||||||
|
this->Poffset = Poffset; |
||||||
|
offsetpct = (float)Poffset / 127.0f; |
||||||
|
}; |
||||||
|
|
||||||
|
void |
||||||
|
Analog_Phaser::setstages (int Pstages) |
||||||
|
{ |
||||||
|
|
||||||
|
if (Pstages >= MAX_PHASER_STAGES) |
||||||
|
Pstages = MAX_PHASER_STAGES ; |
||||||
|
this->Pstages = Pstages; |
||||||
|
|
||||||
|
cleanup (); |
||||||
|
}; |
||||||
|
|
||||||
|
void |
||||||
|
Analog_Phaser::setdepth (int Pdepth) |
||||||
|
{ |
||||||
|
this->Pdepth = Pdepth; |
||||||
|
depth = (float)(Pdepth - 64) / 127.0f; //Pdepth input should be 0-127. depth shall range 0-0.5 since we don't need to shift the full spectrum.
|
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
void |
||||||
|
Analog_Phaser::setpreset (int npreset) |
||||||
|
{ |
||||||
|
const int PRESET_SIZE = 13; |
||||||
|
const int NUM_PRESETS = 6; |
||||||
|
int presets[NUM_PRESETS][PRESET_SIZE] = { |
||||||
|
//Phaser1
|
||||||
|
{64, 20, 14, 0, 1, 64, 110, 40, 4, 10, 0, 64, 1}, |
||||||
|
//Phaser2
|
||||||
|
{64, 20, 14, 5, 1, 64, 110, 40, 6, 10, 0, 70, 1}, |
||||||
|
//Phaser3
|
||||||
|
{64, 20, 9, 0, 0, 64, 40, 40, 8, 10, 0, 60, 0}, |
||||||
|
//Phaser4
|
||||||
|
{64, 20, 14, 10, 0, 64, 110, 80, 7, 10, 1, 45, 1}, |
||||||
|
//Phaser5
|
||||||
|
{25, 20, 240, 10, 0, 64, 25, 16, 8, 100, 0, 25, 0}, |
||||||
|
//Phaser6
|
||||||
|
{64, 20, 1, 10, 1, 64, 110, 40, 12, 10, 0, 70, 1} |
||||||
|
}; |
||||||
|
|
||||||
|
if(npreset>NUM_PRESETS-1) { |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
for (int n = 0; n < PRESET_SIZE; n++) |
||||||
|
changepar (n, presets[npreset][n]); |
||||||
|
} |
||||||
|
|
||||||
|
Ppreset = npreset; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
void |
||||||
|
Analog_Phaser::changepar (int npar, int value) |
||||||
|
{ |
||||||
|
switch (npar) { |
||||||
|
case 0: |
||||||
|
setvolume (value); |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
setdistortion (value); |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
lfo->Pfreq = value; |
||||||
|
lfo->updateparams (PERIOD); |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
lfo->Prandomness = value; |
||||||
|
lfo->updateparams (PERIOD); |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
lfo->PLFOtype = value; |
||||||
|
lfo->updateparams (PERIOD); |
||||||
|
barber = 0; |
||||||
|
if (value == 2) barber = 1; |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
lfo->Pstereo = value; |
||||||
|
lfo->updateparams (PERIOD); |
||||||
|
break; |
||||||
|
case 6: |
||||||
|
setwidth (value); |
||||||
|
break; |
||||||
|
case 7: |
||||||
|
setfb (value); |
||||||
|
break; |
||||||
|
case 8: |
||||||
|
setstages (value); |
||||||
|
break; |
||||||
|
case 9: |
||||||
|
setoffset (value); |
||||||
|
break; |
||||||
|
case 10: |
||||||
|
if (value > 1) |
||||||
|
value = 1; |
||||||
|
Poutsub = value; |
||||||
|
break; |
||||||
|
case 11: |
||||||
|
setdepth (value); |
||||||
|
break; |
||||||
|
case 12: |
||||||
|
if (value > 1) |
||||||
|
value = 1; |
||||||
|
Phyper = value; |
||||||
|
break; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
int |
||||||
|
Analog_Phaser::getpar (int npar) |
||||||
|
{ |
||||||
|
switch (npar) { |
||||||
|
case 0: |
||||||
|
return (Pvolume); |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
return (Pdistortion); |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
return (lfo->Pfreq); |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
return (lfo->Prandomness); |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
return (lfo->PLFOtype); |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
return (lfo->Pstereo); |
||||||
|
break; |
||||||
|
case 6: |
||||||
|
return (Pwidth); |
||||||
|
break; |
||||||
|
case 7: |
||||||
|
return (Pfb); |
||||||
|
break; |
||||||
|
case 8: |
||||||
|
return (Pstages); |
||||||
|
break; |
||||||
|
case 9: |
||||||
|
return (Poffset); |
||||||
|
break; |
||||||
|
case 10: |
||||||
|
return (Poutsub); |
||||||
|
break; |
||||||
|
case 11: |
||||||
|
return (Pdepth); |
||||||
|
break; |
||||||
|
case 12: |
||||||
|
return (Phyper); |
||||||
|
break; |
||||||
|
|
||||||
|
default: |
||||||
|
return (0); |
||||||
|
}; |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,91 @@ |
|||||||
|
/*
|
||||||
|
ZynAddSubFX - a software synthesizer |
||||||
|
|
||||||
|
APhaser.h - Phaser effect |
||||||
|
Copyright (C) 2002-2005 Nasca Octavian Paul |
||||||
|
Author: Nasca Octavian Paul |
||||||
|
|
||||||
|
Modified for rakarrack by Josep Andreu and Ryan Billing |
||||||
|
|
||||||
|
Further modified for rakarrack by Ryan Billing (Transmogrifox) to model Analog Phaser behavior 2009 |
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify |
||||||
|
it under the terms of version 2 of the GNU General Public License |
||||||
|
as published by the Free Software Foundation. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License (version 2) for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License (version 2) |
||||||
|
along with this program; if not, write to the Free Software Foundation, |
||||||
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||||
|
|
||||||
|
*/ |
||||||
|
#ifndef APHASER_H |
||||||
|
#define APHASER_H |
||||||
|
#include "global.h" |
||||||
|
#include "EffectLFO.h" |
||||||
|
|
||||||
|
|
||||||
|
class Analog_Phaser |
||||||
|
{ |
||||||
|
public: |
||||||
|
Analog_Phaser (float * efxoutl_, float * efxoutr_, double sample_rate); |
||||||
|
~Analog_Phaser (); |
||||||
|
void out (float * smpsl, float * smpsr, uint32_t period); |
||||||
|
void setpreset (int npreset); |
||||||
|
void changepar (int npar, int value); |
||||||
|
int getpar (int npar); |
||||||
|
void cleanup (); |
||||||
|
int Ppreset; |
||||||
|
float *efxoutl; |
||||||
|
float *efxoutr; |
||||||
|
float outvolume; |
||||||
|
|
||||||
|
uint32_t PERIOD; |
||||||
|
EffectLFO *lfo; //Phaser modulator
|
||||||
|
|
||||||
|
private: |
||||||
|
//Phaser parameters
|
||||||
|
int Pvolume; //Used in Process.C to set wet/dry mix
|
||||||
|
int Pdistortion; //Model distortion added by FET element
|
||||||
|
int Pwidth; //Phaser width (LFO amplitude)
|
||||||
|
int Pfb; //feedback
|
||||||
|
int Poffset; //Model mismatch between variable resistors
|
||||||
|
int Pstages; //Number of first-order All-Pass stages
|
||||||
|
int Poutsub; //if I wish to subtract the output instead of the adding it
|
||||||
|
int Phyper; //lfo^2 -- converts tri into hyper-sine
|
||||||
|
int Pdepth; //Depth of phaser sweep
|
||||||
|
int Pbarber; //Enable barber pole phasing
|
||||||
|
|
||||||
|
//Control parameters
|
||||||
|
void setvolume (int Pvolume); |
||||||
|
void setdistortion (int Pdistortion); |
||||||
|
void setwidth (int Pwidth); |
||||||
|
void setfb (int Pfb); |
||||||
|
void setoffset (int Poffset); |
||||||
|
void setstages (int Pstages); |
||||||
|
void setdepth (int Pdepth); |
||||||
|
|
||||||
|
//Internal Variables
|
||||||
|
bool barber; //Barber pole phasing flag
|
||||||
|
float distortion, fb, width, offsetpct, fbl, fbr, depth; |
||||||
|
float *lxn1, *lyn1,*rxn1, *ryn1, *offset; |
||||||
|
float oldlgain, oldrgain, rdiff, ldiff, invperiod; |
||||||
|
|
||||||
|
float mis; |
||||||
|
float Rmin; // 2N5457 typical on resistance at Vgs = 0
|
||||||
|
float Rmax; // Resistor parallel to FET
|
||||||
|
float Rmx; // Rmin/Rmax to avoid division in loop
|
||||||
|
float Rconst; // Handle parallel resistor relationship
|
||||||
|
float C; // Capacitor
|
||||||
|
float CFs; // A constant derived from capacitor and resistor relationships
|
||||||
|
float fPERIOD; |
||||||
|
|
||||||
|
class FPreset *Fpre; |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,256 @@ |
|||||||
|
/*
|
||||||
|
ZynAddSubFX - a software synthesizer |
||||||
|
|
||||||
|
EffectLFO.C - Stereo LFO used by some effects |
||||||
|
Copyright (C) 2002-2005 Nasca Octavian Paul |
||||||
|
Author: Nasca Octavian Paul |
||||||
|
|
||||||
|
Modified for rakarrack by Josep Andreu 6 Ryan Billing |
||||||
|
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify |
||||||
|
it under the terms of version 2 of the GNU General Public License |
||||||
|
as published by the Free Software Foundation. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License (version 2) for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License (version 2) |
||||||
|
along with this program; if not, write to the Free Software Foundation, |
||||||
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||||
|
|
||||||
|
*/ |
||||||
|
|
||||||
|
#include <stdlib.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <arm_math.h> |
||||||
|
|
||||||
|
#include "global.h" |
||||||
|
#include "EffectLFO.h" |
||||||
|
#include "f_sin.h" |
||||||
|
|
||||||
|
EffectLFO::EffectLFO (double sample_rate) |
||||||
|
{ |
||||||
|
float fPERIOD = 256;//this is our best guess at what it will be, later we'll correct it when we actually know fPERIOD
|
||||||
|
fSAMPLE_RATE = sample_rate; |
||||||
|
xl = 0.0; |
||||||
|
xr = 0.0; |
||||||
|
Pfreq = 40; |
||||||
|
Prandomness = 0; |
||||||
|
PLFOtype = 0; |
||||||
|
Pstereo = 96; |
||||||
|
|
||||||
|
iperiod = fPERIOD/fSAMPLE_RATE; |
||||||
|
h = iperiod; |
||||||
|
a = 10.0f; |
||||||
|
b = 28.0f; |
||||||
|
c = 8.0f / 5.0f; |
||||||
|
scale = 1.0f/36.0f; |
||||||
|
ratediv = 0.1f; |
||||||
|
holdflag = 0; |
||||||
|
tca = iperiod/(iperiod + 0.02); //20ms default
|
||||||
|
tcb = 1.0f - tca; |
||||||
|
rreg = lreg = oldrreg = oldlreg = 0.0f; |
||||||
|
updateparams ((uint32_t)fPERIOD); |
||||||
|
|
||||||
|
ampl1 = (1.0f - lfornd) + lfornd * (float)RND; |
||||||
|
ampl2 = (1.0f - lfornd) + lfornd * (float)RND; |
||||||
|
ampr1 = (1.0f - lfornd) + lfornd * (float)RND; |
||||||
|
ampr2 = (1.0f - lfornd) + lfornd * (float)RND; |
||||||
|
|
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
EffectLFO::~EffectLFO () |
||||||
|
{ |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update the changed parameters |
||||||
|
*/ |
||||||
|
void |
||||||
|
EffectLFO::updateparams (uint32_t period) |
||||||
|
{ |
||||||
|
float fPERIOD = period; |
||||||
|
//must update several parameters once we actually know the period
|
||||||
|
iperiod = fPERIOD/fSAMPLE_RATE; |
||||||
|
h = iperiod; |
||||||
|
tca = iperiod/(iperiod + 0.02); //20ms default
|
||||||
|
tcb = 1.0f - tca; |
||||||
|
|
||||||
|
|
||||||
|
incx = (float)Pfreq * fPERIOD / (fSAMPLE_RATE * 60.0f); |
||||||
|
|
||||||
|
if (incx > 0.49999999) |
||||||
|
incx = 0.499999999f; //Limit the Frequency
|
||||||
|
|
||||||
|
lfornd = (float)Prandomness / 127.0f; |
||||||
|
if (lfornd < 0.0) |
||||||
|
lfornd = 0.0; |
||||||
|
else if (lfornd > 1.0) |
||||||
|
lfornd = 1.0; |
||||||
|
|
||||||
|
if (PLFOtype > 11) //this has to be updated if more lfo's are added
|
||||||
|
PLFOtype = 0;
|
||||||
|
lfotype = PLFOtype; |
||||||
|
|
||||||
|
xr = fmodf (xl + ((float)Pstereo - 64.0f) / 127.0f + 1.0f, 1.0f); |
||||||
|
|
||||||
|
if ((h = incx*ratediv) > 0.02) h = 0.02; //keeps it stable
|
||||||
|
|
||||||
|
a = 10.0f + (((float) RND) - 0.5f)*8.0f; |
||||||
|
b = 28.0f + (((float) RND) - 0.5f)*12.0f; |
||||||
|
c = 1.25f + 3.0f * ((float) RND); |
||||||
|
|
||||||
|
// printf("incx %f x0 %f y0 %f z0 %f out %f c %f b %f a %f\n",incx,x0,y0,z0, (2.0f * radius - 1.0f), c, b, a);
|
||||||
|
x0 = 0.1f + 0.1f * ((float) RND); |
||||||
|
y0 = 0.0f; |
||||||
|
z0 = 0.2f; |
||||||
|
x1 = y1 = z1 = radius = 0.0f; |
||||||
|
|
||||||
|
float tmp = 6.0f/((float) Pfreq); //S/H time attack 0.2*60=12.0
|
||||||
|
tca = iperiod/(iperiod + tmp); //
|
||||||
|
tcb = 1.0f - tca; |
||||||
|
maxrate = 4.0f*iperiod; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the shape of the LFO |
||||||
|
*/ |
||||||
|
float EffectLFO::getlfoshape (float x) |
||||||
|
{ |
||||||
|
float tmpv; |
||||||
|
float out=0.0; |
||||||
|
int iterations = 1; //make fractal go faster
|
||||||
|
switch (lfotype) { |
||||||
|
case 1: //EffectLFO_TRIANGLE
|
||||||
|
if ((x > 0.0) && (x < 0.25)) |
||||||
|
out = 4.0f * x; |
||||||
|
else if ((x > 0.25) && (x < 0.75)) |
||||||
|
out = 2.0f - 4.0f * x; |
||||||
|
else |
||||||
|
out = 4.0f * x - 4.0f; |
||||||
|
break; |
||||||
|
case 2: //EffectLFO_RAMP Ramp+
|
||||||
|
out = 2.0f * x - 1.0f; |
||||||
|
break; |
||||||
|
case 3: //EffectLFO_RAMP Ramp-
|
||||||
|
out = - 2.0f * x + 1.0f; |
||||||
|
break; |
||||||
|
case 4: //ZigZag
|
||||||
|
x = x * 2.0f - 1.0f; |
||||||
|
tmpv = 0.33f * f_sin(x); |
||||||
|
out = f_sin(f_sin(x*D_PI)*x/tmpv); |
||||||
|
break; |
||||||
|
case 5: //Modulated Square ?? ;-)
|
||||||
|
tmpv = x * D_PI; |
||||||
|
out=f_sin(tmpv+f_sin(2.0f*tmpv)); |
||||||
|
break; |
||||||
|
case 6: // Modulated Saw
|
||||||
|
tmpv = x * D_PI; |
||||||
|
out=f_sin(tmpv+f_sin(tmpv)); |
||||||
|
break; |
||||||
|
case 8: //Lorenz Fractal, faster, using X,Y outputs
|
||||||
|
iterations = 4; |
||||||
|
case 7: // Lorenz Fractal
|
||||||
|
for(int j=0; j<iterations; j++) { |
||||||
|
x1 = x0 + h * a * (y0 - x0); |
||||||
|
y1 = y0 + h * (x0 * (b - z0) - y0); |
||||||
|
z1 = z0 + h * (x0 * y0 - c * z0); |
||||||
|
x0 = x1; |
||||||
|
y0 = y1; |
||||||
|
z0 = z1; |
||||||
|
} |
||||||
|
if(lfotype==7) { |
||||||
|
if((radius = (sqrtf(x0*x0 + y0*y0 + z0*z0) * scale) - 0.25f) > 1.0f) radius = 1.0f; |
||||||
|
if(radius < 0.0) radius = 0.0; |
||||||
|
out = 2.0f * radius - 1.0f; |
||||||
|
} |
||||||
|
|
||||||
|
break; |
||||||
|
case 9: //Sample/Hold Random
|
||||||
|
if(fmod(x,0.5f)<=(2.0f*incx)) { //this function is called by left, then right...so must toggle each time called
|
||||||
|
rreg = lreg; |
||||||
|
lreg = RND1; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if(xlreg<lreg) xlreg += maxrate; |
||||||
|
else xlreg -= maxrate; |
||||||
|
if(xrreg<rreg) xrreg += maxrate; |
||||||
|
else xrreg -= maxrate; |
||||||
|
oldlreg = xlreg*tca + oldlreg*tcb; |
||||||
|
oldrreg = xrreg*tca + oldrreg*tcb; |
||||||
|
|
||||||
|
if(holdflag) { |
||||||
|
out = 2.0f*oldlreg -1.0f; |
||||||
|
holdflag = (1 + holdflag)%2; |
||||||
|
} else { |
||||||
|
out = 2.0f*oldrreg - 1.0f; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
break; |
||||||
|
case 10: //Tri-top
|
||||||
|
if(x<=0.5f) out = -f_sin(x*D_PI); |
||||||
|
else if ((x > 0.5f) && (x < 0.75f)) |
||||||
|
out = 6 * (x-0.5); |
||||||
|
else |
||||||
|
out = 1.5 - 6.0f *( x - 0.75f); |
||||||
|
out-=0.25f; |
||||||
|
out*=0.88888889f; |
||||||
|
break; |
||||||
|
case 11: //Tri-Bottom
|
||||||
|
if(x<=0.5f) out = -f_sin(x*D_PI); |
||||||
|
else if ((x > 0.5f) && (x < 0.75f)) |
||||||
|
out = 6 * (x-0.5); |
||||||
|
else |
||||||
|
out = 1.5 - 6.0f *( x - 0.75f); |
||||||
|
out-=0.25f; |
||||||
|
out*=-0.88888889f; |
||||||
|
break;
|
||||||
|
//more to be added here; also ::updateparams() need to be updated (to allow more lfotypes)
|
||||||
|
default: |
||||||
|
out = f_cos (x * D_PI); //EffectLFO_SINE
|
||||||
|
}; |
||||||
|
return (out); |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* LFO output |
||||||
|
*/ |
||||||
|
void |
||||||
|
EffectLFO::effectlfoout (float * outl, float * outr) |
||||||
|
{ |
||||||
|
float out; |
||||||
|
|
||||||
|
out = getlfoshape (xl); |
||||||
|
//if ((lfotype == 0) || (lfotype == 1)) //What was that for?
|
||||||
|
out *= (ampl1 + xl * (ampl2 - ampl1)); |
||||||
|
xl += incx; |
||||||
|
if (xl > 1.0) { |
||||||
|
xl -= 1.0f; |
||||||
|
ampl1 = ampl2; |
||||||
|
ampl2 = (1.0f - lfornd) + lfornd * (float)RND; |
||||||
|
}; |
||||||
|
if(lfotype==8) out = scale*x0; //fractal parameter
|
||||||
|
*outl = (out + 1.0f) * 0.5f; |
||||||
|
|
||||||
|
|
||||||
|
if(lfotype==8) out = scale*y0; //fractal parameter
|
||||||
|
else out = getlfoshape (xr); |
||||||
|
|
||||||
|
//if ((lfotype == 0) || (lfotype == 1))
|
||||||
|
out *= (ampr1 + xr * (ampr2 - ampr1)); |
||||||
|
xr += incx; |
||||||
|
if (xr > 1.0) { |
||||||
|
xr -= 1.0f; |
||||||
|
ampr1 = ampr2; |
||||||
|
ampr2 = (1.0f - lfornd) + lfornd * (float)RND; |
||||||
|
}; |
||||||
|
*outr = (out + 1.0f) * 0.5f; |
||||||
|
}; |
@ -0,0 +1,72 @@ |
|||||||
|
/*
|
||||||
|
ZynAddSubFX - a software synthesizer |
||||||
|
|
||||||
|
EffectLFO.h - Stereo LFO used by some effects |
||||||
|
Copyright (C) 2002-2005 Nasca Octavian Paul |
||||||
|
Author: Nasca Octavian Paul |
||||||
|
|
||||||
|
Modified for rakarrack by Josep Andreu & Ryan Billing |
||||||
|
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify |
||||||
|
it under the terms of version 2 of the GNU General Public License |
||||||
|
as published by the Free Software Foundation. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License (version 2) for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License (version 2) |
||||||
|
along with this program; if not, write to the Free Software Foundation, |
||||||
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||||
|
|
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef EFFECT_LFO_H |
||||||
|
#define EFFECT_LFO_H |
||||||
|
|
||||||
|
#include "global.h" |
||||||
|
#include <arm_math.h> |
||||||
|
|
||||||
|
class EffectLFO |
||||||
|
{ |
||||||
|
public: |
||||||
|
EffectLFO (double sample_rate); |
||||||
|
~EffectLFO (); |
||||||
|
void effectlfoout (float * outl, float * outr); |
||||||
|
void updateparams (uint32_t period); |
||||||
|
int Pfreq; |
||||||
|
int Prandomness; |
||||||
|
int PLFOtype; |
||||||
|
int Pstereo; //"64"=0
|
||||||
|
private: |
||||||
|
float getlfoshape (float x); |
||||||
|
|
||||||
|
float xl, xr; |
||||||
|
float incx; |
||||||
|
float ampl1, ampl2, ampr1, ampr2; //necesar pentru "randomness"
|
||||||
|
float lfointensity; |
||||||
|
float lfornd; |
||||||
|
int lfotype; |
||||||
|
|
||||||
|
//Lorenz Fractal parameters
|
||||||
|
float x0,y0,z0,x1,y1,z1,radius; |
||||||
|
float h; |
||||||
|
float a; |
||||||
|
float b; |
||||||
|
float c; |
||||||
|
float scale; |
||||||
|
float iperiod; |
||||||
|
float ratediv; |
||||||
|
|
||||||
|
//Sample/Hold
|
||||||
|
int holdflag; //toggle left/right channel changes
|
||||||
|
float tca, tcb, maxrate; |
||||||
|
float rreg, lreg, xlreg,xrreg, oldrreg, oldlreg; |
||||||
|
|
||||||
|
float fSAMPLE_RATE; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,337 @@ |
|||||||
|
/*
|
||||||
|
ZynAddSubFX - a software synthesizer |
||||||
|
|
||||||
|
Phaser.C - Phaser effect |
||||||
|
Copyright (C) 2002-2005 Nasca Octavian Paul |
||||||
|
Author: Nasca Octavian Paul |
||||||
|
|
||||||
|
Modified for rakarrack by Josep Andreu |
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify |
||||||
|
it under the terms of version 2 of the GNU General Public License |
||||||
|
as published by the Free Software Foundation. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License (version 2) for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License (version 2) |
||||||
|
along with this program; if not, write to the Free Software Foundation, |
||||||
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||||
|
|
||||||
|
*/ |
||||||
|
#include <math.h> |
||||||
|
#include "Phaser.h" |
||||||
|
#include <stdio.h> |
||||||
|
//#include "FPreset.h"
|
||||||
|
#define PHASER_LFO_SHAPE 2 |
||||||
|
|
||||||
|
Phaser::Phaser (float * efxoutl_, float * efxoutr_, double sample_rate) |
||||||
|
{ |
||||||
|
efxoutl = efxoutl_; |
||||||
|
efxoutr = efxoutr_; |
||||||
|
|
||||||
|
oldl = (float *) malloc(sizeof(float)* MAX_PHASER_STAGES * 2); |
||||||
|
oldr = (float *) malloc(sizeof(float)* MAX_PHASER_STAGES * 2); |
||||||
|
|
||||||
|
lfo = new EffectLFO(sample_rate); |
||||||
|
|
||||||
|
Ppreset = 0; |
||||||
|
PERIOD = 256; //best guess until the effect starts running;
|
||||||
|
setpreset (Ppreset); |
||||||
|
cleanup (); |
||||||
|
}; |
||||||
|
|
||||||
|
Phaser::~Phaser () |
||||||
|
{ |
||||||
|
free(oldl); |
||||||
|
free(oldr); |
||||||
|
delete lfo; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Effect output |
||||||
|
*/ |
||||||
|
void |
||||||
|
Phaser::out (float * smpsl, float * smpsr, uint32_t period) |
||||||
|
{ |
||||||
|
unsigned int i; |
||||||
|
int j; |
||||||
|
float lfol, lfor, lgain, rgain, tmp; |
||||||
|
|
||||||
|
lfo->effectlfoout (&lfol, &lfor); |
||||||
|
lgain = lfol; |
||||||
|
rgain = lfor; |
||||||
|
lgain = |
||||||
|
(expf (lgain * PHASER_LFO_SHAPE) - 1.0f) / (expf (PHASER_LFO_SHAPE) - 1.0f); |
||||||
|
rgain = |
||||||
|
(expf (rgain * PHASER_LFO_SHAPE) - 1.0f) / (expf (PHASER_LFO_SHAPE) - 1.0f); |
||||||
|
|
||||||
|
|
||||||
|
lgain = 1.0f - phase * (1.0f - depth) - (1.0f - phase) * lgain * depth; |
||||||
|
rgain = 1.0f - phase * (1.0f - depth) - (1.0f - phase) * rgain * depth; |
||||||
|
|
||||||
|
if (lgain > 1.0) |
||||||
|
lgain = 1.0f; |
||||||
|
else if (lgain < 0.0) |
||||||
|
lgain = 0.0f; |
||||||
|
if (rgain > 1.0) |
||||||
|
rgain = 1.0f; |
||||||
|
else if (rgain < 0.0) |
||||||
|
rgain = 0.0f; |
||||||
|
|
||||||
|
float v1, v2; |
||||||
|
if (outvolume < 0.5f) |
||||||
|
{ |
||||||
|
v1 = 1.0f; |
||||||
|
v2 = outvolume * 2.0f; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
v1 = (1.0f - outvolume) * 2.0f; |
||||||
|
v2 = 1.0f; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < period; i++) { |
||||||
|
float x = (float) i / ((float)period); |
||||||
|
float x1 = 1.0f - x; |
||||||
|
float gl = lgain * x + oldlgain * x1; |
||||||
|
float gr = rgain * x + oldrgain * x1; |
||||||
|
float inl = smpsl[i] * panning + fbl; |
||||||
|
float inr = smpsr[i] * (1.0f - panning) + fbr; |
||||||
|
|
||||||
|
//Left channel
|
||||||
|
for (j = 0; j < Pstages * 2; j++) { |
||||||
|
//Phasing routine
|
||||||
|
tmp = oldl[j] + DENORMAL_GUARD; |
||||||
|
oldl[j] = gl * tmp + inl; |
||||||
|
inl = tmp - gl * oldl[j]; |
||||||
|
}; |
||||||
|
//Right channel
|
||||||
|
for (j = 0; j < Pstages * 2; j++) { |
||||||
|
//Phasing routine
|
||||||
|
tmp = oldr[j] + DENORMAL_GUARD; |
||||||
|
oldr[j] = (gr * tmp) + inr; |
||||||
|
inr = tmp - (gr * oldr[j]); |
||||||
|
}; |
||||||
|
//Left/Right crossing
|
||||||
|
float l = inl; |
||||||
|
float r = inr; |
||||||
|
inl = l * (1.0f - lrcross) + r * lrcross; |
||||||
|
inr = r * (1.0f - lrcross) + l * lrcross; |
||||||
|
|
||||||
|
fbl = inl * fb; |
||||||
|
fbr = inr * fb; |
||||||
|
|
||||||
|
if (Poutsub != 0) { |
||||||
|
inl *= -1.0f; |
||||||
|
inr *= -1.0f; |
||||||
|
} |
||||||
|
|
||||||
|
efxoutl[i] = smpsl[i] * v1 + inl * v2; |
||||||
|
efxoutr[i] = smpsr[i] * v1 + inr * v2; |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
oldlgain = lgain; |
||||||
|
oldrgain = rgain; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup the effect |
||||||
|
*/ |
||||||
|
void |
||||||
|
Phaser::cleanup () |
||||||
|
{ |
||||||
|
fbl = 0.0; |
||||||
|
fbr = 0.0; |
||||||
|
oldlgain = 0.0; |
||||||
|
oldrgain = 0.0; |
||||||
|
for (int i = 0; i < Pstages * 2; i++) { |
||||||
|
oldl[i] = 0.0; |
||||||
|
oldr[i] = 0.0; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* Parameter control |
||||||
|
*/ |
||||||
|
void |
||||||
|
Phaser::setdepth (int Pdepth) |
||||||
|
{ |
||||||
|
this->Pdepth = Pdepth; |
||||||
|
depth = ((float)Pdepth / 127.0f); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
void |
||||||
|
Phaser::setfb (int Pfb) |
||||||
|
{ |
||||||
|
this->Pfb = Pfb; |
||||||
|
fb = ((float)Pfb - 64.0f) / 64.1f; |
||||||
|
}; |
||||||
|
|
||||||
|
void |
||||||
|
Phaser::setvolume (int Pvolume) |
||||||
|
{ |
||||||
|
this->Pvolume = Pvolume; |
||||||
|
outvolume = (float)Pvolume / 127.0f; |
||||||
|
}; |
||||||
|
|
||||||
|
void |
||||||
|
Phaser::setpanning (int Ppanning) |
||||||
|
{ |
||||||
|
this->Ppanning = Ppanning; |
||||||
|
panning = ((float)Ppanning + .5f)/ 127.0f; |
||||||
|
}; |
||||||
|
|
||||||
|
void |
||||||
|
Phaser::setlrcross (int Plrcross) |
||||||
|
{ |
||||||
|
this->Plrcross = Plrcross; |
||||||
|
lrcross = (float)Plrcross / 127.0f; |
||||||
|
}; |
||||||
|
|
||||||
|
void |
||||||
|
Phaser::setstages (int Pstages) |
||||||
|
{ |
||||||
|
if (Pstages > MAX_PHASER_STAGES) |
||||||
|
Pstages = MAX_PHASER_STAGES; |
||||||
|
this->Pstages = Pstages; |
||||||
|
cleanup (); |
||||||
|
}; |
||||||
|
|
||||||
|
void |
||||||
|
Phaser::setphase (int Pphase) |
||||||
|
{ |
||||||
|
this->Pphase = Pphase; |
||||||
|
phase = ((float)Pphase / 127.0f); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
void |
||||||
|
Phaser::setpreset (int npreset) |
||||||
|
{ |
||||||
|
const int PRESET_SIZE = 12; |
||||||
|
const int NUM_PRESETS = 6; |
||||||
|
int presets[NUM_PRESETS][PRESET_SIZE] = { |
||||||
|
//Phaser1
|
||||||
|
{64, 64, 11, 0, 0, 64, 110, 64, 1, 0, 0, 20}, |
||||||
|
//Phaser2
|
||||||
|
{64, 64, 10, 0, 0, 88, 40, 64, 3, 0, 0, 20}, |
||||||
|
//Phaser3
|
||||||
|
{64, 64, 8, 0, 0, 66, 68, 107, 2, 0, 0, 20}, |
||||||
|
//Phaser4
|
||||||
|
{39, 64, 1, 0, 0, 66, 67, 10, 5, 0, 1, 20}, |
||||||
|
//Phaser5
|
||||||
|
{64, 64, 1, 0, 1, 110, 67, 78, 10, 0, 0, 20}, |
||||||
|
//Phaser6
|
||||||
|
{64, 64, 31, 100, 0, 58, 37, 78, 3, 0, 0, 20} |
||||||
|
}; |
||||||
|
|
||||||
|
if(npreset>NUM_PRESETS-1) { |
||||||
|
|
||||||
|
} else { |
||||||
|
for (int n = 0; n < PRESET_SIZE; n++) |
||||||
|
changepar (n, presets[npreset][n]); |
||||||
|
} |
||||||
|
Ppreset = npreset; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
void |
||||||
|
Phaser::changepar (int npar, int value) |
||||||
|
{ |
||||||
|
switch (npar) { |
||||||
|
case 0: |
||||||
|
setvolume (value); |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
setpanning (value); |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
lfo->Pfreq = value; |
||||||
|
lfo->updateparams (PERIOD); |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
lfo->Prandomness = value; |
||||||
|
lfo->updateparams (PERIOD); |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
lfo->PLFOtype = value; |
||||||
|
lfo->updateparams (PERIOD); |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
lfo->Pstereo = value; |
||||||
|
lfo->updateparams (PERIOD); |
||||||
|
break; |
||||||
|
case 6: |
||||||
|
setdepth (value); |
||||||
|
break; |
||||||
|
case 7: |
||||||
|
setfb (value); |
||||||
|
break; |
||||||
|
case 8: |
||||||
|
setstages (value); |
||||||
|
break; |
||||||
|
case 9: |
||||||
|
setlrcross (value); |
||||||
|
break; |
||||||
|
case 10: |
||||||
|
if (value > 1) |
||||||
|
value = 1; |
||||||
|
Poutsub = value; |
||||||
|
break; |
||||||
|
case 11: |
||||||
|
setphase (value); |
||||||
|
break; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
int |
||||||
|
Phaser::getpar (int npar) |
||||||
|
{ |
||||||
|
switch (npar) { |
||||||
|
case 0: |
||||||
|
return (Pvolume); |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
return (Ppanning); |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
return (lfo->Pfreq); // tempo
|
||||||
|
break; |
||||||
|
case 3: |
||||||
|
return (lfo->Prandomness); |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
return (lfo->PLFOtype); |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
return (lfo->Pstereo); // STDL
|
||||||
|
break; |
||||||
|
case 6: |
||||||
|
return (Pdepth); |
||||||
|
break; |
||||||
|
case 7: |
||||||
|
return (Pfb); // pfb feedback
|
||||||
|
break; |
||||||
|
case 8: |
||||||
|
return (Pstages); |
||||||
|
break; |
||||||
|
case 9: |
||||||
|
return (Plrcross); |
||||||
|
break; |
||||||
|
case 10: |
||||||
|
return (Poutsub); |
||||||
|
break; |
||||||
|
case 11: |
||||||
|
return (Pphase); |
||||||
|
break; |
||||||
|
default: |
||||||
|
return (0); |
||||||
|
} |
||||||
|
}; |
@ -0,0 +1,77 @@ |
|||||||
|
/*
|
||||||
|
ZynAddSubFX - a software synthesizer |
||||||
|
|
||||||
|
Phaser.h - Phaser effect |
||||||
|
Copyright (C) 2002-2005 Nasca Octavian Paul |
||||||
|
Author: Nasca Octavian Paul |
||||||
|
|
||||||
|
Modified for rakarrack by Josep Andreu |
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify |
||||||
|
it under the terms of version 2 of the GNU General Public License |
||||||
|
as published by the Free Software Foundation. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License (version 2) for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License (version 2) |
||||||
|
along with this program; if not, write to the Free Software Foundation, |
||||||
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||||
|
|
||||||
|
*/ |
||||||
|
#ifndef PHASER_H |
||||||
|
#define PHASER_H |
||||||
|
#include "global.h" |
||||||
|
#include "EffectLFO.h" |
||||||
|
|
||||||
|
class Phaser |
||||||
|
{ |
||||||
|
public: |
||||||
|
Phaser (float * efxoutl_, float * efxoutr_, double sample_rate); |
||||||
|
~Phaser (); |
||||||
|
void out (float * smpsl, float * smpsr, uint32_t period); |
||||||
|
void setpreset (int npreset); |
||||||
|
void changepar (int npar, int value); |
||||||
|
int getpar (int npar); |
||||||
|
void cleanup (); |
||||||
|
int Ppreset; |
||||||
|
float outvolume; |
||||||
|
|
||||||
|
float *efxoutl; |
||||||
|
float *efxoutr; |
||||||
|
|
||||||
|
uint32_t PERIOD; |
||||||
|
EffectLFO *lfo; //Phaser modulator
|
||||||
|
|
||||||
|
private: |
||||||
|
void setvolume (int Pvolume); |
||||||
|
void setpanning (int Ppanning); |
||||||
|
void setdepth (int Pdepth); |
||||||
|
void setfb (int Pfb); |
||||||
|
void setlrcross (int Plrcross); |
||||||
|
void setstages (int Pstages); |
||||||
|
void setphase (int Pphase); |
||||||
|
|
||||||
|
|
||||||
|
//Parametrii Phaser
|
||||||
|
int Pvolume; |
||||||
|
int Ppanning; |
||||||
|
int Pdepth; //the depth of the Phaser
|
||||||
|
int Pfb; //feedback
|
||||||
|
int Plrcross; //feedback
|
||||||
|
int Pstages; |
||||||
|
int Poutsub; //if I wish to substract the output instead of the adding it
|
||||||
|
int Pphase; |
||||||
|
|
||||||
|
//Control Parametrii
|
||||||
|
|
||||||
|
//Valorile interne
|
||||||
|
float panning, fb, depth, lrcross, fbl, fbr, phase; |
||||||
|
float *oldl, *oldr; |
||||||
|
float oldlgain, oldrgain; |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,50 @@ |
|||||||
|
/*
|
||||||
|
Cubic Sine Approximation based upon a modified Taylor Series Expansion |
||||||
|
Author: Ryan Billing (C) 2010 |
||||||
|
|
||||||
|
This is unlicensed. Do whatever you want with but use at your own disgression. |
||||||
|
The author makes no guarantee of its suitability for any purpose. |
||||||
|
*/ |
||||||
|
#ifndef FSIN_H |
||||||
|
#define FSIN_H |
||||||
|
|
||||||
|
#include <arm_math.h> |
||||||
|
#include "global.h" |
||||||
|
|
||||||
|
//globals
|
||||||
|
static const float p2 = PI/2.0f; |
||||||
|
static const float fact3 = 0.148148148148148f; //can multiply by 1/fact3
|
||||||
|
|
||||||
|
static inline float |
||||||
|
f_sin(float x) |
||||||
|
{ |
||||||
|
|
||||||
|
float y; //function output
|
||||||
|
float tmp; |
||||||
|
bool sign; |
||||||
|
if ((x>D_PI) || (x<-D_PI)) x = fmod(x,D_PI); |
||||||
|
if (x < 0.0f) x+=D_PI; |
||||||
|
sign = 0; |
||||||
|
if(x>PI) { |
||||||
|
x = D_PI - x; |
||||||
|
sign = 1; |
||||||
|
} |
||||||
|
|
||||||
|
if (x <= p2) y = x - x*x*x*fact3; |
||||||
|
else { |
||||||
|
tmp = x - PI; |
||||||
|
y = -tmp + tmp*tmp*tmp*fact3; |
||||||
|
} |
||||||
|
|
||||||
|
if (sign) y = -y; |
||||||
|
|
||||||
|
return y; |
||||||
|
} |
||||||
|
|
||||||
|
static inline float |
||||||
|
f_cos(float x_) |
||||||
|
{ |
||||||
|
return f_sin(p2 + x_); |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,181 @@ |
|||||||
|
/*
|
||||||
|
rakarrack - a guitar efects software |
||||||
|
|
||||||
|
global.h - Variable Definitions and functions |
||||||
|
Copyright (C) 2008-2010 Josep Andreu |
||||||
|
Author: Josep Andreu & Ryan Billing |
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify |
||||||
|
it under the terms of version 2 of the GNU General Public License |
||||||
|
as published by the Free Software Foundation. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License (version 2) for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License |
||||||
|
(version2) along with this program; if not, write to the Free Software Foundation, |
||||||
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||||
|
|
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
#ifndef DXEMU_H |
||||||
|
#define DXEMU_H |
||||||
|
|
||||||
|
#include <arm_math.h> |
||||||
|
|
||||||
|
#define D_PI 6.283185f |
||||||
|
//#define PI 3.141598f
|
||||||
|
#define LOG_10 2.302585f |
||||||
|
#define LOG_2 0.693147f |
||||||
|
#define LN2R 1.442695041f |
||||||
|
#define CNST_E 2.71828182845905f |
||||||
|
#define AMPLITUDE_INTERPOLATION_THRESHOLD 0.0001f |
||||||
|
#define FF_MAX_VOWELS 6 |
||||||
|
#define FF_MAX_FORMANTS 12 |
||||||
|
#define FF_MAX_SEQUENCE 8 |
||||||
|
#define MAX_FILTER_STAGES 5 |
||||||
|
#define RND (rand()/(RAND_MAX+1.0)) |
||||||
|
#define RND1 (((float) rand())/(((float) RAND_MAX)+1.0f)) |
||||||
|
#define F2I(f,i) (i)=((f>0) ? ( (int)(f) ) :( (int)(f-1.0f) )) |
||||||
|
#define dB2rap(dB) (float)((expf((dB)*LOG_10/20.0f))) |
||||||
|
#define rap2dB(rap) (float)((20*log(rap)/LOG_10)) |
||||||
|
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) |
||||||
|
#define INTERPOLATE_AMPLITUDE(a,b,x,size) ( (a) + ( (b) - (a) ) * (float)(x) / (float) (size) ) |
||||||
|
#define ABOVE_AMPLITUDE_THRESHOLD(a,b) ( ( 2.0f*fabs( (b) - (a) ) / ( fabs( (b) + (a) + 0.0000000001f) ) ) > AMPLITUDE_INTERPOLATION_THRESHOLD ) |
||||||
|
#define POLY 8 |
||||||
|
#define DENORMAL_GUARD 1e-18f // Make it smaller until CPU problem re-appears
|
||||||
|
#define SwapFourBytes(data) ( (((data) >> 24) & 0x000000ff) | (((data) >> 8) & 0x0000ff00) | (((data) << 8) & 0x00ff0000) | (((data) << 24) & 0xff000000) ) |
||||||
|
#define D_NOTE 1.059463f |
||||||
|
#define LOG_D_NOTE 0.057762f |
||||||
|
#define D_NOTE_SQRT 1.029302f |
||||||
|
#define MAX_PEAKS 8 |
||||||
|
#define MAX_ALIENWAH_DELAY 100 |
||||||
|
#define ATTACK 0.175f //crossover time for reverse delay
|
||||||
|
#define MAX_DELAY 2 // Number of Seconds
|
||||||
|
#define MAXHARMS 8 // max number of harmonics available
|
||||||
|
#define MAX_PHASER_STAGES 12 |
||||||
|
#define MAX_CHORUS_DELAY 250.0f //ms
|
||||||
|
#define LN2 (1.0f) //Uncomment for att/rel to behave more like a capacitor.
|
||||||
|
#define MUG_CORR_FACT 0.4f |
||||||
|
//Crunch waveshaping constants
|
||||||
|
#define Thi 0.67f //High threshold for limiting onset
|
||||||
|
#define Tlo -0.65f //Low threshold for limiting onset
|
||||||
|
#define Tlc -0.6139445f //Tlo + sqrt(Tlo/500)
|
||||||
|
#define Thc 0.6365834f //Thi - sqrt(Thi/600)
|
||||||
|
#define CRUNCH_GAIN 100.0f //Typical voltage gain for most OD stompboxes
|
||||||
|
#define DIV_TLC_CONST 0.002f // 1/300
|
||||||
|
#define DIV_THC_CONST 0.0016666f // 1/600 (approximately)
|
||||||
|
//End waveshaping constants
|
||||||
|
#define D_FLANGE_MAX_DELAY 0.055f // Number of Seconds - 50ms corresponds to fdepth = 20 (Hz). Added some extra for padding
|
||||||
|
#define LFO_CONSTANT 9.765625e-04 // 1/(2^LOG_FMAX - 1)
|
||||||
|
#define LOG_FMAX 10.0f // -- This optimizes LFO sweep for useful range.
|
||||||
|
#define MINDEPTH 20.0f // won't allow filter lower than 20Hz
|
||||||
|
#define MAXDEPTH 15000.0f // Keeps delay greater than 2 samples at 44kHz SR
|
||||||
|
#define MAX_EQ_BANDS 16 |
||||||
|
#define CLOSED 1 |
||||||
|
#define OPENING 2 |
||||||
|
#define OPEN 3 |
||||||
|
#define CLOSING 4 |
||||||
|
#define ENV_TR 0.0001f |
||||||
|
#define HARMONICS 11 |
||||||
|
#define REV_COMBS 8 |
||||||
|
#define REV_APS 4 |
||||||
|
#define MAX_SFILTER_STAGES 12 |
||||||
|
|
||||||
|
#define TEMPBUFSIZE 1024 |
||||||
|
|
||||||
|
typedef union { |
||||||
|
float f; |
||||||
|
long i; |
||||||
|
} ls_pcast32; |
||||||
|
|
||||||
|
/*
|
||||||
|
static inline float f_pow2(float x) |
||||||
|
{ |
||||||
|
ls_pcast32 *px, tx, lx; |
||||||
|
float dx; |
||||||
|
|
||||||
|
px = (ls_pcast32 *)&x; // store address of float as long pointer
|
||||||
|
tx.f = (x-0.5f) + (3<<22); // temporary value for truncation
|
||||||
|
lx.i = tx.i - 0x4b400000; // integer power of 2
|
||||||
|
dx = x - (float)lx.i; // float remainder of power of 2
|
||||||
|
|
||||||
|
x = 1.0f + dx * (0.6960656421638072f + // cubic apporoximation of 2^x
|
||||||
|
dx * (0.224494337302845f + // for x in the range [0, 1]
|
||||||
|
dx * (0.07944023841053369f))); |
||||||
|
(*px).i += (lx.i << 23); // add integer power of 2 to exponent
|
||||||
|
|
||||||
|
return (*px).f; |
||||||
|
} |
||||||
|
*/ |
||||||
|
/*
|
||||||
|
#define P2a0 1.00000534060469 |
||||||
|
#define P2a1 0.693057900547259 |
||||||
|
#define P2a2 0.239411678986933 |
||||||
|
#define P2a3 0.0532229404911678 |
||||||
|
#define P2a4 0.00686649174914722 |
||||||
|
#include <math.h> |
||||||
|
static inline float f_pow2(float x) |
||||||
|
{ |
||||||
|
float y,xx, intpow; |
||||||
|
long xint = (int) fabs(ceil(x)); |
||||||
|
xx = x - ceil(x); |
||||||
|
xint = xint<<xint; |
||||||
|
if(x>0) intpow = (float) xint; |
||||||
|
else intpow = 1.0f; |
||||||
|
|
||||||
|
y = intpow*(xx*(xx*(xx*(xx*P2a4 + P2a3) + P2a2) + P2a1) + P2a0); |
||||||
|
|
||||||
|
return y; |
||||||
|
|
||||||
|
} |
||||||
|
*/ |
||||||
|
|
||||||
|
//The below pow function really works & is good to 16 bits, but is it faster than math lib powf()???
|
||||||
|
//globals
|
||||||
|
#include <math.h> |
||||||
|
static const float a[5] = { 1.00000534060469, 0.693057900547259, 0.239411678986933, 0.0532229404911678, 0.00686649174914722 }; |
||||||
|
//lookup for positive powers of 2
|
||||||
|
static const float pw2[25] = {1.0f, 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f, 128.0f, 256.0f, 512.0f, 1024.0f, 2048.0f, 4096.0f, 8192.0f, 16384.0f, 32768.0f, 65536.0f, 131072.0f, 262144.0f, 524288.0f, 1048576.0f, 2097152.0f, 4194304.0f, 8388608.0f, 16777216.0f}; |
||||||
|
//negative powers of 2, notice ipw2[0] will never be indexed.
|
||||||
|
static const float ipw2[25] = {1.0, 5.0e-01, 2.5e-01, 1.25e-01, 6.25e-02, 3.125e-02, 1.5625e-02, 7.8125e-03, 3.90625e-03, 1.953125e-03, 9.765625e-04, 4.8828125e-04, 2.44140625e-04, 1.220703125e-04, 6.103515625e-05, 3.0517578125e-05, 1.52587890625e-05, 7.62939453125e-06, 3.814697265625e-06, 1.9073486328125e-06, 9.5367431640625e-07, 4.76837158203125e-07, 2.38418579101562e-07, 1.19209289550781e-07, 5.96046447753906e-08}; |
||||||
|
|
||||||
|
static inline float f_pow2(float x) |
||||||
|
{ |
||||||
|
float y = 0.0f; |
||||||
|
|
||||||
|
if(x >=24) return pw2[24]; |
||||||
|
else if (x <= -24.0f) return ipw2[24]; |
||||||
|
else { |
||||||
|
float whole = ceilf(x); |
||||||
|
int xint = (int) whole; |
||||||
|
x = x - whole; |
||||||
|
|
||||||
|
if (xint>=0) { |
||||||
|
y = pw2[xint]*(x*(x*(x*(x*a[4] + a[3]) + a[2]) + a[1]) + a[0]); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
y = ipw2[-xint]*(x*(x*(x*(x*a[4] + a[3]) + a[2]) + a[1]) + a[0]); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return y; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#define f_exp(x) f_pow2(x * LN2R) |
||||||
|
|
||||||
|
//#include "config.h"
|
||||||
|
#include <sys/time.h> |
||||||
|
#include <stdint.h> |
||||||
|
#include <string.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
//#include "FPreset.h"
|
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue