History

Rought implementation of DATTORRO reverb ported from Tom Erbe's max patches.

mulshine committed 7 years ago

Commit 32bb7b91 parent 9dffd7c6 files · +223 −27Browse files

Unified · Split

6 files
  1. LEAF/Inc/leaf-delay.h +5 −2
  2. LEAF/Inc/leaf-filter.h +4 −2
  3. LEAF/Src_cpp/leaf-filter.cpp +8 −2
  4. LEAF_JUCEPlugin/LEAF.jucer +0 −2
  5. LEAF_JUCEPlugin/Source/LEAFLink.cpp +5 −1
  6. LEAF_JUCEPlugin/Source/MyTest.cpp +201 −18
LEAF/Inc/leaf-delay.h+5−2
@@ -100,7 +100,7 @@ typedef struct _tDelayA · 99 unmodified lines
100100 } tDelayA;
101101
102102 void tDelayA_init (tDelayA* const, float delay, uint32_t maxDelay);
103−void tDelayA_free (tDelayA* const);
103+void tDelayA_free (tDelayA* const);
104104
105105 int tDelayA_setDelay (tDelayA* const, float delay);
106106 float tDelayA_getDelay (tDelayA* const);
@@ -109,7 +109,10 @@ float tDelayA_tapOut (tDelayA* const, uint32_t tapDelay); · 2 unmodified lines
109109 float tDelayA_addTo (tDelayA* const, float value, uint32_t tapDelay);
110110 float tDelayA_tick (tDelayA* const, float sample);
111111 float tDelayA_getLastOut (tDelayA* const);
112−float tDelayA_getLastIn (tDelayA* const);
112+float tDelayA_getLastIn (tDelayA* const);
113+void tDelayA_setGain (tDelayA* const, float gain);
114+float tDelayA_getGain (tDelayA* const);
115+
113116
114117 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
115118
LEAF/Inc/leaf-filter.h+4−2
@@ -25,7 +25,8 @@ typedef struct _tOnePole · 24 unmodified lines
2525 {
2626 float gain;
2727 float a0,a1;
28− float b0,b1;
28+ float b0,b1;
29+ float freq;
2930
3031 float lastIn, lastOut;
3132
@@ -37,7 +38,8 @@ void tOnePole_free (tOnePole* const); · 5 unmodified lines
3738 float tOnePole_tick (tOnePole* const, float input);
3839 void tOnePole_setB0 (tOnePole* const, float b0);
3940 void tOnePole_setA1 (tOnePole* const, float a1);
40−void tOnePole_setPole (tOnePole* const, float thePole);
41+void tOnePole_setPole (tOnePole* const, float thePole);
42+void tOnePole_setFreq (tOnePole* const, float freq);
4143 void tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
4244 void tOnePole_setGain (tOnePole* const, float gain);
4345
LEAF/Src_cpp/leaf-filter.cpp+8−2
@@ -276,6 +276,12 @@ void tOnePole_setPole(tOnePole* const f, float thePole) · 275 unmodified lines
276276 else f->b0 = (1.0f + thePole);
277277
278278 f->a1 = -thePole;
279+}
280+
281+void tOnePole_setFreq (tOnePole* const f, float freq)
282+{
283+ f->a1 = expf(-2.0 * PI * freq);
284+ f->b0 = 1.0f - f->a1;
279285 }
280286
281287 void tOnePole_setCoefficients(tOnePole* const f, float b0, float a1)
@@ -679,7 +685,7 @@ void tSVF_init(tSVF* const svf, SVFType type, float freq, float Q) · 397 unmodified lines
679685
680686 float a1,a2,a3,g,k;
681687 g = tanf(PI * freq * leaf.invSampleRate);
682− k = 1.0f/LEAF_clip(0.01f,Q,10.0f);
688+ k = 1.0f/Q;
683689 a1 = 1.0f/(1.0f+g*(g+k));
684690 a2 = g*a1;
685691 a3 = g*a2;
@@ -708,7 +714,7 @@ int tSVF_setFreq(tSVF* const svf, float freq) · 22 unmodified lines
708714
709715 int tSVF_setQ(tSVF* const svf, float Q)
710716 {
711− svf->k = 1.0f/LEAF_clip(0.01f,Q,10.0f);
717+ svf->k = 1.0f/Q;
712718 svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
713719 svf->a2 = svf->g * svf->a1;
714720 svf->a3 = svf->g * svf->a2;
LEAF_JUCEPlugin/LEAF.jucer+0−2
@@ -21,8 +21,6 @@ · 20 unmodified lines
2121 <FILE id="O0YJRY" name="d_fft_mayer.c" compile="1" resource="0" file="../LEAF/Externals/d_fft_mayer.c"/>
2222 <FILE id="L7c1sT" name="d_fft_mayer.cpp" compile="1" resource="0" file="../LEAF/Externals/d_fft_mayer.cpp"/>
2323 <FILE id="HdG3WV" name="d_fft_mayer.h" compile="0" resource="0" file="../LEAF/Externals/d_fft_mayer.h"/>
24− <FILE id="E7GkIZ" name="mpool.cpp" compile="1" resource="0" file="../LEAF/Externals/mpool.cpp"/>
25− <FILE id="udMePt" name="mpool.h" compile="0" resource="0" file="../LEAF/Externals/mpool.h"/>
2624 <FILE id="Hu4b98" name="trigtbl.h" compile="0" resource="0" file="../LEAF/Externals/trigtbl.h"/>
2725 </GROUP>
2826 <GROUP id="{0E2E673D-2AE5-AECB-4E28-A1EE29180BD2}" name="Inc">
LEAF_JUCEPlugin/Source/LEAFLink.cpp+5−1
@@ -20,7 +20,11 @@ std::vector<juce::String> cButtonNames = std::vector<juce::String> · 19 unmodified lines
2020
2121 std::vector<juce::String> cSliderNames = std::vector<juce::String>
2222 {
23− "mix"
23+ "mix",
24+ "predelay",
25+ "input filter",
26+ "feedback filter",
27+ "feedback gain"
2428 };
2529
2630 std::vector<juce::String> cComboBoxNames = std::vector<juce::String>
LEAF_JUCEPlugin/Source/MyTest.cpp+201−18
@@ -14,45 +14,228 @@ · 13 unmodified lines
1414
1515 static void leaf_pool_report(void);
1616 static void leaf_pool_dump(void);
17−static void run_pool_test(void);
17+static void run_pool_test(void);
18+
19+
20+// INPUT
21+tDelayL in_delay;
22+tOnePole in_filter;
23+tDelayA in_allpass[4];
24+float in_allpass_delays[4] = { 4.771f, 3.595f, 12.73f, 9.307f };
25+float in_allpass_gains[4] = { 0.75f, 0.75f, 0.625f, 0.625f };
26+
27+// FEEDBACK 1
28+tDelayA f1_allpass;
29+tDelayL f1_delay_1;
30+tOnePole f1_filter;
31+tDelayL f1_delay_2;
32+tDelayL f1_delay_3;
33+
34+tCycle f1_lfo;
35+
36+// FEEDBACK 2
37+tDelayA f2_allpass;
38+tDelayL f2_delay_1;
39+tOnePole f2_filter;
40+tDelayL f2_delay_2;
41+tDelayL f2_delay_3;
42+
43+tCycle f2_lfo;
44+
45+float t;
1846
19−tSquare osc;
2047
2148 void LEAFTest_init (float sampleRate, int blockSize)
2249 {
2350 LEAF_init(sampleRate, blockSize, &randomNumberGenerator);
2451
25− tSquare_init(&osc);
26− tSquare_setFreq(&osc, 110.0f);
52+ t = leaf.sampleRate * 0.001f;
2753
28− tSquare_setTableSize(&osc, 4000);
29−
54+ // ==================DATTORRO===================
55+ // INPUT
56+ tDelayL_init(&in_delay, 0.f, 200.f*t);
57+ tOnePole_init(&in_filter, 1.f);
58+
59+ for (int i = 0; i < 4; i++)
60+ {
61+ tDelayA_init(&in_allpass[i], in_allpass_delays[i], 20.f*t);
62+ tDelayA_setGain(&in_allpass[i], in_allpass_gains[i]);
63+ }
64+
65+ // FEEDBACK 1
66+ tDelayA_init(&f1_allpass, 30.51f*t, 100.f*t);
67+ tDelayA_setGain(&f1_allpass, 0.7f);
68+
69+ tDelayL_init(&f1_delay_1, 141.69f*t, 200.0f*t);
70+ tDelayL_init(&f1_delay_2, 89.24f*t, 100.0f*t);
71+ tDelayL_init(&f1_delay_3, 125.f*t, 200.0f*t);
72+
73+ tOnePole_init(&f1_filter, 1.f);
74+
75+ tCycle_init(&f1_lfo);
76+ tCycle_setFreq(&f1_lfo, 0.1f);
77+
78+ // FEEDBACK 2
79+ tDelayA_init(&f2_allpass, 22.58f*t, 100.f*t);
80+ tDelayA_setGain(&f2_allpass, 0.7f);
81+
82+ tDelayL_init(&f2_delay_1, 149.62f*t, 200.0f*t);
83+ tDelayL_init(&f2_delay_2, 60.48f*t, 100.0f*t);
84+ tDelayL_init(&f2_delay_3, 106.28f*t, 200.0f*t);
85+
86+ tOnePole_init(&f2_filter, 1.f);
87+
88+ tCycle_init(&f2_lfo);
89+ tCycle_setFreq(&f2_lfo, 0.07f);
90+
91+ // =============================================
92+
3093 leaf_pool_report();
3194 }
3295
3396 int timer = 0;
97+
98+
99+float f1_delay_2_last;
100+float f2_delay_2_last;
101+
102+float f1_last;
103+float f2_last;
104+
105+
106+float mix;
107+float predelay = 0.f;
108+float input_filter = 1.;
109+float feedback_filter = 1.f;
110+float feedback_gain = 0.0f;
111+
34112
35−float prev = 0.0;
36113
37114 float LEAFTest_tick (float input)
38−{
39− float sample = 0.0f;
40−
41− timer++;
42− if (timer == (1 * leaf.sampleRate))
43− {
44− timer = 0;
115+{
116+ // ==================DATTORRO===================
117+
118+ // INPUT
119+ float in_sample = tDelayL_tick(&in_delay, input);
120+
121+ in_sample = tOnePole_tick(&in_filter, in_sample);
122+
123+ for (int i = 0; i < 4; i++)
124+ {
125+ in_sample = tDelayA_tick(&in_allpass[i], in_sample);
45126 }
127+
128+ // FEEDBACK 1
129+ float f1_sample = in_sample + f2_last; // + f2_last_out;
130+
131+ tDelayA_setDelay(&f1_allpass, 30.51f*t + tCycle_tick(&f1_lfo) * 4.0f);
132+
133+ f1_sample = tDelayA_tick(&f1_allpass, f1_sample);
134+
135+ f1_sample = tDelayL_tick(&f1_delay_1, f1_sample);
136+
137+ f1_sample = tOnePole_tick(&f1_filter, f1_sample);
138+
139+ f1_sample = f1_sample + f1_delay_2_last * 0.5f;
140+
141+ float f1_delay_2_sample = tDelayL_tick(&f1_delay_2, f1_sample * 0.5f);
142+
143+ f1_delay_2_last = f1_delay_2_sample;
144+
145+ f1_sample = f1_delay_2_last + f1_sample;
146+
147+ f1_sample *= feedback_gain;
148+
149+ f1_last = tDelayL_tick(&f1_delay_3, f1_sample);
150+
151+ // FEEDBACK 2
152+ float f2_sample = in_sample + f1_last;
153+
154+ tDelayA_setDelay(&f2_allpass, 22.58f*t + tCycle_tick(&f2_lfo) * 4.0f);
155+
156+ f2_sample = tDelayA_tick(&f2_allpass, f2_sample);
157+
158+ f2_sample = tDelayL_tick(&f2_delay_1, f2_sample);
46159
47− sample = 0.5 * tSquare_tick(&osc);
160+ f2_sample = tOnePole_tick(&f2_filter, f2_sample);
161+
162+ f2_sample = f2_sample + f2_delay_2_last * 0.5f;
163+
164+ float f2_delay_2_sample = tDelayL_tick(&f2_delay_2, f2_sample * 0.5f);
165+
166+ f2_delay_2_last = f2_delay_2_sample;
167+
168+ f2_sample = f2_delay_2_last + f2_sample;
169+
170+ f2_sample *= feedback_gain;
171+
172+ f2_last = tDelayL_tick(&f2_delay_3, f2_sample);
173+
174+ // TAP OUT 1
175+ f1_sample = tDelayL_tapOut(&f1_delay_1, 8.9f*t) +
176+ tDelayL_tapOut(&f1_delay_1, 99.8f*t);
177+
178+ f1_sample -= tDelayL_tapOut(&f1_delay_2, 64.2f*t);
179+
180+ f1_sample += tDelayL_tapOut(&f1_delay_3, 67.f*t);
181+
182+ f1_sample -= tDelayL_tapOut(&f2_delay_1, 66.8f*t);
183+
184+ f1_sample -= tDelayL_tapOut(&f2_delay_2, 6.3f*t);
185+
186+ f1_sample -= tDelayL_tapOut(&f2_delay_3, 35.8f*t);
187+
188+ f1_sample *= 0.14;
189+
190+ // TAP OUT 2
191+ f2_sample = tDelayL_tapOut(&f2_delay_1, 11.8f*t) +
192+ tDelayL_tapOut(&f2_delay_1, 121.7f*t);
193+
194+ f2_sample -= tDelayL_tapOut(&f2_delay_2, 6.3f*t);
195+
196+ f2_sample += tDelayL_tapOut(&f2_delay_3, 89.7f*t);
197+
198+ f2_sample -= tDelayL_tapOut(&f1_delay_1, 70.8f*t);
199+
200+ f2_sample -= tDelayL_tapOut(&f1_delay_2, 11.2f*t);
201+
202+ f2_sample -= tDelayL_tapOut(&f1_delay_3, 4.1f*t);
203+
204+ f2_sample *= 0.14f;
205+
206+ float sample = (f1_sample + f2_sample) * 0.5f;
207+
208+ // =============================================
48209
49− return sample;
210+ return (input * (1.0f - mix) + sample * mix);
50211
51212 }
52213
53214 void LEAFTest_block (void)
54−{
55− float val = getSliderValue("mix");
215+{
216+ float val = getSliderValue("mix");
217+
218+ mix = val;
219+
220+ val = getSliderValue("predelay");
221+
222+ predelay = (val * 200.f) * leaf.sampleRate * 0.001f;
223+ tDelayL_setDelay(&in_delay, predelay);
224+
225+ val = getSliderValue("input filter");
226+
227+ input_filter = val * 20000.f;
228+ tOnePole_setFreq(&in_filter, input_filter);
229+
230+ val = getSliderValue("feedback filter");
231+
232+ feedback_filter = val * 20000.f;
233+ tOnePole_setFreq(&f1_filter, feedback_filter);
234+ tOnePole_setFreq(&f2_filter, feedback_filter);
235+
236+ val = getSliderValue("feedback gain");
237+
238+ feedback_gain = val;
56239 }
57240
58241 void LEAFTest_controllerInput (int cnum, float cval)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t