ref: 423d846d8b563bae08b1c8c2b8e685d0f615b4b6
parent: 425336efe954a71d5070a70b0b6f63098382f17a
parent: 386620799c550f502c21dbb355c64a80c7f4d4d3
author: mulshine <mulshine@princeton.edu>
date: Thu Jan 3 12:36:11 EST 2019
Merged Dattorro developments in to LEAF master.
--- a/LEAF/Inc/leaf-delay.h
+++ b/LEAF/Inc/leaf-delay.h
@@ -71,7 +71,7 @@
int tDelayL_setDelay (tDelayL* const, float delay);
float tDelayL_getDelay (tDelayL* const);
void tDelayL_tapIn (tDelayL* const, float in, uint32_t tapDelay);
-float tDelayL_tapOut (tDelayL* const, uint32_t tapDelay);
+float tDelayL_tapOut (tDelayL* const, float tapDelay);
float tDelayL_addTo (tDelayL* const, float value, uint32_t tapDelay);
float tDelayL_tick (tDelayL* const, float sample);
float tDelayL_getLastOut (tDelayL* const);
@@ -109,10 +109,7 @@
float tDelayA_addTo (tDelayA* const, float value, uint32_t tapDelay);
float tDelayA_tick (tDelayA* const, float sample);
float tDelayA_getLastOut (tDelayA* const);
-float tDelayA_getLastIn (tDelayA* const);
-void tDelayA_setGain (tDelayA* const, float gain);
-float tDelayA_getGain (tDelayA* const);
-
+float tDelayA_getLastIn (tDelayA* const);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
--- a/LEAF/Inc/leaf-filter.h
+++ b/LEAF/Inc/leaf-filter.h
@@ -14,18 +14,44 @@
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
#include "leaf-globals.h"
-#include "leaf-math.h"
+#include "leaf-math.h"
+
+#include "leaf-delay.h"
-#include "leaf-wavetables.h"
+#include "leaf-wavetables.h"
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+/* tAllpass: Schroeder allpass. Comb-filter with feedforward and feedback. */
+typedef struct _tAllpass
+{
+ float gain;
+
+ tDelayL delay;
+
+ float lastOut;
+
+} tAllpass;
+
+void tAllpass_init (tAllpass* const, float initDelay, uint32_t maxDelay);
+void tAllpass_free (tAllpass* const);
+
+float tAllpass_tick (tAllpass* const, float input);
+void tAllpass_setGain (tAllpass* const, float gain);
+void tAllpass_setDelay (tAllpass* const f, float delay);
+
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
/* tOnePole: OnePole filter, reimplemented from STK (Cook and Scavone). */
typedef struct _tOnePole
{
- float gain;
- float a0,a1;
+ float gain;
+ float a0,a1;
float b0,b1;
+
+ float coef;
+
float freq;
float lastIn, lastOut;
--- a/LEAF/Inc/leaf-reverb.h
+++ b/LEAF/Inc/leaf-reverb.h
@@ -11,14 +11,16 @@
#ifndef LEAFREVERB_H_INCLUDED
#define LEAFREVERB_H_INCLUDED
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
#include "leaf-globals.h"
#include "leaf-math.h"
-#include "leaf-delay.h"
+#include "leaf-delay.h"
+#include "leaf-filter.h"
+#include "leaf-oscillator.h"
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
/* PRCRev: Reverb, reimplemented from STK (Cook and Scavone). */
typedef struct _tPRCRev
@@ -47,7 +49,7 @@
// Set mix between dry input and wet output signal.
void tPRCRev_setMix (tPRCRev* const, float mix);
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
/* NRev: Reverb, reimplemented from STK (Cook and Scavone). */
typedef struct _tNRev
@@ -77,6 +79,61 @@
// Set mix between dry input and wet output signal.
void tNRev_setMix (tNRev* const, float mix);
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+
+typedef struct _tDattorro
+{
+ float predelay;
+ float input_filter;
+ float feedback_filter;
+ float feedback_gain;
+ float mix;
+
+ float size, t;
+
+ float f1_delay_2_last,
+ f2_delay_2_last;
+
+ float f1_last,
+ f2_last;
+
+ // INPUT
+ tDelayL in_delay;
+ tOnePole in_filter;
+ tAllpass in_allpass[4];
+
+ // FEEDBACK 1
+ tAllpass f1_allpass;
+ tDelayL f1_delay_1;
+ tOnePole f1_filter;
+ tDelayL f1_delay_2;
+ tDelayL f1_delay_3;
+
+ tCycle f1_lfo;
+
+ // FEEDBACK 2
+ tAllpass f2_allpass;
+ tDelayL f2_delay_1;
+ tOnePole f2_filter;
+ tDelayL f2_delay_2;
+ tDelayL f2_delay_3;
+
+ tCycle f2_lfo;
+
+} tDattorro;
+
+void tDattorro_init (tDattorro* const);
+void tDattorro_free (tDattorro* const);
+
+float tDattorro_tick (tDattorro* const, float input);
+
+void tDattorro_setMix (tDattorro* const, float mix);
+void tDattorro_setSize (tDattorro* const, float size);
+void tDattorro_setInputDelay (tDattorro* const, float preDelay);
+void tDattorro_setInputFilter (tDattorro* const, float freq);
+void tDattorro_setFeedbackFilter (tDattorro* const, float freq);
+void tDattorro_setFeedbackGain (tDattorro* const, float gain);
+
#endif // LEAFREVERB_H_INCLUDED
--- a/LEAF/Inc_cpp/leaf-delay.hpp
+++ b/LEAF/Inc_cpp/leaf-delay.hpp
@@ -71,7 +71,7 @@
int tDelayL_setDelay (tDelayL* const, float delay);
float tDelayL_getDelay (tDelayL* const);
void tDelayL_tapIn (tDelayL* const, float in, uint32_t tapDelay);
-float tDelayL_tapOut (tDelayL* const, uint32_t tapDelay);
+float tDelayL_tapOut (tDelayL* const, float tapDelay);
float tDelayL_addTo (tDelayL* const, float value, uint32_t tapDelay);
float tDelayL_tick (tDelayL* const, float sample);
float tDelayL_getLastOut (tDelayL* const);
@@ -100,7 +100,7 @@
} tDelayA;
void tDelayA_init (tDelayA* const, float delay, uint32_t maxDelay);
-void tDelayA_free (tDelayA* const);
+void tDelayA_free (tDelayA* const);
int tDelayA_setDelay (tDelayA* const, float delay);
float tDelayA_getDelay (tDelayA* const);
--- a/LEAF/Inc_cpp/leaf-filter.hpp
+++ b/LEAF/Inc_cpp/leaf-filter.hpp
@@ -14,18 +14,45 @@
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
#include "leaf-globals.h"
-#include "leaf-math.h"
+#include "leaf-math.h"
+
+#include "leaf-delay.h"
-#include "leaf-wavetables.h"
+#include "leaf-wavetables.h"
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+/* tAllpass: Schroeder allpass. Comb-filter with feedforward and feedback. */
+typedef struct _tAllpass
+{
+ float gain;
+
+ tDelayL delay;
+
+ float lastOut;
+
+} tAllpass;
+
+void tAllpass_init (tAllpass* const, float initDelay, uint32_t maxDelay);
+void tAllpass_free (tAllpass* const);
+
+float tAllpass_tick (tAllpass* const, float input);
+void tAllpass_setGain (tAllpass* const, float gain);
+void tAllpass_setDelay (tAllpass* const f, float delay);
+
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
/* tOnePole: OnePole filter, reimplemented from STK (Cook and Scavone). */
typedef struct _tOnePole
{
- float gain;
- float a0,a1;
- float b0,b1;
+ float gain;
+ float a0,a1;
+ float b0,b1;
+
+ float coef;
+
+ float freq;
float lastIn, lastOut;
@@ -37,7 +64,8 @@
float tOnePole_tick (tOnePole* const, float input);
void tOnePole_setB0 (tOnePole* const, float b0);
void tOnePole_setA1 (tOnePole* const, float a1);
-void tOnePole_setPole (tOnePole* const, float thePole);
+void tOnePole_setPole (tOnePole* const, float thePole);
+void tOnePole_setFreq (tOnePole* const, float freq);
void tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
void tOnePole_setGain (tOnePole* const, float gain);
--- a/LEAF/Inc_cpp/leaf-math.hpp
+++ b/LEAF/Inc_cpp/leaf-math.hpp
@@ -70,7 +70,7 @@
#define TWO_TO_31 2147483648.0f
#define INV_TWO_TO_31 0.000000000465661f
-// Erbe shaper
+// Jones shaper
float LEAF_shaper (float input, float m_drive);
float LEAF_reedTable (float input, float offset, float slope);
@@ -77,7 +77,12 @@
float LEAF_clip (float min, float val, float max);
float LEAF_softClip (float val, float thresh);
oBool LEAF_isPrime (uint64_t number );
-float LEAF_midiToFrequency (float f);
+float LEAF_midiToFrequency (float f);
+
+void LEAF_generate_sine(float* buffer, int size);
+void LEAF_generate_sawtooth(float* buffer, float basefreq, int size);
+void LEAF_generate_triangle(float* buffer, float basefreq, int size);
+void LEAF_generate_square(float* buffer, float basefreq, int size);
// dope af
float LEAF_chebyshevT(float in, int n);
--- a/LEAF/Inc_cpp/leaf-oscillator.hpp
+++ b/LEAF/Inc_cpp/leaf-oscillator.hpp
@@ -17,6 +17,16 @@
#include "leaf-math.h"
#include "leaf-filter.h"
+
+/*
+extern const float* sinewave;
+
+extern const float* sawtooth[11];
+
+extern const float* triangle[11];
+
+extern const float* squarewave[11];
+ */
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -86,7 +96,9 @@
// Underlying phasor
float phase;
float inc,freq;
-
+
+ int tsize;
+ float* table;
} tCycle;
void tCycle_init (tCycle* const);
@@ -93,7 +105,8 @@
void tCycle_free (tCycle* const);
float tCycle_tick (tCycle* const);
-int tCycle_setFreq (tCycle* const, float freq);
+int tCycle_setFreq (tCycle* const, float freq);
+void tCycle_setTableSize (tCycle* const c, int size);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -102,15 +115,20 @@
{
// Underlying phasor
float phase;
- float inc,freq;
+ float inc,freq;
+
+ int tsize;
+
+ float* table[NUM_TABLES];
} tSawtooth;
-void tSawtooth_init (tSawtooth* const);
-void tSawtooth_free (tSawtooth* const);
+void tSawtooth_init (tSawtooth* const);
+void tSawtooth_free (tSawtooth* const);
-float tSawtooth_tick (tSawtooth* const);
-int tSawtooth_setFreq (tSawtooth* const, float freq);
+float tSawtooth_tick (tSawtooth* const);
+int tSawtooth_setFreq (tSawtooth* const, float freq);
+void tSawtooth_setTableSize (tSawtooth* const c, int size);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -119,15 +137,20 @@
{
// Underlying phasor
float phase;
- float inc,freq;
+ float inc,freq;
+
+ int tsize;
+
+ float* table[NUM_TABLES];
} tTriangle;
-void tTriangle_init (tTriangle* const);
-void tTriangle_free (tTriangle* const);
+void tTriangle_init (tTriangle* const);
+void tTriangle_free (tTriangle* const);
-float tTriangle_tick (tTriangle* const);
-int tTriangle_setFreq (tTriangle* const, float freq);
+float tTriangle_tick (tTriangle* const);
+int tTriangle_setFreq (tTriangle* const, float freq);
+void tTriangle_setTableSize (tTriangle* const c, int size);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@@ -136,15 +159,20 @@
{
// Underlying phasor
float phase;
- float inc,freq;
+ float inc,freq;
+
+ int tsize;
+
+ float* table[NUM_TABLES];
} tSquare;
-void tSquare_init (tSquare* const);
-void tSquare_free (tSquare* const);
+void tSquare_init (tSquare* const);
+void tSquare_free (tSquare* const);
-float tSquare_tick (tSquare* const);
-int tSquare_setFreq (tSquare* const, float freq);
+float tSquare_tick (tSquare* const);
+int tSquare_setFreq (tSquare* const, float freq);
+void tSquare_setTableSize (tSquare* const c, int size);
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
--- a/LEAF/Inc_cpp/leaf-reverb.hpp
+++ b/LEAF/Inc_cpp/leaf-reverb.hpp
@@ -11,14 +11,16 @@
#ifndef LEAFREVERB_H_INCLUDED
#define LEAFREVERB_H_INCLUDED
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
#include "leaf-globals.h"
#include "leaf-math.h"
-#include "leaf-delay.h"
+#include "leaf-delay.h"
+#include "leaf-filter.h"
+#include "leaf-oscillator.h"
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
/* PRCRev: Reverb, reimplemented from STK (Cook and Scavone). */
typedef struct _tPRCRev
@@ -47,7 +49,7 @@
// Set mix between dry input and wet output signal.
void tPRCRev_setMix (tPRCRev* const, float mix);
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
/* NRev: Reverb, reimplemented from STK (Cook and Scavone). */
typedef struct _tNRev
@@ -77,6 +79,61 @@
// Set mix between dry input and wet output signal.
void tNRev_setMix (tNRev* const, float mix);
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+
+typedef struct _tDattorro
+{
+ float predelay;
+ float input_filter;
+ float feedback_filter;
+ float feedback_gain;
+ float mix;
+
+ float size, t;
+
+ float f1_delay_2_last,
+ f2_delay_2_last;
+
+ float f1_last,
+ f2_last;
+
+ // INPUT
+ tDelayL in_delay;
+ tOnePole in_filter;
+ tAllpass in_allpass[4];
+
+ // FEEDBACK 1
+ tAllpass f1_allpass;
+ tDelayL f1_delay_1;
+ tOnePole f1_filter;
+ tDelayL f1_delay_2;
+ tDelayL f1_delay_3;
+
+ tCycle f1_lfo;
+
+ // FEEDBACK 2
+ tAllpass f2_allpass;
+ tDelayL f2_delay_1;
+ tOnePole f2_filter;
+ tDelayL f2_delay_2;
+ tDelayL f2_delay_3;
+
+ tCycle f2_lfo;
+
+} tDattorro;
+
+void tDattorro_init (tDattorro* const);
+void tDattorro_free (tDattorro* const);
+
+float tDattorro_tick (tDattorro* const, float input);
+
+void tDattorro_setMix (tDattorro* const, float mix);
+void tDattorro_setSize (tDattorro* const, float size);
+void tDattorro_setInputDelay (tDattorro* const, float preDelay);
+void tDattorro_setInputFilter (tDattorro* const, float freq);
+void tDattorro_setFeedbackFilter (tDattorro* const, float freq);
+void tDattorro_setFeedbackGain (tDattorro* const, float gain);
+
#endif // LEAFREVERB_H_INCLUDED
--- a/LEAF/Inc_cpp/leaf-wavetables.hpp
+++ b/LEAF/Inc_cpp/leaf-wavetables.hpp
@@ -43,10 +43,10 @@
T5120,
T10240,
T20480,
- TableNameNil
+ NUM_TABLES
} TableName;
-// mtof lookup table based on input range [0.0,1.0) in 4096 increments - midi frequency values scaled between m25 and m134 (as done in previous code)
+// mtof lookup table based on input range [0.0,1.0) in 4096 increments - midi frequency values scaled between m25 and m134 (from the Snyderphonics DrumBox code)
extern const float exp_decay[EXP_DECAY_TABLE_SIZE];
extern const float attack_decay_inc[ATTACK_DECAY_INC_TABLE_SIZE];
@@ -57,17 +57,6 @@
extern const float decayCoeffTable[DECAY_COEFF_TABLE_SIZE];
extern const float tanh1[TANH1_TABLE_SIZE];
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* Sine wave table ripped from http://aquaticus.info/pwm-sine-wave. */
-extern const float sinewave[SINE_TABLE_SIZE];
-
-extern const float sawtooth[11][SAW_TABLE_SIZE];
-
-extern const float triangle[11][TRI_TABLE_SIZE];
-
-extern const float squarewave[11][SQR_TABLE_SIZE];
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
--- a/LEAF/Src/leaf-808.c
+++ b/LEAF/Src/leaf-808.c
@@ -121,7 +121,7 @@
float t808Hihat_tick(t808Hihat* const hihat) {
float sample = 0.0f;
- float gainScale = 0.3f;
+ float gainScale = 0.1666f;
float myNoise = tNoise_tick(&hihat->n);
@@ -140,6 +140,7 @@
sample *= gainScale;
+<<<<<<< HEAD
sample = (hihat->oscNoiseMix * sample) + ((1.0f-hihat->oscNoiseMix) * myNoise);
sample = tSVF_tick(&hihat->bandpassOsc, sample);
@@ -149,6 +150,18 @@
sample = tHighpass_tick(&hihat->highpass, sample);
sample += ((0.5f * tEnvelope_tick(&hihat->envStick)) * tSVF_tick(&hihat->bandpassStick, tNoise_tick(&hihat->stick)));
sample = tanhf(sample * 2.0f);
+=======
+ sample = (hihat->oscNoiseMix * sample) + ((1.0f-hihat->oscNoiseMix) * (0.8f * tNoise_tick(&hihat->n)));
+
+ sample = tSVF_tick(&hihat->bandpassOsc, sample);
+
+ sample *= tEnvelope_tick(&hihat->envGain);
+
+ sample = 0.85f * LEAF_clip(0.0f, tHighpass_tick(&hihat->highpass, sample), 1.0f);
+
+ sample += 0.15f * tEnvelope_tick(&hihat->envStick) * tSVF_tick(&hihat->bandpassStick, tNoise_tick(&hihat->stick));
+
+>>>>>>> dattorro
return sample;
}
@@ -178,6 +191,7 @@
tSVF_setFreq(&hihat->bandpassOsc,freq);
}
+<<<<<<< HEAD
void t808Hihat_setOscBandpassQ(t808Hihat* const hihat, float Q)
{
tSVF_setQ(&hihat->bandpassOsc,Q);
@@ -192,6 +206,18 @@
void t808Hihat_setOscFreq(t808Hihat* const hihat, float freq)
{
hihat->freq = freq;
+=======
+
+void t808Hihat_setOscFreq(t808Hihat* const hihat, float freq)
+{
+ tSquare_setFreq(&hihat->p[0], 2.0f * freq);
+ tSquare_setFreq(&hihat->p[1], 3.00f * freq);
+ tSquare_setFreq(&hihat->p[2], 4.16f * freq);
+ tSquare_setFreq(&hihat->p[3], 5.43f * freq);
+ tSquare_setFreq(&hihat->p[4], 6.79f * freq);
+ tSquare_setFreq(&hihat->p[5], 8.21f * freq);
+
+>>>>>>> dattorro
}
void t808Hihat_init(t808Hihat* const hihat)
@@ -205,12 +231,17 @@
tNoise_init(&hihat->n, WhiteNoise);
// need to fix SVF to be generic
- tSVF_init(&hihat->bandpassStick, SVFTypeBandpass,2500.0,1.2f);
- tSVF_init(&hihat->bandpassOsc, SVFTypeBandpass,3500,0.3f);
+ tSVF_init(&hihat->bandpassStick, SVFTypeBandpass,2500.0,1.5f);
+ tSVF_init(&hihat->bandpassOsc, SVFTypeBandpass,3500,0.5f);
+<<<<<<< HEAD
tEnvelope_init(&hihat->envGain, 0.0f, 50.0f, OFALSE);
tEnvelope_init(&hihat->noiseFMGain, 0.0f, 500.0f, OFALSE);
tEnvelope_init(&hihat->envStick, 0.0f, 4.0f, OFALSE);
+=======
+ tEnvelope_init(&hihat->envGain, 5.0f, 50.0f, OFALSE);
+ tEnvelope_init(&hihat->envStick, 5.0f, 15.0f, OFALSE);
+>>>>>>> dattorro
tHighpass_init(&hihat->highpass, 7000.0f);
--- a/LEAF/Src/leaf-delay.c
+++ b/LEAF/Src/leaf-delay.c
@@ -29,8 +29,6 @@
d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
- d->delay = 0.0f;
-
d->inPoint = 0;
d->outPoint = 0;
@@ -143,8 +141,6 @@
d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
- d->delay = 0.0f;
-
d->gain = 1.0f;
d->lastIn = 0.0f;
@@ -206,14 +202,28 @@
return 0;
}
-float tDelayL_tapOut (tDelayL* const d, uint32_t tapDelay)
+float tDelayL_tapOut (tDelayL* const d, float tapDelay)
{
- int32_t tap = d->inPoint - tapDelay - 1;
+ float tap = (float) d->inPoint - tapDelay - 1.f;
// Check for wraparound.
- while ( tap < 0 ) tap += d->maxDelay;
+ while ( tap < 0.f ) tap += (float)d->maxDelay;
+
+ float alpha = tap - (int)tap;
+ float omAlpha = 1.f - alpha;
+
+ int ptx = (int) tap;
+
+ // First 1/2 of interpolation
+ float samp = d->buff[ptx] * omAlpha;
+
+ // Second 1/2 of interpolation
+ if ((ptx + 1) < d->maxDelay)
+ samp += d->buff[ptx+1] * d->alpha;
+ else
+ samp += d->buff[0] * d->alpha;
- return d->buff[tap];
+ return samp;
}
@@ -273,8 +283,6 @@
else d->delay = delay;
d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
-
- d->delay = 0.0f;
d->gain = 1.0f;
--- a/LEAF/Src/leaf-filter.c
+++ b/LEAF/Src/leaf-filter.c
@@ -20,7 +20,44 @@
#include "../Inc/leaf-wavetables.h"
#include "../leaf.h"
-#endif
+#endif
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
+void tAllpass_init(tAllpass* const f, float initDelay, uint32_t maxDelay)
+{
+ f->gain = 0.7f;
+
+ f->lastOut = 0.0f;
+
+ tDelayL_init(&f->delay, initDelay, maxDelay);
+}
+
+void tAllpass_setDelay(tAllpass* const f, float delay)
+{
+ tDelayL_setDelay(&f->delay, delay);
+}
+
+void tAllpass_free(tAllpass* const f)
+{
+ leaf_free(&f->delay);
+ leaf_free(f);
+}
+
+void tAllpass_setGain(tAllpass* const f, float gain)
+{
+ f->gain = gain;
+}
+
+float tAllpass_tick(tAllpass* const f, float input)
+{
+ float s1 = (-f->gain) * f->lastOut + input;
+
+ float s2 = tDelayL_tick(&f->delay, s1) + (f->gain) * input;
+
+ f->lastOut = s2;
+
+ return f->lastOut;
+}
void tButterworth_init(tButterworth* const f, int N, float f1, float f2)
{
@@ -239,12 +276,12 @@
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tOnePole_init(tOnePole* const f, float thePole)
+void tOnePole_init(tOnePole* const f, float freq)
{
f->gain = 1.0f;
f->a0 = 1.0;
- tOnePole_setPole(f, thePole);
+ tOnePole_setFreq(f, freq);
f->lastIn = 0.0f;
f->lastOut = 0.0f;
@@ -276,6 +313,15 @@
else f->b0 = (1.0f + thePole);
f->a1 = -thePole;
+}
+
+void tOnePole_setFreq (tOnePole* const f, float freq)
+{
+ f->b0 = freq * TWO_PI * leaf.invSampleRate;
+
+ f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
+
+ f->a1 = 1.0f - f->b0;
}
void tOnePole_setCoefficients(tOnePole* const f, float b0, float a1)
@@ -294,7 +340,7 @@
float tOnePole_tick(tOnePole* const f, float input)
{
float in = input * f->gain;
- float out = (f->b0 * in) - (f->a1 * f->lastOut);
+ float out = (f->b0 * in) + (f->a1 * f->lastOut);
f->lastIn = in;
f->lastOut = out;
@@ -679,7 +725,7 @@
float a1,a2,a3,g,k;
g = tanf(PI * freq * leaf.invSampleRate);
- k = 1.0f/LEAF_clip(0.01f,Q,10.0f);
+ k = 1.0f/Q;
a1 = 1.0f/(1.0f+g*(g+k));
a2 = g*a1;
a3 = g*a2;
@@ -708,7 +754,7 @@
int tSVF_setQ(tSVF* const svf, float Q)
{
- svf->k = 1.0f/LEAF_clip(0.01f,Q,10.0f);
+ svf->k = 1.0f/Q;
svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
svf->a2 = svf->g * svf->a1;
svf->a3 = svf->g * svf->a2;
--- a/LEAF/Src/leaf-reverb.c
+++ b/LEAF/Src/leaf-reverb.c
@@ -248,12 +248,238 @@
r->lastOut = out;
return out;
-}
+}
-
-
void tNRevSampleRateChanged (tNRev* const r)
{
for (int i=0; i<6; i++) r->combCoeffs[i] = pow(10.0, (-3.0 * tDelay_getDelay(r->combDelays[i]) * leaf.invSampleRate / r->t60 ));
+}
+
+// ======================================DATTORRO=========================================
+
+#define SAMP(in) (in*r->t)
+
+float in_allpass_delays[4] = { 4.771f, 3.595f, 12.73f, 9.307f };
+float in_allpass_gains[4] = { 0.75f, 0.75f, 0.625f, 0.625f };
+
+void tDattorro_init (tDattorro* const r)
+{
+ tDattorro_setMix(r, 0.5f);
+
+ tDattorro_setInputDelay(r, 5.f);
+
+ tDattorro_setInputFilter(r, 1000.f);
+
+ tDattorro_setFeedbackFilter(r, 1000.f);
+
+ tDattorro_setFeedbackGain(r, 0.25f);
+
+ tDattorro_setSize(r, 1.0f);
+
+ // INPUT
+ tDelayL_init(&r->in_delay, 0.f, SAMP(200.f));
+ tOnePole_init(&r->in_filter, 1.f);
+
+ for (int i = 0; i < 4; i++)
+ {
+ tAllpass_init(&r->in_allpass[i], in_allpass_delays[i], SAMP(20.f));
+ tAllpass_setGain(&r->in_allpass[i], in_allpass_gains[i]);
+ }
+
+ // FEEDBACK 1
+ tAllpass_init(&r->f1_allpass, SAMP(30.51f), SAMP(100.f));
+ tAllpass_setGain(&r->f1_allpass, 0.7f);
+
+ tDelayL_init(&r->f1_delay_1, SAMP(141.69f), SAMP(200.0f));
+ tDelayL_init(&r->f1_delay_2, SAMP(89.24f), SAMP(100.0f));
+ tDelayL_init(&r->f1_delay_3, SAMP(125.f), SAMP(200.0f));
+
+ tOnePole_init(&r->f1_filter, 1.f);
+
+ tCycle_init(&r->f1_lfo);
+ tCycle_setFreq(&r->f1_lfo, 0.1f);
+
+ // FEEDBACK 2
+ tAllpass_init(&r->f2_allpass, SAMP(22.58f), SAMP(100.f));
+ tAllpass_setGain(&r->f2_allpass, 0.7f);
+
+ tDelayL_init(&r->f2_delay_1, SAMP(149.62f), SAMP(200.0f));
+ tDelayL_init(&r->f2_delay_2, SAMP(60.48f), SAMP(100.0f));
+ tDelayL_init(&r->f2_delay_3, SAMP(106.28f), SAMP(200.0f));
+
+ tOnePole_init(&r->f2_filter, 1.f);
+
+ tCycle_init(&r->f2_lfo);
+ tCycle_setFreq(&r->f2_lfo, 0.07f);
+}
+
+void tDattorro_free (tDattorro* const r)
+{
+ // INPUT
+ tDelayL_free(&r->in_delay);
+ tOnePole_free(&r->in_filter);
+
+ for (int i = 0; i < 4; i++)
+ {
+ tAllpass_free(&r->in_allpass[i]);
+ }
+
+ // FEEDBACK 1
+ tAllpass_free(&r->f1_allpass);
+
+ tDelayL_free(&r->f1_delay_1);
+ tDelayL_free(&r->f1_delay_2);
+ tDelayL_free(&r->f1_delay_3);
+
+ tOnePole_free(&r->f1_filter);
+
+ tCycle_free(&r->f1_lfo);
+
+ // FEEDBACK 2
+ tAllpass_free(&r->f2_allpass);
+
+ tDelayL_free(&r->f2_delay_1);
+ tDelayL_free(&r->f2_delay_2);
+ tDelayL_free(&r->f2_delay_3);
+
+ tOnePole_free(&r->f2_filter);
+
+ tCycle_free(&r->f2_lfo);
+
+ leaf_free(r);
+}
+
+float tDattorro_tick (tDattorro* const r, float input)
+{
+ // INPUT
+ float in_sample = tDelayL_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 = tDelayL_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 = tDelayL_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 *= r->feedback_gain;
+
+ r->f1_last = tDelayL_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 = tDelayL_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 = tDelayL_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 *= r->feedback_gain;
+
+ r->f2_last = tDelayL_tick(&r->f2_delay_3, f2_sample);
+
+
+ // TAP OUT 1
+ f1_sample = tDelayL_tapOut(&r->f1_delay_1, SAMP(8.9f)) +
+ tDelayL_tapOut(&r->f1_delay_1, SAMP(99.8f));
+
+ f1_sample -= tDelayL_tapOut(&r->f1_delay_2, SAMP(64.2f));
+
+ f1_sample += tDelayL_tapOut(&r->f1_delay_3, SAMP(67.f));
+
+ f1_sample -= tDelayL_tapOut(&r->f2_delay_1, SAMP(66.8f));
+
+ f1_sample -= tDelayL_tapOut(&r->f2_delay_2, SAMP(6.3f));
+
+ f1_sample -= tDelayL_tapOut(&r->f2_delay_3, SAMP(35.8f));
+
+ f1_sample *= 0.14f;
+
+ // TAP OUT 2
+ f2_sample = tDelayL_tapOut(&r->f2_delay_1, SAMP(11.8f)) +
+ tDelayL_tapOut(&r->f2_delay_1, SAMP(121.7f));
+
+ f2_sample -= tDelayL_tapOut(&r->f2_delay_2, SAMP(6.3f));
+
+ f2_sample += tDelayL_tapOut(&r->f2_delay_3, SAMP(89.7f));
+
+ f2_sample -= tDelayL_tapOut(&r->f1_delay_1, SAMP(70.8f));
+
+ f2_sample -= tDelayL_tapOut(&r->f1_delay_2, SAMP(11.2f));
+
+ f2_sample -= tDelayL_tapOut(&r->f1_delay_3, SAMP(4.1f));
+
+ f2_sample *= 0.14f;
+
+ float sample = (f1_sample + f2_sample) * 0.5f;
+
+ return (input * (1.0f - r->mix) + sample * r->mix);
+}
+
+void tDattorro_setMix (tDattorro* const r, float mix)
+{
+ r->mix = LEAF_clip(0.0f, mix, 1.0f);
+}
+
+void tDattorro_setSize (tDattorro* const r, float size)
+{
+ r->size = LEAF_clip(0.001f, size, 100.0f);
+ r->t = r->size * leaf.sampleRate * 0.001f;
+}
+
+void tDattorro_setInputDelay (tDattorro* const r, float preDelay)
+{
+ r->predelay = LEAF_clip(0.0f, preDelay, 200.0f);
+
+ tDelayL_setDelay(&r->in_delay, SAMP(r->predelay));
+}
+
+void tDattorro_setInputFilter (tDattorro* const r, float freq)
+{
+ r->input_filter = LEAF_clip(0.0f, freq, 20000.0f);
+
+ tOnePole_setFreq(&r->in_filter, r->input_filter);
+}
+
+void tDattorro_setFeedbackFilter (tDattorro* const r, float freq)
+{
+ r->feedback_filter = LEAF_clip(0.0f, freq, 20000.0f);
+
+ tOnePole_setFreq(&r->f1_filter, r->feedback_filter);
+ tOnePole_setFreq(&r->f2_filter, r->feedback_filter);
+}
+
+void tDattorro_setFeedbackGain (tDattorro* const r, float gain)
+{
+ r->feedback_gain = gain;
}
--- a/LEAF/Src/leaf-utilities.c
+++ b/LEAF/Src/leaf-utilities.c
@@ -330,8 +330,8 @@
{
int32_t decayIndex;
- if (decay <= 1.0f) {
- decayIndex = 1;
+ if (decay < 0.0f) {
+ decayIndex = 0.0f;
} else if (decay < 8192.0f) {
decayIndex = ((int32_t)(decay * 8.0f)) - 1;
} else {
--- a/LEAF/Src_cpp/leaf-delay.cpp
+++ b/LEAF/Src_cpp/leaf-delay.cpp
@@ -29,8 +29,6 @@
d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
- d->delay = 0.0f;
-
d->inPoint = 0;
d->outPoint = 0;
@@ -143,8 +141,6 @@
d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
- d->delay = 0.0f;
-
d->gain = 1.0f;
d->lastIn = 0.0f;
@@ -206,14 +202,28 @@
return 0;
}
-float tDelayL_tapOut (tDelayL* const d, uint32_t tapDelay)
+float tDelayL_tapOut (tDelayL* const d, float tapDelay)
{
- int32_t tap = d->inPoint - tapDelay - 1;
+ float tap = (float) d->inPoint - tapDelay - 1.f;
// Check for wraparound.
- while ( tap < 0 ) tap += d->maxDelay;
+ while ( tap < 0.f ) tap += (float)d->maxDelay;
+
+ float alpha = tap - (int)tap;
+ float omAlpha = 1.f - alpha;
+
+ int ptx = (int) tap;
+
+ // First 1/2 of interpolation
+ float samp = d->buff[ptx] * omAlpha;
+
+ // Second 1/2 of interpolation
+ if ((ptx + 1) < d->maxDelay)
+ samp += d->buff[ptx+1] * d->alpha;
+ else
+ samp += d->buff[0] * d->alpha;
- return d->buff[tap];
+ return samp;
}
@@ -273,8 +283,6 @@
else d->delay = delay;
d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
-
- d->delay = 0.0f;
d->gain = 1.0f;
--- a/LEAF/Src_cpp/leaf-filter.cpp
+++ b/LEAF/Src_cpp/leaf-filter.cpp
@@ -20,7 +20,44 @@
#include "../Inc/leaf-wavetables.h"
#include "../leaf.h"
-#endif
+#endif
+
+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
+void tAllpass_init(tAllpass* const f, float initDelay, uint32_t maxDelay)
+{
+ f->gain = 0.7f;
+
+ f->lastOut = 0.0f;
+
+ tDelayL_init(&f->delay, initDelay, maxDelay);
+}
+
+void tAllpass_setDelay(tAllpass* const f, float delay)
+{
+ tDelayL_setDelay(&f->delay, delay);
+}
+
+void tAllpass_free(tAllpass* const f)
+{
+ leaf_free(&f->delay);
+ leaf_free(f);
+}
+
+void tAllpass_setGain(tAllpass* const f, float gain)
+{
+ f->gain = gain;
+}
+
+float tAllpass_tick(tAllpass* const f, float input)
+{
+ float s1 = (-f->gain) * f->lastOut + input;
+
+ float s2 = tDelayL_tick(&f->delay, s1) + (f->gain) * input;
+
+ f->lastOut = s2;
+
+ return f->lastOut;
+}
void tButterworth_init(tButterworth* const f, int N, float f1, float f2)
{
@@ -239,12 +276,12 @@
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tOnePole_init(tOnePole* const f, float thePole)
+void tOnePole_init(tOnePole* const f, float freq)
{
f->gain = 1.0f;
f->a0 = 1.0;
- tOnePole_setPole(f, thePole);
+ tOnePole_setFreq(f, freq);
f->lastIn = 0.0f;
f->lastOut = 0.0f;
@@ -280,8 +317,11 @@
void tOnePole_setFreq (tOnePole* const f, float freq)
{
- f->a1 = expf(-2.0 * PI * freq);
- f->b0 = 1.0f - f->a1;
+ f->b0 = freq * TWO_PI * leaf.invSampleRate;
+
+ f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
+
+ f->a1 = 1.0f - f->b0;
}
void tOnePole_setCoefficients(tOnePole* const f, float b0, float a1)
@@ -300,7 +340,7 @@
float tOnePole_tick(tOnePole* const f, float input)
{
float in = input * f->gain;
- float out = (f->b0 * in) - (f->a1 * f->lastOut);
+ float out = (f->b0 * in) + (f->a1 * f->lastOut);
f->lastIn = in;
f->lastOut = out;
--- a/LEAF/Src_cpp/leaf-reverb.cpp
+++ b/LEAF/Src_cpp/leaf-reverb.cpp
@@ -248,12 +248,238 @@
r->lastOut = out;
return out;
-}
+}
-
-
void tNRevSampleRateChanged (tNRev* const r)
{
for (int i=0; i<6; i++) r->combCoeffs[i] = pow(10.0, (-3.0 * tDelay_getDelay(r->combDelays[i]) * leaf.invSampleRate / r->t60 ));
+}
+
+// ======================================DATTORRO=========================================
+
+#define SAMP(in) (in*r->t)
+
+float in_allpass_delays[4] = { 4.771f, 3.595f, 12.73f, 9.307f };
+float in_allpass_gains[4] = { 0.75f, 0.75f, 0.625f, 0.625f };
+
+void tDattorro_init (tDattorro* const r)
+{
+ tDattorro_setMix(r, 0.5f);
+
+ tDattorro_setInputDelay(r, 5.f);
+
+ tDattorro_setInputFilter(r, 1000.f);
+
+ tDattorro_setFeedbackFilter(r, 1000.f);
+
+ tDattorro_setFeedbackGain(r, 0.25f);
+
+ tDattorro_setSize(r, 1.0f);
+
+ // INPUT
+ tDelayL_init(&r->in_delay, 0.f, SAMP(200.f));
+ tOnePole_init(&r->in_filter, 1.f);
+
+ for (int i = 0; i < 4; i++)
+ {
+ tAllpass_init(&r->in_allpass[i], in_allpass_delays[i], SAMP(20.f));
+ tAllpass_setGain(&r->in_allpass[i], in_allpass_gains[i]);
+ }
+
+ // FEEDBACK 1
+ tAllpass_init(&r->f1_allpass, SAMP(30.51f), SAMP(100.f));
+ tAllpass_setGain(&r->f1_allpass, 0.7f);
+
+ tDelayL_init(&r->f1_delay_1, SAMP(141.69f), SAMP(200.0f));
+ tDelayL_init(&r->f1_delay_2, SAMP(89.24f), SAMP(100.0f));
+ tDelayL_init(&r->f1_delay_3, SAMP(125.f), SAMP(200.0f));
+
+ tOnePole_init(&r->f1_filter, 1.f);
+
+ tCycle_init(&r->f1_lfo);
+ tCycle_setFreq(&r->f1_lfo, 0.1f);
+
+ // FEEDBACK 2
+ tAllpass_init(&r->f2_allpass, SAMP(22.58f), SAMP(100.f));
+ tAllpass_setGain(&r->f2_allpass, 0.7f);
+
+ tDelayL_init(&r->f2_delay_1, SAMP(149.62f), SAMP(200.0f));
+ tDelayL_init(&r->f2_delay_2, SAMP(60.48f), SAMP(100.0f));
+ tDelayL_init(&r->f2_delay_3, SAMP(106.28f), SAMP(200.0f));
+
+ tOnePole_init(&r->f2_filter, 1.f);
+
+ tCycle_init(&r->f2_lfo);
+ tCycle_setFreq(&r->f2_lfo, 0.07f);
+}
+
+void tDattorro_free (tDattorro* const r)
+{
+ // INPUT
+ tDelayL_free(&r->in_delay);
+ tOnePole_free(&r->in_filter);
+
+ for (int i = 0; i < 4; i++)
+ {
+ tAllpass_free(&r->in_allpass[i]);
+ }
+
+ // FEEDBACK 1
+ tAllpass_free(&r->f1_allpass);
+
+ tDelayL_free(&r->f1_delay_1);
+ tDelayL_free(&r->f1_delay_2);
+ tDelayL_free(&r->f1_delay_3);
+
+ tOnePole_free(&r->f1_filter);
+
+ tCycle_free(&r->f1_lfo);
+
+ // FEEDBACK 2
+ tAllpass_free(&r->f2_allpass);
+
+ tDelayL_free(&r->f2_delay_1);
+ tDelayL_free(&r->f2_delay_2);
+ tDelayL_free(&r->f2_delay_3);
+
+ tOnePole_free(&r->f2_filter);
+
+ tCycle_free(&r->f2_lfo);
+
+ leaf_free(r);
+}
+
+float tDattorro_tick (tDattorro* const r, float input)
+{
+ // INPUT
+ float in_sample = tDelayL_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 = tDelayL_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 = tDelayL_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 *= r->feedback_gain;
+
+ r->f1_last = tDelayL_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 = tDelayL_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 = tDelayL_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 *= r->feedback_gain;
+
+ r->f2_last = tDelayL_tick(&r->f2_delay_3, f2_sample);
+
+
+ // TAP OUT 1
+ f1_sample = tDelayL_tapOut(&r->f1_delay_1, SAMP(8.9f)) +
+ tDelayL_tapOut(&r->f1_delay_1, SAMP(99.8f));
+
+ f1_sample -= tDelayL_tapOut(&r->f1_delay_2, SAMP(64.2f));
+
+ f1_sample += tDelayL_tapOut(&r->f1_delay_3, SAMP(67.f));
+
+ f1_sample -= tDelayL_tapOut(&r->f2_delay_1, SAMP(66.8f));
+
+ f1_sample -= tDelayL_tapOut(&r->f2_delay_2, SAMP(6.3f));
+
+ f1_sample -= tDelayL_tapOut(&r->f2_delay_3, SAMP(35.8f));
+
+ f1_sample *= 0.14f;
+
+ // TAP OUT 2
+ f2_sample = tDelayL_tapOut(&r->f2_delay_1, SAMP(11.8f)) +
+ tDelayL_tapOut(&r->f2_delay_1, SAMP(121.7f));
+
+ f2_sample -= tDelayL_tapOut(&r->f2_delay_2, SAMP(6.3f));
+
+ f2_sample += tDelayL_tapOut(&r->f2_delay_3, SAMP(89.7f));
+
+ f2_sample -= tDelayL_tapOut(&r->f1_delay_1, SAMP(70.8f));
+
+ f2_sample -= tDelayL_tapOut(&r->f1_delay_2, SAMP(11.2f));
+
+ f2_sample -= tDelayL_tapOut(&r->f1_delay_3, SAMP(4.1f));
+
+ f2_sample *= 0.14f;
+
+ float sample = (f1_sample + f2_sample) * 0.5f;
+
+ return (input * (1.0f - r->mix) + sample * r->mix);
+}
+
+void tDattorro_setMix (tDattorro* const r, float mix)
+{
+ r->mix = LEAF_clip(0.0f, mix, 1.0f);
+}
+
+void tDattorro_setSize (tDattorro* const r, float size)
+{
+ r->size = LEAF_clip(0.001f, size, 100.0f);
+ r->t = r->size * leaf.sampleRate * 0.001f;
+}
+
+void tDattorro_setInputDelay (tDattorro* const r, float preDelay)
+{
+ r->predelay = LEAF_clip(0.0f, preDelay, 200.0f);
+
+ tDelayL_setDelay(&r->in_delay, SAMP(r->predelay));
+}
+
+void tDattorro_setInputFilter (tDattorro* const r, float freq)
+{
+ r->input_filter = LEAF_clip(0.0f, freq, 20000.0f);
+
+ tOnePole_setFreq(&r->in_filter, r->input_filter);
+}
+
+void tDattorro_setFeedbackFilter (tDattorro* const r, float freq)
+{
+ r->feedback_filter = LEAF_clip(0.0f, freq, 20000.0f);
+
+ tOnePole_setFreq(&r->f1_filter, r->feedback_filter);
+ tOnePole_setFreq(&r->f2_filter, r->feedback_filter);
+}
+
+void tDattorro_setFeedbackGain (tDattorro* const r, float gain)
+{
+ r->feedback_gain = gain;
}
--- a/LEAF_JUCEPlugin/Source/LEAFLink.cpp
+++ b/LEAF_JUCEPlugin/Source/LEAFLink.cpp
@@ -24,7 +24,8 @@
"predelay",
"input filter",
"feedback filter",
- "feedback gain"
+ "feedback gain",
+ "size"
};
std::vector<juce::String> cComboBoxNames = std::vector<juce::String>
--- a/LEAF_JUCEPlugin/Source/MyTest.cpp
+++ b/LEAF_JUCEPlugin/Source/MyTest.cpp
@@ -16,38 +16,22 @@
static void leaf_pool_dump(void);
static void run_pool_test(void);
+tDattorro reverb;
-// INPUT
-tDelayL in_delay;
-tOnePole in_filter;
-tDelayA in_allpass[4];
-float in_allpass_delays[4] = { 4.771f, 3.595f, 12.73f, 9.307f };
-float in_allpass_gains[4] = { 0.75f, 0.75f, 0.625f, 0.625f };
-
-// FEEDBACK 1
-tDelayA f1_allpass;
-tDelayL f1_delay_1;
-tOnePole f1_filter;
-tDelayL f1_delay_2;
-tDelayL f1_delay_3;
-
-tCycle f1_lfo;
-
-// FEEDBACK 2
-tDelayA f2_allpass;
-tDelayL f2_delay_1;
-tOnePole f2_filter;
-tDelayL f2_delay_2;
-tDelayL f2_delay_3;
-
-tCycle f2_lfo;
-
-float t;
void LEAFTest_init (float sampleRate, int blockSize)
{
LEAF_init(sampleRate, blockSize, &randomNumberGenerator);
-
+
+ tDattorro_init(&reverb);
+
+ setSliderValue("mix", reverb.mix);
+ setSliderValue("predelay", reverb.predelay / 200.0f);
+ setSliderValue("input filter", reverb.input_filter / 20000.0f);
+ setSliderValue("feedback filter", reverb.feedback_filter / 20000.0f);
+ setSliderValue("feedback gain", reverb.feedback_gain);
+ //setSliderValue("size", reverb.size / 4.0f);
+
leaf_pool_report();
}
@@ -54,53 +38,44 @@
int timer = 0;
-float f1_delay_2_last;
-float f2_delay_2_last;
-
-float f1_last;
-float f2_last;
-
-
-float mix;
-float predelay = 0.f;
-float input_filter = 1.;
-float feedback_filter = 1.f;
-float feedback_gain = 0.0f;
-
+#define CLICK 0
-
float LEAFTest_tick (float input)
{
-
- return 0.0f;
-
+#if CLICK
+ input = 0.0f;
+
+ timer++;
+ if (timer == (1 * leaf.sampleRate))
+ {
+ timer = 0;
+
+ input = 1.0f;
+ }
+#endif
+
+ return tDattorro_tick(&reverb, input);
}
void LEAFTest_block (void)
{
float val = getSliderValue("mix");
+ tDattorro_setMix(&reverb, val);
- mix = val;
-
val = getSliderValue("predelay");
+ tDattorro_setInputDelay(&reverb, val * 200.0f);
- predelay = (val * 200.f) * leaf.sampleRate * 0.001f;
- tDelayL_setDelay(&in_delay, predelay);
-
val = getSliderValue("input filter");
+ tDattorro_setInputFilter(&reverb, val * 20000.0f);
- input_filter = val * 20000.f;
- tOnePole_setFreq(&in_filter, input_filter);
-
val = getSliderValue("feedback filter");
+ tDattorro_setFeedbackFilter(&reverb, val * 20000.0f);
- feedback_filter = val * 20000.f;
- tOnePole_setFreq(&f1_filter, feedback_filter);
- tOnePole_setFreq(&f2_filter, feedback_filter);
-
val = getSliderValue("feedback gain");
+ tDattorro_setFeedbackGain(&reverb, val);
- feedback_gain = val;
+ //val = getSliderValue("size");
+ //tDattorro_setSize(&reverb, val * 4.0f);
}
void LEAFTest_controllerInput (int cnum, float cval)