ref: 6e322e9033baed4027c8b3184c41fbc8df18b186
parent: 61205ba2be7fbb6b695eb0bdfa8ffc0ed365ac0b
author: spiricom <jeff@snyderphonics.com>
date: Thu Dec 26 14:56:16 EST 2019
jeff updates from working on vocodec over dec 22-26
binary files a/.DS_Store b/.DS_Store differ
binary files a/LEAF/.DS_Store b/LEAF/.DS_Store differ
binary files a/LEAF/Inc/.DS_Store b/LEAF/Inc/.DS_Store differ
--- a/LEAF/Inc/leaf-distortion.h
+++ b/LEAF/Inc/leaf-distortion.h
@@ -25,10 +25,24 @@
typedef struct _tLockhartWavefolder
{
- double Ln1;
- double Fn1;
+ float Ln1;
+ float Fn1;
float xn1;
+ float RL;
+ float R;
+ float VT;
+ float Is;
+
+ float a;
+ float b;
+ float d;
+
+ // Antialiasing error threshold
+ float thresh;
+ float half_a;
+ float longthing;
+
} _tLockhartWavefolder;
typedef _tLockhartWavefolder* tLockhartWavefolder;
--- a/LEAF/Inc/leaf-filters.h
+++ b/LEAF/Inc/leaf-filters.h
@@ -50,12 +50,8 @@
float gain;
float a0,a1;
float b0,b1;
-
- float coef;
-
- float freq;
-
float lastIn, lastOut;
+
} _tOnePole;
@@ -83,7 +79,7 @@
float radius, frequency;
oBool normalize;
-
+
float lastOut[2];
} _tTwoPole;
@@ -288,7 +284,7 @@
{
float gain;
- float N;
+ int N;
tSVF low[NUM_SVF_BW];
tSVF high[NUM_SVF_BW];
--- a/LEAF/Inc/leaf-global.h
+++ b/LEAF/Inc/leaf-global.h
@@ -20,7 +20,7 @@
float sampleRate;
float invSampleRate;
int blockSize;
-
+ float twoPiTimesInvSampleRate;
float (*random)(void);
} LEAF;
--- a/LEAF/Inc/leaf-math.h
+++ b/LEAF/Inc/leaf-math.h
@@ -64,13 +64,16 @@
#define INV_LOG2 3.321928095f
#define SOS_M 343.0f
-
+#define TWO_TO_5 32.0f
+#define INV_TWO_TO_5 0.03125f
#define TWO_TO_7 128.f
#define INV_TWO_TO_7 0.0078125f
#define TWO_TO_8 256.f
#define INV_TWO_TO_8 0.00390625f
-#define TWO_TO_5 32.0f
-#define INV_TWO_TO_5 0.03125f
+#define TWO_TO_10 1024.f
+#define INV_TWO_TO_10 0.0009765625f
+#define TWO_TO_11 2048.f
+#define INV_TWO_TO_11 0.00048828125f
#define TWO_TO_12 4096.f
#define INV_TWO_TO_12 0.00024414062f
#define TWO_TO_15 32768.f
@@ -133,8 +136,18 @@
#define LOGTEN 2.302585092994
+ float fast_mtof(float f);
+
+ float fastexpf(float x);
+
+ float fasterexpf(float x);
+
float mtof(float f);
+ float fast_mtof(float f);
+
+ float faster_mtof(float f);
+
float ftom(float f);
float powtodb(float f);
--- a/LEAF/Inc/leaf-reverb.h
+++ b/LEAF/Inc/leaf-reverb.h
@@ -136,8 +136,9 @@
void tDattorroReverb_free (tDattorroReverb* const);
float tDattorroReverb_tick (tDattorroReverb* const, float input);
-
+ void tDattorroReverb_tickStereo (tDattorroReverb* const rev, float input, float* output);
void tDattorroReverb_setMix (tDattorroReverb* const, float mix);
+ void tDattorroReverb_setHP (tDattorroReverb* const, float freq);
void tDattorroReverb_setSize (tDattorroReverb* const, float size);
void tDattorroReverb_setInputDelay (tDattorroReverb* const, float preDelay);
void tDattorroReverb_setInputFilter (tDattorroReverb* const, float freq);
binary files a/LEAF/Src/.DS_Store b/LEAF/Src/.DS_Store differ
--- a/LEAF/Src/leaf-distortion.c
+++ b/LEAF/Src/leaf-distortion.c
@@ -28,6 +28,20 @@
w->Ln1 = 0.0;
w->Fn1 = 0.0;
w->xn1 = 0.0f;
+
+ w->RL = 7.5e3;
+ w->R = 15e3;
+ w->VT = 26e-3;
+ w->Is = 10e-16;
+
+ w->a = 2.0*w->RL/w->R;
+ w->b = (w->R+2.0*w->RL)/(w->VT*w->R);
+ w->d = (w->RL*w->Is)/w->VT;
+ w->half_a = 0.5f * w->a;
+ w->longthing = (0.5*w->VT/w->b);
+
+ // Antialiasing error threshold
+ w->thresh = 10e-10;
}
void tLockhartWavefolder_free(tLockhartWavefolder* const wf)
@@ -73,37 +87,27 @@
float out = 0.0f;
// Constants
- double RL = 7.5e3;
- double R = 15e3;
- double VT = 26e-3;
- double Is = 10e-16;
+
- double a = 2.0*RL/R;
- double b = (R+2.0*RL)/(VT*R);
- double d = (RL*Is)/VT;
-
- // Antialiasing error threshold
- double thresh = 10e-10;
-
// Compute Antiderivative
int l = (samp > 0) - (samp < 0);
- double u = d*exp(l*b*samp);
+ double u = w->d*exp(l*w->b*samp);
double Ln = tLockhartWavefolderLambert(u,w->Ln1);
- double Fn = (0.5*VT/b)*(Ln*(Ln + 2.0)) - 0.5*a*samp*samp;
+ double Fn = w->longthing*(Ln*(Ln + 2.0)) - w->half_a*samp*samp;
// Check for ill-conditioning
- if (fabs(samp-w->xn1)<thresh) {
+ if (fabs(samp-w->xn1)<w->thresh) {
// Compute Averaged Wavefolder Output
double xn = 0.5*(samp+w->xn1);
- u = d*exp(l*b*xn);
+ u = w->d*exp(l*w->b*xn);
Ln = tLockhartWavefolderLambert(u,w->Ln1);
- out = (float) (l*VT*Ln - a*xn);
+ out = (float) (l*w->VT*Ln - w->a*xn);
if (isnan(out))
{
;
}
-
+
}
else {
--- a/LEAF/Src/leaf-effects.c
+++ b/LEAF/Src/leaf-effects.c
@@ -644,13 +644,17 @@
{
_tAutotune* r = *rt;
- r->inputPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
-
- for (int v = 0; v < r->numVoices; ++v)
- {
- r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
- }
-
+ float tempPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
+ if (tempPeriod < 1000.0f) //to avoid trying to follow consonants
+ {
+ r->inputPeriod = tempPeriod;
+ }
+
+ for (int v = 0; v < r->numVoices; ++v)
+ {
+ r->tickOutput[v] = tPitchShift_shiftToFreq(&r->ps[v], r->freq[v]);
+ }
+
return r->tickOutput;
}
@@ -1273,7 +1277,7 @@
fs->falph = powf(0.001f, 80.0f / (leaf.sampleRate));
- fs->flamb = -(0.8517f*sqrt(atanf(0.06583f*leaf.sampleRate))-0.1916f);
+ fs->flamb = -(0.8517f*sqrtf(atanf(0.06583f*leaf.sampleRate))-0.1916f);
fs->fhp = 0.0f;
fs->flp = 0.0f;
fs->flpa = powf(0.001f, 10.0f / (leaf.sampleRate));
@@ -1280,6 +1284,8 @@
fs->fmute = 1.0f;
fs->fmutealph = powf(0.001f, 1.0f / (leaf.sampleRate));
fs->cbi = 0;
+ fs->intensity = 1.0f;
+ fs->invIntensity = 1.0f;
}
void tFormantShifter_free(tFormantShifter* const fsr)
@@ -1314,12 +1320,11 @@
in *= fs->intensity;
- float fa, fb, fc, foma, falph, ford, flpa, flamb, tf, fk;
+ float fa, fb, fc, foma, falph, ford, flamb, tf, fk;
int ti4;
ford = fs->ford;
falph = fs->falph;
foma = (1.0f - falph);
- flpa = fs->flpa;
flamb = fs->flamb;
tf = in;
@@ -1356,11 +1361,11 @@
{
_tFormantShifter* fs = *fsr;
- float fa, fb, fc, foma, falph, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
+ float fa, fb, fc, falph, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
int ti4;
ford = fs->ford;
falph = fs->falph;
- foma = (1.0f - falph);
+
flpa = fs->flpa;
flamb = fs->flamb;
tf = fs->shiftFactor * (1+flamb)/(1-flamb);
@@ -1368,7 +1373,7 @@
ti4 = fs->cbi;
tf2 = in;
- fa = 0;
+ fa = 0.0f;
fb = fa;
for (int i=0; i<ford; i++)
{
@@ -1407,13 +1412,13 @@
tf = 2.0f*tf2;
tf2 = tf;
tf = (1.0f - f1resp + f0resp);
- if (tf!=0)
+ if (tf!=0.0f)
{
tf2 = (tf2 + f0resp) / tf;
}
else
{
- tf2 = 0;
+ tf2 = 0.0f;
}
// third time: update delay registers
@@ -1434,16 +1439,16 @@
// Bring up the gain slowly when formant correction goes from disabled
// to enabled, while things stabilize.
- if (fs->fmute>0.5)
+ if (fs->fmute>0.5f)
{
- tf = tf*(fs->fmute - 0.5)*2;
+ tf = tf*(fs->fmute - 0.5f)*2.0f;
}
else
{
- tf = 0;
+ tf = 0.0f;
}
tf2 = fs->fmutealph;
- fs->fmute = (1-tf2) + tf2*fs->fmute;
+ fs->fmute = (1.0f-tf2) + tf2*fs->fmute;
// now tf is signal output
// ...and we're done messing with formants
@@ -1461,5 +1466,14 @@
{
_tFormantShifter* fs = *fsr;
fs->intensity = intensity;
- fs->invIntensity = 1.0f/fs->intensity;
+ //make sure you don't divide by zero, doofies
+ if (fs->intensity != 0.0f)
+ {
+ fs->invIntensity = 1.0f/fs->intensity;
+ }
+ else
+ {
+ fs->invIntensity = 1.0f;
+ }
+
}
--- a/LEAF/Src/leaf-envelopes.c
+++ b/LEAF/Src/leaf-envelopes.c
@@ -514,7 +514,12 @@
r->curr += r->inc;
- if (((r->curr >= r->dest) && (r->inc > 0.0f)) || ((r->curr <= r->dest) && (r->inc < 0.0f))) r->inc = 0.0f;
+ if (((r->curr >= r->dest) && (r->inc > 0.0f)) || ((r->curr <= r->dest) && (r->inc < 0.0f)))
+ {
+ r->inc = 0.0f;
+ r->curr=r->dest;
+ }
+
// Palle: There is a slight risk that you overshoot here and stay on dest+inc, which with a large inc value could be a real problem
// I suggest you add: r->curr=r->dest in the true if case
--- a/LEAF/Src/leaf-filters.c
+++ b/LEAF/Src/leaf-filters.c
@@ -279,7 +279,7 @@
f->radius = radius;
f->b2 = radius * radius;
- f->b1 = -2.0f * radius * cosf(TWO_PI * freq * leaf.invSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
+ f->b1 = -2.0f * radius * cosf(freq * leaf.twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
// Normalize the filter gain. From STK.
if ( f->b1 > 0.0f ) // Maximum at z = 0.
@@ -331,7 +331,7 @@
f->gain = 1.0f;
f->a0 = 1.0;
-
+
tOnePole_setFreq(ft, freq);
f->lastIn = 0.0f;
@@ -374,7 +374,7 @@
void tOnePole_setFreq (tOnePole* const ft, float freq)
{
_tOnePole* f = *ft;
- f->b0 = freq * TWO_PI * leaf.invSampleRate;
+ f->b0 = freq * leaf.twoPiTimesInvSampleRate;
f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
f->a1 = 1.0f - f->b0;
}
@@ -462,7 +462,8 @@
{
_tTwoPole* f = *ft;
- if (frequency < 0.0f) frequency = 0.0f; // need to also handle when frequency > nyquist
+ if (frequency < 0.0f) frequency = 0.0f;
+ if (frequency > (leaf.sampleRate * 0.49f)) frequency = leaf.sampleRate * 0.49f;
if (radius < 0.0f) radius = 0.0f;
if (radius >= 1.0f) radius = 0.999999f;
@@ -471,14 +472,14 @@
f->normalize = normalize;
f->a2 = radius * radius;
- f->a1 = -2.0f * radius * cos(TWO_PI * frequency * leaf.invSampleRate);
+ f->a1 = -2.0f * radius * cosf(frequency * leaf.twoPiTimesInvSampleRate);
if ( normalize )
{
// Normalize the filter gain ... not terribly efficient.
- float real = 1 - radius + (f->a2 - radius) * cos(TWO_PI * 2 * frequency * leaf.invSampleRate);
- float imag = (f->a2 - radius) * sin(TWO_PI * 2 * frequency * leaf.invSampleRate);
- f->b0 = sqrt( pow(real, 2) + pow(imag, 2) );
+ float real = 1 - radius + (f->a2 - radius) * cosf(2 * frequency * leaf.twoPiTimesInvSampleRate);
+ float imag = (f->a2 - radius) * sinf(2 * frequency * leaf.twoPiTimesInvSampleRate);
+ f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
}
}
@@ -501,14 +502,14 @@
_tTwoPole* f = *ft;
f->a2 = f->radius * f->radius;
- f->a1 = -2.0f * f->radius * cos(TWO_PI * f->frequency * leaf.invSampleRate);
+ f->a1 = -2.0f * f->radius * cosf(f->frequency * leaf.twoPiTimesInvSampleRate);
if ( f->normalize )
{
// Normalize the filter gain ... not terribly efficient.
- float real = 1 - f->radius + (f->a2 - f->radius) * cos(TWO_PI * 2 * f->frequency * leaf.invSampleRate);
- float imag = (f->a2 - f->radius) * sin(TWO_PI * 2 * f->frequency * leaf.invSampleRate);
- f->b0 = sqrt( pow(real, 2) + pow(imag, 2) );
+ float real = 1 - f->radius + (f->a2 - f->radius) * cosf(2 * f->frequency * leaf.twoPiTimesInvSampleRate);
+ float imag = (f->a2 - f->radius) * sinf(2 * f->frequency * leaf.twoPiTimesInvSampleRate);
+ f->b0 = sqrtf( powf(real, 2) + powf(imag, 2) );
}
}
@@ -663,8 +664,8 @@
{
_tBiQuad* f = *ft;
- // Should also deal with frequency being > half sample rate / nyquist. See STK
if (freq < 0.0f) freq = 0.0f;
+ if (freq > (leaf.sampleRate * 0.49f)) freq = leaf.sampleRate * 0.49f;
if (radius < 0.0f) radius = 0.0f;
if (radius >= 1.0f) radius = 1.0f;
@@ -673,7 +674,7 @@
f->normalize = normalize;
f->a2 = radius * radius;
- f->a1 = -2.0f * radius * cosf(TWO_PI * freq * leaf.invSampleRate);
+ f->a1 = -2.0f * radius * cosf(freq * leaf.twoPiTimesInvSampleRate);
if (normalize)
{
@@ -687,12 +688,12 @@
{
_tBiQuad* f = *ft;
- // Should also deal with frequency being > half sample rate / nyquist. See STK
if (freq < 0.0f) freq = 0.0f;
+ if (freq > (leaf.sampleRate * 0.49f)) freq = leaf.sampleRate * 0.49f;
if (radius < 0.0f) radius = 0.0f;
f->b2 = radius * radius;
- f->b1 = -2.0f * radius * cosf(TWO_PI * freq * leaf.invSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
+ f->b1 = -2.0f * radius * cosf(freq * leaf.twoPiTimesInvSampleRate); // OPTIMIZE with LOOKUP or APPROXIMATION
// Does not attempt to normalize filter gain.
}
@@ -755,7 +756,7 @@
{
_tBiQuad* f = *ft;
f->a2 = f->radius * f->radius;
- f->a1 = -2.0f * f->radius * cosf(TWO_PI * f->frequency * leaf.invSampleRate);
+ f->a1 = -2.0f * f->radius * cosf(f->frequency * leaf.twoPiTimesInvSampleRate);
if (f->normalize)
{
@@ -770,7 +771,7 @@
{
_tHighpass* f = *ft = (_tHighpass*) leaf_alloc(sizeof(_tHighpass));
- f->R = (1.0f-((freq * 2.0f * 3.14f)* leaf.invSampleRate));
+ f->R = (1.0f - (freq * leaf.twoPiTimesInvSampleRate));
f->ys = 0.0f;
f->xs = 0.0f;
@@ -788,7 +789,7 @@
{
_tHighpass* f = *ft;
f->frequency = freq;
- f->R = (1.0f-((freq * 2.0f * 3.14f) * leaf.invSampleRate));
+ f->R = (1.0f - (freq * leaf.twoPiTimesInvSampleRate));
}
@@ -813,7 +814,7 @@
f->R = (1.0f-((f->frequency * 2.0f * 3.14f) * leaf.invSampleRate));
}
-// Less efficient, more accurate version of SVF, in which cutoff frequency is taken as floating point Hz value and tanh
+// Less efficient, more accurate version of SVF, in which cutoff frequency is taken as floating point Hz value and tanf
// is calculated when frequency changes.
void tSVF_init(tSVF* const svff, SVFType type, float freq, float Q)
{
@@ -825,17 +826,11 @@
svf->ic2eq = 0;
float a1,a2,a3,g,k;
- g = tanf(PI * freq * leaf.invSampleRate);
- k = 1.0f/Q;
- a1 = 1.0f/(1.0f+g*(g+k));
- a2 = g*a1;
- a3 = g*a2;
-
- svf->g = g;
- svf->k = k;
- svf->a1 = a1;
- svf->a2 = a2;
- svf->a3 = a3;
+ svf->g = tanf(PI * freq * leaf.invSampleRate);
+ svf->k = 1.0f/Q;
+ svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
+ svf->a2 = g*a1;
+ svf->a3 = g*a2;
}
void tSVF_free(tSVF* const svff)
@@ -896,17 +891,11 @@
svf->ic2eq = 0;
float a1,a2,a3,g,k;
- g = filtertan[input];
- k = 1.0f/Q;
- a1 = 1.0f/(1.0f+g*(g+k));
- a2 = g*a1;
- a3 = g*a2;
-
- svf->g = g;
- svf->k = k;
- svf->a1 = a1;
- svf->a2 = a2;
- svf->a3 = a3;
+ svf->g = filtertan[input];
+ svf->k = 1.0f/Q;
+ svf->a1 = 1.0f/(1.0f+g*(g+k));
+ svf->a2 = g*a1;
+ svf->a3 = g*a2;
}
void tEfficientSVF_free(tEfficientSVF* const svff)
--- a/LEAF/Src/leaf-math.c
+++ b/LEAF/Src/leaf-math.c
@@ -73,6 +73,22 @@
return alias.f;
}
+
+float fastexpf(float x) {
+ x = 1.0f + (x * 0.0009765625f);
+ x *= x; x *= x; x *= x; x *= x;
+ x *= x; x *= x; x *= x; x *= x;
+ x *= x; x *= x;
+ return x;
+}
+
+float fasterexpf(float x) {
+ x = 1.0 + (x * 0.00390625f);
+ x *= x; x *= x; x *= x; x *= x;
+ x *= x; x *= x; x *= x; x *= x;
+ return x;
+}
+
// fast floating-point exp2 function taken from Robert Bristow Johnson's
// post in the music-dsp list on Date: Tue, 02 Sep 2014 16:50:11 -0400
float fastexp2f(float x)
@@ -394,6 +410,16 @@
if (f <= -1500.0f) return(0);
else if (f > 1499.0f) return(mtof(1499.0f));
else return (8.17579891564f * expf(0.0577622650f * f));
+}
+
+float fast_mtof(float f)
+{
+ return (8.17579891564f * fastexpf(0.0577622650f * f));
+}
+
+float faster_mtof(float f)
+{
+ return (8.17579891564f * fastexpf(0.0577622650f * f));
}
float ftom(float f)
--- a/LEAF/Src/leaf-reverb.c
+++ b/LEAF/Src/leaf-reverb.c
@@ -357,7 +357,7 @@
tOnePole_free(&r->f1_filter);
- tHighpass_free(&r->f2_hp);
+ tHighpass_free(&r->f1_hp);
tCycle_free(&r->f1_lfo);
@@ -479,6 +479,112 @@
return (input * (1.0f - r->mix) + sample * r->mix);
}
+void tDattorroReverb_tickStereo (tDattorroReverb* const rev, float input, float* output)
+{
+ _tDattorroReverb* r = *rev;
+
+ // INPUT
+ float in_sample = tTapeDelay_tick(&r->in_delay, input);
+
+ in_sample = tOnePole_tick(&r->in_filter, in_sample);
+
+ for (int i = 0; i < 4; i++)
+ {
+ in_sample = tAllpass_tick(&r->in_allpass[i], in_sample);
+ }
+
+ // FEEDBACK 1
+ float f1_sample = in_sample + r->f2_last; // + f2_last_out;
+
+ tAllpass_setDelay(&r->f1_allpass, SAMP(30.51f) + tCycle_tick(&r->f1_lfo) * SAMP(4.0f));
+
+ f1_sample = tAllpass_tick(&r->f1_allpass, f1_sample);
+
+ f1_sample = tTapeDelay_tick(&r->f1_delay_1, f1_sample);
+
+ f1_sample = tOnePole_tick(&r->f1_filter, f1_sample);
+
+ f1_sample = f1_sample + r->f1_delay_2_last * 0.5f;
+
+ float f1_delay_2_sample = tTapeDelay_tick(&r->f1_delay_2, f1_sample * 0.5f);
+
+ r->f1_delay_2_last = f1_delay_2_sample;
+
+ f1_sample = r->f1_delay_2_last + f1_sample;
+
+ f1_sample = tHighpass_tick(&r->f1_hp, f1_sample);
+
+ f1_sample *= r->feedback_gain;
+
+ f1_sample = tanhf(f1_sample);
+
+ r->f1_last = tTapeDelay_tick(&r->f1_delay_3, f1_sample);
+
+ // FEEDBACK 2
+ float f2_sample = in_sample + r->f1_last;
+
+ tAllpass_setDelay(&r->f2_allpass, SAMP(22.58f) + tCycle_tick(&r->f2_lfo) * SAMP(4.0f));
+
+ f2_sample = tAllpass_tick(&r->f2_allpass, f2_sample);
+
+ f2_sample = tTapeDelay_tick(&r->f2_delay_1, f2_sample);
+
+ f2_sample = tOnePole_tick(&r->f2_filter, f2_sample);
+
+ f2_sample = f2_sample + r->f2_delay_2_last * 0.5f;
+
+ float f2_delay_2_sample = tTapeDelay_tick(&r->f2_delay_2, f2_sample * 0.5f);
+
+ r->f2_delay_2_last = f2_delay_2_sample;
+
+ f2_sample = r->f2_delay_2_last + f2_sample;
+
+ f2_sample = tHighpass_tick(&r->f2_hp, f2_sample);
+
+ f2_sample *= r->feedback_gain;
+
+ f2_sample = tanhf(f2_sample);
+
+ r->f2_last = tTapeDelay_tick(&r->f2_delay_3, f2_sample);
+
+
+ // TAP OUT 1
+ f1_sample = tTapeDelay_tapOut(&r->f1_delay_1, SAMP(8.9f)) +
+ tTapeDelay_tapOut(&r->f1_delay_1, SAMP(99.8f));
+
+ f1_sample -= tTapeDelay_tapOut(&r->f1_delay_2, SAMP(64.2f));
+
+ f1_sample += tTapeDelay_tapOut(&r->f1_delay_3, SAMP(67.f));
+
+ f1_sample -= tTapeDelay_tapOut(&r->f2_delay_1, SAMP(66.8f));
+
+ f1_sample -= tTapeDelay_tapOut(&r->f2_delay_2, SAMP(6.3f));
+
+ f1_sample -= tTapeDelay_tapOut(&r->f2_delay_3, SAMP(35.8f));
+
+ f1_sample *= 0.14f;
+
+ // TAP OUT 2
+ f2_sample = tTapeDelay_tapOut(&r->f2_delay_1, SAMP(11.8f)) +
+ tTapeDelay_tapOut(&r->f2_delay_1, SAMP(121.7f));
+
+ f2_sample -= tTapeDelay_tapOut(&r->f2_delay_2, SAMP(6.3f));
+
+ f2_sample += tTapeDelay_tapOut(&r->f2_delay_3, SAMP(89.7f));
+
+ f2_sample -= tTapeDelay_tapOut(&r->f1_delay_1, SAMP(70.8f));
+
+ f2_sample -= tTapeDelay_tapOut(&r->f1_delay_2, SAMP(11.2f));
+
+ f2_sample -= tTapeDelay_tapOut(&r->f1_delay_3, SAMP(4.1f));
+
+ f2_sample *= 0.14f;
+
+ output[0] = input * (1.0f - r->mix) + f1_sample * r->mix;
+ output[1] = input * (1.0f - r->mix) + f2_sample * r->mix;
+
+}
+
void tDattorroReverb_setMix (tDattorroReverb* const rev, float mix)
{
_tDattorroReverb* r = *rev;
@@ -485,6 +591,16 @@
r->mix = LEAF_clip(0.0f, mix, 1.0f);
}
+
+void tDattorroReverb_setHP (tDattorroReverb* const rev, float freq)
+{
+ _tDattorroReverb* r = *rev;
+ float newFreq = LEAF_clip(20.0f, freq, 20000.0f);
+ tHighpass_setFreq(&r->f1_hp, newFreq);
+ tHighpass_setFreq(&r->f2_hp, newFreq);
+}
+
+
void tDattorroReverb_setSize (tDattorroReverb* const rev, float size)
{
_tDattorroReverb* r = *rev;
@@ -507,6 +623,7 @@
tTapeDelay_setDelay(&r->f1_delay_3, SAMP(125.f));
// maybe change rate of SINE LFO's when size changes?
+ //tCycle_setFreq(&r->f2_lfo, 0.07f * size * r->size_max);
// FEEDBACK 2
//tAllpass_setDelay(&r->f2_allpass, SAMP(22.58f));
--- a/LEAF/Src/leaf.c
+++ b/LEAF/Src/leaf.c
@@ -30,6 +30,8 @@
leaf.invSampleRate = 1.0f/sr;
+ leaf.twoPiTimesInvSampleRate = leaf.invSampleRate * TWO_PI;
+
leaf.random = random;
}