History

Merge fixed.

mulshine committed 7 years ago

Commit 0659ec32 parents cb6284e 8733f5c12 files · +826 −59Browse files

Unified · Split

12 files
  1. LEAF/Inc/leaf-delay.h +2 −0
  2. LEAF/Inc/leaf-globals.h +2 −3
  3. LEAF/Inc/leaf-mempool.h +2 −0
  4. LEAF/Inc/leaf-oversampler.h +55 −0
  5. LEAF/Inc/leaf-utilities.h +167 −24
  6. LEAF/Inc/leaf-vocoder.h +1 −1
  7. LEAF/Src/leaf-delay.c +24 −0
  8. LEAF/Src/leaf-oversampler.c +124 −0
  9. LEAF/Src/leaf-utilities.c +424 −9
  10. LEAF/Src/leaf-wavefolder.c +2 −2
  11. LEAF/leaf.h +22 −20
  12. LEAF_JUCEPlugin/Source/MyTest.cpp +1 −0
LEAF/Inc/leaf-delay.h+2−0
@@ -75,6 +75,8 @@ void tDelayL_tapIn (tDelayL* const, float in, uint32_t tapDelay); · 74 unmodified lines
7575 float tDelayL_tapOut (tDelayL* const, float tapDelay);
7676 float tDelayL_addTo (tDelayL* const, float value, uint32_t tapDelay);
7777 float tDelayL_tick (tDelayL* const, float sample);
78+void tDelayL_tickIn (tDelayL* const d, float input);
79+float tDelayL_tickOut (tDelayL* const d);
7880 float tDelayL_getLastOut (tDelayL* const);
7981 float tDelayL_getLastIn (tDelayL* const);
8082
LEAF/Inc/leaf-globals.h+2−3
@@ -49,15 +49,14 @@ extern const float shaper1[SHAPER1_TABLE_SIZE]; · 48 unmodified lines
4949 #define MPOLY_NUM_MAX_VOICES 8
5050 #define NUM_OSC 4
5151 #define INV_NUM_OSC (1.0f / NUM_OSC)
52−#define PS_FRAME_SIZE 1024 // SNAC_FRAME_SIZE in LEAFCore.h should match (or be smaller than?) this
52+#define PS_FRAME_SIZE 1024 // SNAC_FRAME_SIZE in leaf-pitch.h should match (or be smaller than?) this
5353 #define ENV_WINDOW_SIZE 1024
5454 #define ENV_HOP_SIZE 256
55−#define NUM_KNOBS 4
5655
5756 #define DELAY_LENGTH 16000 // The maximum delay length of all Delay/DelayL/DelayA components.
5857 // Feel free to change to suit memory constraints or desired delay max length / functionality.
5958
60−#define TALKBOX_BUFFER_LENGTH 1600 // Every talkbox instance introduces 5 buffers of this size
59+
6160
6261
6362 union unholy_t { /* a union between a float and an integer */
LEAF/Inc/leaf-mempool.h+2−0
@@ -50,7 +50,9 @@ extern "C" { · 49 unmodified lines
5050
5151 //==============================================================================
5252
53+
5354 #define MPOOL_POOL_SIZE 500000
55+
5456 #define MPOOL_ALIGN_SIZE (8)
5557
5658 //#define size_t unsigned long
LEAF/Inc/leaf-oversampler.h+55−0
@@ -0,0 +1,55 @@
1+//
2+// leaf-oversampler.h
3+// LEAF
4+//
5+// Created by Matthew Wang and Joshua Becker on 2/28/19.
6+// Copyright © 2019 Princeton University. All rights reserved.
7+//
8+//==============================================================================
9+
10+#ifndef LEAF_OVERSAMPLER_H_INCLUDED
11+#define LEAF_OVERSAMPLER_H_INCLUDED
12+
13+#ifdef __cplusplus
14+extern "C" {
15+#endif
16+
17+//==============================================================================
18+
19+#include "leaf-globals.h"
20+#include "leaf-math.h"
21+#include "leaf-filter.h"
22+
23+//==============================================================================
24+typedef struct _tOversamplerFilter
25+{
26+ float cutoff, Q;
27+ float ic1eq,ic2eq;
28+ float g,k,a1,a2,a3;
29+} tOversamplerFilter;
30+
31+typedef struct _tOversampler2x
32+{
33+ tOversamplerFilter filters[2];
34+} tOversampler2x;
35+
36+void tOversampler2x_init(tOversampler2x* const);
37+float tOversampler2x_tick(tOversampler2x* const, float input, float (*nonLinearTick)(float));
38+
39+typedef struct _tOversampler4x
40+{
41+ tOversamplerFilter filters[4];
42+} tOversampler4x;
43+
44+void tOversampler4x_init(tOversampler4x* const);
45+float tOversampler4x_tick(tOversampler4x* const, float input, float (*nonLinearTick)(float));
46+
47+//==============================================================================
48+
49+#ifdef __cplusplus
50+}
51+#endif
52+
53+#endif // LEAF_OVERSAMPLER_H_INCLUDED
54+
55+//==============================================================================
LEAF/Inc/leaf-utilities.h+167−24
@@ -1,24 +1,28 @@
1−/*==============================================================================
1+/*
2+ ==============================================================================
23
3− leaf-utilities.h
4+ LEAFUtilities.h
45 Created: 20 Jan 2017 12:02:17pm
56 Author: Michael R Mulshine
67
7−==============================================================================*/
8+ ==============================================================================
9+*/
810
9−#ifndef LEAF_UTILITIES_H_INCLUDED
10−#define LEAF_UTILITIES_H_INCLUDED
11−
12−#ifdef __cplusplus
13−extern "C" {
11+#ifndef LEAFUTILITIES_H_INCLUDED
12+#define LEAFUTILITIES_H_INCLUDED
13+
14+#ifdef __cplusplus
15+extern "C" {
1416 #endif
1517
16−//==============================================================================
18+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
1719
1820 #include "leaf-globals.h"
1921 #include "leaf-math.h"
22+#include "leaf-filter.h"
23+#include "leaf-delay.h"
2024
21−//==============================================================================
25+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
2226
2327 // STACK implementation (fixed size)
2428 #define STACK_SIZE 128
@@ -46,7 +50,7 @@ int tStack_contains (tStack* const, uint16_t item); · 21 unmodified lines
4650 int tStack_next (tStack* const);
4751 int tStack_get (tStack* const, int which);
4852
49−//==============================================================================
53+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
5054
5155 /* Ramp */
5256 typedef struct _tRamp {
@@ -68,7 +72,148 @@ int tRamp_setTime (tRamp* const, float time); · 15 unmodified lines
6872 int tRamp_setDest (tRamp* const, float dest);
6973 int tRamp_setVal (tRamp* const, float val);
7074
71−//==============================================================================
75+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
76+
77+/* Exponential Smoother */
78+typedef struct _tExpSmooth {
79+ float factor, oneminusfactor;
80+ float curr,dest;
81+
82+} tExpSmooth;
83+
84+void tExpSmooth_init (tExpSmooth* const, float val, float factor);
85+void tExpSmooth_free (tExpSmooth* const);
86+
87+float tExpSmooth_tick (tExpSmooth* const);
88+float tExpSmooth_sample (tExpSmooth* const);
89+int tExpSmooth_setFactor (tExpSmooth* const, float factor);
90+int tExpSmooth_setDest (tExpSmooth* const, float dest);
91+int tExpSmooth_setVal (tExpSmooth* const, float val);
92+
93+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
94+
95+/* PowerEnvelopeFollower */
96+typedef struct _tPwrFollow {
97+ float factor, oneminusfactor;
98+ float curr;
99+
100+} tPwrFollow;
101+
102+void tPwrFollow_init (tPwrFollow* const, float factor);
103+void tPwrFollow_free (tPwrFollow* const);
104+float tPwrFollow_tick (tPwrFollow* const, float input);
105+float tPwrFollow_sample (tPwrFollow* const);
106+int tPwrFollow_setFactor (tPwrFollow* const, float factor);
107+
108+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
109+
110+//Reed Table - borrowed from STK
111+typedef struct _tReedTable {
112+ float offset, slope;
113+} tReedTable;
114+
115+void tReedTable_init (tReedTable* const, float offset, float slope);
116+void tReedTable_free (tReedTable* const);
117+float tReedTable_tick (tReedTable* const, float input);
118+float tReedTable_tanh_tick (tReedTable* const p, float input); //tanh softclip version of reed table - replacing the hard clip in original stk code
119+void tReedTable_setOffset (tReedTable* const, float offset);
120+void tReedTable_setSlope (tReedTable* const, float slope);
121+
122+
123+
124+///
125+/* Feedback leveller */
126+// An auto VCA that you put into a feedback circuit to make it stay at the same level.
127+// It can enforce level bidirectionally (amplifying and attenuating as needed) or
128+// just attenutating. The former option allows for infinite sustain strings, for example, while
129+// The latter option allows for decaying strings, which can never exceed
130+// a specific level.
131+
132+typedef struct _tFBleveller {
133+ float targetLevel; // target power level
134+ float strength; // how strongly level difference affects the VCA
135+ int mode; // 0 for upwards limiting only, 1 for biderctional limiting
136+ float curr;
137+ tPwrFollow pwrFlw; // internal power follower needed for level tracking
138+
139+} tFBleveller;
140+
141+void tFBleveller_init (tFBleveller* const, float targetLevel, float factor, float strength, int mode);
142+void tFBleveller_free (tFBleveller* const);
143+
144+float tFBleveller_tick (tFBleveller* const, float input);
145+float tFBleveller_sample (tFBleveller* const);
146+int tFBleveller_setTargetLevel (tFBleveller* const, float TargetLevel);
147+int tFBleveller_setFactor (tFBleveller* const, float factor);
148+int tFBleveller_setMode (tFBleveller* const, int mode); // 0 for upwards limiting only, 1 for biderctional limiting
149+int tFBleveller_setStrength (tFBleveller* const, float strength);
150+
151+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
152+
153+/* Simple Living String */
154+typedef struct _tSimpleLivingString {
155+ float freq, waveLengthInSamples; // the frequency of the string, determining delay length
156+ float dampFreq; // frequency for the bridge LP filter, in Hz
157+ float decay; // amplitude damping factor for the string (only active in mode 0)
158+ float levMode;
159+ float curr;
160+ tDelayL delayLine;
161+ tOnePole bridgeFilter;
162+ tHighpass DCblocker;
163+ tFBleveller fbLev;
164+ tExpSmooth wlSmooth;
165+} tSimpleLivingString;
166+
167+void tSimpleLivingString_init (tSimpleLivingString* const, float freq, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode);
168+void tSimpleLivingString_free (tSimpleLivingString* const);
169+float tSimpleLivingString_tick (tSimpleLivingString* const, float input);
170+float tSimpleLivingString_sample (tSimpleLivingString* const);
171+int tSimpleLivingString_setFreq (tSimpleLivingString* const, float freq);
172+int tSimpleLivingString_setWaveLength (tSimpleLivingString* const, float waveLength); // in samples
173+int tSimpleLivingString_setDampFreq (tSimpleLivingString* const, float dampFreq);
174+int tSimpleLivingString_setDecay (tSimpleLivingString* const, float decay); // should be near 1.0
175+int tSimpleLivingString_setTargetLev (tSimpleLivingString* const, float targetLev);
176+int tSimpleLivingString_setLevSmoothFactor (tSimpleLivingString* const, float levSmoothFactor);
177+int tSimpleLivingString_setLevStrength (tSimpleLivingString* const, float levStrength);
178+int tSimpleLivingString_setLevMode (tSimpleLivingString* const, int levMode);
179+
180+
181+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
182+
183+/* Living String */
184+typedef struct _tLivingString {
185+ float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
186+ float pickPos; // the pick position, dividing the string in two, in ratio
187+ float prepIndex; // the amount of pressure on the pickpoint of the string (near 0=soft obj, near 1=hard obj)
188+ float dampFreq; // frequency for the bridge LP filter, in Hz
189+ float decay; // amplitude damping factor for the string (only active in mode 0)
190+ float levMode;
191+ float curr;
192+ tDelayL delLF,delUF,delUB,delLB; // delay for lower/upper/forward/backward part of the waveguide model
193+ tOnePole bridgeFilter, nutFilter, prepFilterU, prepFilterL;
194+ tHighpass DCblockerL, DCblockerU;
195+ tFBleveller fbLevU, fbLevL;
196+ tExpSmooth wlSmooth, ppSmooth;
197+} tLivingString;
198+
199+void tLivingString_init (tLivingString* const, float freq, float pickPos, float prepIndex, float dampFreq, float decay,
200+ float targetLev, float levSmoothFactor, float levStrength, int levMode);
201+void tLivingString_free (tLivingString* const);
202+float tLivingString_tick (tLivingString* const, float input);
203+float tLivingString_sample (tLivingString* const);
204+int tLivingString_setFreq (tLivingString* const, float freq);
205+int tLivingString_setWaveLength (tLivingString* const, float waveLength); // in samples
206+int tLivingString_setPickPos (tLivingString* const, float pickPos);
207+int tLivingString_setPrepIndex (tLivingString* const, float prepIndex);
208+int tLivingString_setDampFreq (tLivingString* const, float dampFreq);
209+int tLivingString_setDecay (tLivingString* const, float decay); // should be near 1.0
210+int tLivingString_setTargetLev (tLivingString* const, float targetLev);
211+int tLivingString_setLevSmoothFactor (tLivingString* const, float levSmoothFactor);
212+int tLivingString_setLevStrength (tLivingString* const, float levStrength);
213+int tLivingString_setLevMode (tLivingString* const, int levMode);
214+
215+
216+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
72217
73218 /* Compressor */
74219 typedef struct _tCompressor
@@ -86,7 +231,7 @@ void tCompressor_init (tCompressor* const); · 11 unmodified lines
86231 void tCompressor_free (tCompressor* const);
87232 float tCompressor_tick (tCompressor* const, float input);
88233
89−//==============================================================================
234+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
90235
91236 /* Attack-Decay envelope */
92237 typedef struct _tEnvelope {
@@ -118,7 +263,7 @@ int tEnvelope_setDecay (tEnvelope* const, float decay); · 25 unmodified lines
118263 int tEnvelope_loop (tEnvelope* const, oBool loop);
119264 int tEnvelope_on (tEnvelope* const, float velocity);
120265
121−//==============================================================================
266+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
122267
123268 /* ADSR */
124269 typedef struct _tADSR
@@ -150,7 +295,7 @@ int tADSR_setRelease(tADSR* const, float release); · 25 unmodified lines
150295 int tADSR_on (tADSR* const, float velocity);
151296 int tADSR_off (tADSR* const);
152297
153−//==============================================================================
298+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
154299
155300 /* Envelope Follower */
156301 typedef struct _tEnvelopeFollower
@@ -168,7 +313,7 @@ float tEnvelopeFollower_tick (tEnvelopeFollower* const, float x); · 11 unmodified lines
168313 int tEnvelopeFollower_decayCoeff (tEnvelopeFollower* const, float decayCoeff);
169314 int tEnvelopeFollower_attackThresh (tEnvelopeFollower* const, float attackThresh);
170315
171−//==============================================================================
316+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
172317
173318 /* tAtkDtk */
174319 #define DEFBLOCKSIZE 1024
@@ -219,7 +364,7 @@ void tAtkDtk_setThreshold (tAtkDtk* const, float thres); · 44 unmodified lines
219364 // find largest transient in input block, return index of attack
220365 int tAtkDtk_detect (tAtkDtk* const, float *in);
221366
222−//==============================================================================
367+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
223368
224369 // ENV~ from PD, modified for LEAF
225370 #define MAXOVERLAP 32
@@ -244,14 +389,12 @@ void tEnv_free (tEnv* const); · 18 unmodified lines
244389 float tEnv_tick (tEnv* const);
245390 void tEnv_processBlock (tEnv* const, float* in);
246391
247−//==============================================================================
248−
249−#ifdef __cplusplus
250−}
392+// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
393+
394+#ifdef __cplusplus
395+}
251396 #endif
252397
253−#endif // LEAF_UTILITIES_H_INCLUDED
254−
255−//==============================================================================
398+#endif // LEAFUTILITIES_H_INCLUDED
256399
257400
LEAF/Inc/leaf-vocoder.h+1−1
@@ -22,7 +22,7 @@ extern "C" { · 21 unmodified lines
2222
2323 /* tTalkbox */
2424 #define NUM_TALKBOX_PARAM 4
25−#define TALKBOX_BUFFER_LENGTH 1024 //1600
25+#define TALKBOX_BUFFER_LENGTH 1024 // Every talkbox instance introduces 5 buffers of this size - was originally 1600
2626
2727 typedef struct _tTalkbox
2828 {
LEAF/Src/leaf-delay.c+24−0
@@ -178,6 +178,30 @@ float tDelayL_tick (tDelayL* const d, float input) · 177 unmodified lines
178178 return d->lastOut;
179179 }
180180
181+void tDelayL_tickIn (tDelayL* const d, float input)
182+{
183+ d->buff[d->inPoint] = input * d->gain;
184+
185+ // Increment input pointer modulo length.
186+ if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
187+}
188+
189+float tDelayL_tickOut (tDelayL* const d)
190+{
191+ uint32_t idx = (uint32_t) d->outPoint;
192+
193+ d->lastOut = LEAF_interpolate_hermite (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
194+ d->buff[idx],
195+ d->buff[(idx + 1) % d->maxDelay],
196+ d->buff[(idx + 2) % d->maxDelay],
197+ d->alpha);
198+
199+ // Increment output pointer modulo length
200+ if ( (++d->outPoint) >= d->maxDelay ) d->outPoint = 0;
201+
202+ return d->lastOut;
203+}
204+
181205 int tDelayL_setDelay (tDelayL* const d, float delay)
182206 {
183207 d->delay = LEAF_clip(0.0f, delay, d->maxDelay);
LEAF/Src/leaf-oversampler.c+124−0
@@ -0,0 +1,124 @@
1+//
2+// leaf-oversampler.c
3+// LEAF
4+//
5+// Created by Matthew Wang and Joshua Becker on 2/28/19.
6+// Copyright © 2019 Princeton University. All rights reserved.
7+//
8+
9+#if _WIN32 || _WIN64
10+
11+#include "..\Inc\leaf-oversampler.h"
12+#else
13+
14+#include "../Inc/leaf-oversampler.h"
15+
16+#endif
17+
18+// Currently just using a double sample rate version of SVF from leaf-filter.c, may want to implement better filter for oversampling.
19+// Quick testing seems to indicate that this filter sufficiently handles most aliasing.
20+void tOversamplerFilter_init(tOversamplerFilter* const lpf, float freq, float Q, float sampleRateMultiplier)
21+{
22+ lpf->ic1eq = 0;
23+ lpf->ic2eq = 0;
24+
25+ float a1,a2,a3,g,k;
26+ float scaledInverseSampleRate = leaf.invSampleRate * (1 / sampleRateMultiplier);
27+
28+ g = tanf(PI * freq * scaledInverseSampleRate);
29+ k = 1.0f/Q;
30+ a1 = 1.0f/(1.0f+g*(g+k));
31+ a2 = g*a1;
32+ a3 = g*a2;
33+
34+ lpf->g = g;
35+ lpf->k = k;
36+ lpf->a1 = a1;
37+ lpf->a2 = a2;
38+ lpf->a3 = a3;
39+}
40+
41+float tOversamplerFilter_tick(tOversamplerFilter* const lpf, float v0)
42+{
43+ float v1,v2,v3;
44+ v3 = v0 - lpf->ic2eq;
45+ v1 = (lpf->a1 * lpf->ic1eq) + (lpf->a2 * v3);
46+ v2 = lpf->ic2eq + (lpf->a2 * lpf->ic1eq) + (lpf->a3 * v3);
47+ lpf->ic1eq = (2.0f * v1) - lpf->ic1eq;
48+ lpf->ic2eq = (2.0f * v2) - lpf->ic2eq;
49+
50+ return v2;
51+}
52+
53+// 2X Oversampler
54+void tOversampler2x_init(tOversampler2x* const os)
55+{
56+ tOversamplerFilter_init(&os->filters[0], leaf.sampleRate*0.5f, 0.1f, 2.f);
57+ tOversamplerFilter_init(&os->filters[1], leaf.sampleRate*0.5f, 0.1f, 2.f);
58+}
59+
60+float tOversampler2x_tick(tOversampler2x* const os, float input, float (*nonLinearTick)(float))
61+{
62+ float sample = input;
63+ float oversample = 0.f;
64+
65+ sample = tOversamplerFilter_tick(&os->filters[0], sample);
66+ oversample = tOversamplerFilter_tick(&os->filters[0], oversample);
67+
68+ sample = nonLinearTick(sample);
69+ oversample = nonLinearTick(oversample);
70+
71+ sample = tOversamplerFilter_tick(&os->filters[1], sample);
72+ oversample = tOversamplerFilter_tick(&os->filters[1], oversample);
73+
74+ return sample;
75+}
76+
77+// 4X Oversampler
78+void tOversampler4x_init(tOversampler4x* const os)
79+{
80+ tOversamplerFilter_init(&os->filters[0], leaf.sampleRate*0.25f, 0.1f, 2.f); //sample rate was *0.5 but I assume that was copypaste mistake (copied from 2X filter) - JS
81+ tOversamplerFilter_init(&os->filters[1], leaf.sampleRate*0.25f, 0.1f, 4.f);
82+ tOversamplerFilter_init(&os->filters[2], leaf.sampleRate*0.25f, 0.1f, 4.f);
83+ tOversamplerFilter_init(&os->filters[3] , leaf.sampleRate*0.25f, 0.1f, 2.f);
84+}
85+
86+float tOversampler4x_tick(tOversampler4x* const os, float input, float (*nonLinearTick)(float))
87+{
88+ float sample = input;
89+ float oversample1 = 0.f;
90+ float oversample2 = 0.f;
91+ float oversample3 = 0.f;
92+ // Phase 1:
93+ // x = [sample, oversample2]
94+ // lpf(x)
95+ // Phase 2:
96+ // x = [sample, oversample1, oversample2, oversample3]
97+ // lpf(dist(lpf(x)))
98+ // Phase 3:
99+ // x = [sample, oversample2]
100+ // lpf(x)
101+
102+ sample = tOversamplerFilter_tick(&os->filters[0], sample);
103+ oversample2 = tOversamplerFilter_tick(&os->filters[0], oversample2);
104+
105+ sample = tOversamplerFilter_tick(&os->filters[1], sample);
106+ oversample1 = tOversamplerFilter_tick(&os->filters[1], oversample1);
107+ oversample2 = tOversamplerFilter_tick(&os->filters[1], oversample2);
108+ oversample3 = tOversamplerFilter_tick(&os->filters[1], oversample3);
109+
110+ sample = nonLinearTick(sample);
111+ oversample1 = nonLinearTick(oversample1);
112+ oversample2 = nonLinearTick(oversample2);
113+ oversample3 = nonLinearTick(oversample3);
114+
115+ sample = tOversamplerFilter_tick(&os->filters[2], sample);
116+ oversample1 = tOversamplerFilter_tick(&os->filters[2], oversample1);
117+ oversample2 = tOversamplerFilter_tick(&os->filters[2], oversample2);
118+ oversample3 = tOversamplerFilter_tick(&os->filters[2], oversample3);
119+
120+ sample = tOversamplerFilter_tick(&os->filters[3], sample);
121+ oversample2 = tOversamplerFilter_tick(&os->filters[3], oversample2);
122+
123+ return sample;
124+}
LEAF/Src/leaf-utilities.c+424−9
@@ -1,10 +1,12 @@
1−/*==============================================================================
1+/*
2+ ==============================================================================
23
3− leaf-utilities.c
4+ LEAFUtilities.c
45 Created: 20 Jan 2017 12:02:17pm
56 Author: Michael R Mulshine
67
7−==============================================================================*/
8+ ==============================================================================
9+*/
810
911
1012 #if _WIN32 || _WIN64
@@ -29,12 +31,12 @@ float mtof(float f) · 18 unmodified lines
2931 {
3032 if (f <= -1500.0f) return(0);
3133 else if (f > 1499.0f) return(mtof(1499.0f));
32− else return (8.17579891564f * exp(0.0577622650f * f));
34+ else return (8.17579891564f * expf(0.0577622650f * f));
3335 }
3436
3537 float ftom(float f)
3638 {
37− return (f > 0 ? 17.3123405046f * log(.12231220585f * f) : -1500.0f);
39+ return (f > 0 ? 17.3123405046f * logf(.12231220585f * f) : -1500.0f);
3840 }
3941
4042 float powtodb(float f)
@@ -42,7 +44,7 @@ float powtodb(float f) · 1 unmodified line
4244 if (f <= 0) return (0);
4345 else
4446 {
45− float val = 100 + 10.f/LOGTEN * log(f);
47+ float val = 100 + 10.f/LOGTEN * logf(f);
4648 return (val < 0 ? 0 : val);
4749 }
4850 }
@@ -65,7 +67,7 @@ float dbtopow(float f) · 16 unmodified lines
6567 {
6668 if (f > 870.0f)
6769 f = 870.0f;
68− return (exp((LOGTEN * 0.1f) * (f-100.0f)));
70+ return (expf((LOGTEN * 0.1f) * (f-100.0f)));
6971 }
7072 }
7173
@@ -78,7 +80,7 @@ float dbtorms(float f) · 6 unmodified lines
7880 if (f > 485.0f)
7981 f = 485.0f;
8082 }
81− return (exp((LOGTEN * 0.05f) * (f-100.0f)));
83+ return (expf((LOGTEN * 0.05f) * (f-100.0f)));
8284 }
8385
8486 /* ---------------- env~ - simple envelope follower. ----------------- */
@@ -103,7 +105,7 @@ void tEnv_init(tEnv* const x, int ws, int hs, int bs) · 18 unmodified lines
103105
104106 for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
105107 for (i = 0; i < npoints; i++)
106− x->buf[i] = (1.0f - cos((2 * PI * i) / npoints))/npoints;
108+ x->buf[i] = (1.0f - cosf((2 * PI * i) / npoints))/npoints;
107109 for (; i < npoints+INITVSTAKEN; i++) x->buf[i] = 0;
108110
109111 x->x_f = 0;
@@ -761,6 +763,8 @@ float tRamp_tick(tRamp* const r) { · 651 unmodified lines
761763 r->curr += r->inc;
762764
763765 if (((r->curr >= r->dest) && (r->inc > 0.0f)) || ((r->curr <= r->dest) && (r->inc < 0.0f))) r->inc = 0.0f;
766+ // 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
767+ // I suggest you add: r->curr=r->dest in the true if case
764768
765769 return r->curr;
766770 }
@@ -775,6 +779,417 @@ void tRampSampleRateChanged(tRamp* const r) · 8 unmodified lines
775779 r->inv_sr_ms = 1.0f / (leaf.sampleRate * 0.001f);
776780 r->inc = ((r->dest-r->curr)/r->time * r->inv_sr_ms)*((float)r->samples_per_tick);
777781 }
782+
783+
784+/* Exponential Smoother */
785+void tExpSmooth_init(tExpSmooth* const smooth, float val, float factor)
786+{ // factor is usually a value between 0 and 0.1. Lower value is slower. 0.01 for example gives you a smoothing time of about 10ms
787+ smooth->curr=val;
788+ smooth->dest=val;
789+ if (factor<0) factor=0;
790+ if (factor>1) factor=1;
791+ smooth->factor=factor;
792+ smooth->oneminusfactor=1.0f-factor;
793+}
794+
795+int tExpSmooth_setFactor(tExpSmooth* const smooth, float factor)
796+{ // factor is usually a value between 0 and 0.1. Lower value is slower. 0.01 for example gives you a smoothing time of about 10ms
797+ if (factor<0)
798+ factor=0;
799+ else
800+ if (factor>1) factor=1;
801+ smooth->factor=factor;
802+ smooth->oneminusfactor=1.0f-factor;
803+ return 0;
804+}
805+
806+int tExpSmooth_setDest(tExpSmooth* const smooth, float dest)
807+{
808+ smooth->dest=dest;
809+ return 0;
810+}
811+
812+int tExpSmooth_setVal(tExpSmooth* const smooth, float val)
813+{
814+ smooth->curr=val;
815+ return 0;
816+}
817+
818+float tExpSmooth_tick(tExpSmooth* const smooth)
819+{
820+ smooth->curr = smooth->factor*smooth->dest+smooth->oneminusfactor*smooth->curr;
821+ return smooth->curr;
822+}
823+
824+float tExpSmooth_sample(tExpSmooth* const smooth)
825+{
826+ return smooth->curr;
827+}
828+
829+
830+/* Power Follower */
831+
832+void tPwrFollow_init(tPwrFollow* const p, float factor)
833+{
834+ p->curr=0.0f;
835+ p->factor=factor;
836+ p->oneminusfactor=1.0f-factor;
837+}
838+
839+int tPwrFollow_setFactor(tPwrFollow* const p, float factor)
840+{
841+ if (factor<0) factor=0;
842+ if (factor>1) factor=1;
843+ p->factor=factor;
844+ p->oneminusfactor=1.0f-factor;
845+ return 0;
846+}
847+
848+float tPwrFollow_tick(tPwrFollow* const p, float input)
849+{
850+ p->curr = p->factor*input*input+p->oneminusfactor*p->curr;
851+ return p->curr;
852+}
853+
854+float tPwrFollow_sample(tPwrFollow* const p)
855+{
856+ return p->curr;
857+}
858+
859+/* Feedback Leveler */
860+
861+void tFBleveller_init(tFBleveller* const p, float targetLevel, float factor, float strength, int mode)
862+{
863+ p->curr=0.0f;
864+ p->targetLevel=targetLevel;
865+ tPwrFollow_init(&p->pwrFlw,factor);
866+ p->mode=mode;
867+ p->strength=strength;
868+}
869+
870+int tFBleveller_setStrength(tFBleveller* const p, float strength)
871+{ // strength is how strongly level diff is affecting the amp ratio
872+ // try 0.125 for a start
873+ p->strength=strength;
874+ return 0;
875+}
876+
877+int tFBleveller_setFactor(tFBleveller* const p, float factor)
878+{
879+ tPwrFollow_setFactor(&p->pwrFlw,factor);
880+ return 0;
881+}
882+
883+int tFBleveller_setMode(tFBleveller* const p, int mode)
884+{ // 0 for decaying with upwards lev limiting, 1 for constrained absolute level (also downwards limiting)
885+ p->mode=mode;
886+ return 0;
887+}
888+
889+float tFBleveller_tick(tFBleveller* const p, float input)
890+{
891+ float levdiff=(tPwrFollow_tick(&p->pwrFlw, input)-p->targetLevel);
892+ if (p->mode==0 && levdiff<0) levdiff=0;
893+ p->curr=input*(1-p->strength*levdiff);
894+ return p->curr;
895+}
896+
897+float tFBleveller_sample(tFBleveller* const p)
898+{
899+ return p->curr;
900+}
901+
902+
903+int tFBleveller_setTargetLevel (tFBleveller* const p, float TargetLevel)
904+{
905+ p->targetLevel=TargetLevel;
906+}
907+
908+///Reed Table model
909+//default values from STK are 0.6 offset and -0.8 slope
910+
911+void tReedTable_init (tReedTable* const p, float offset, float slope)
912+{
913+ p->offset = offset;
914+ p->slope = slope;
915+}
916+
917+void tReedTable_free (tReedTable* const p)
918+{
919+ ;
920+}
921+
922+float tReedTable_tick (tReedTable* const p, float input)
923+{
924+ // The input is differential pressure across the reed.
925+ float output = p->offset + (p->slope * input);
926+
927+ // If output is > 1, the reed has slammed shut and the
928+ // reflection function value saturates at 1.0.
929+ if ( output > 1.0f) output = 1.0f;
930+
931+ // This is nearly impossible in a physical system, but
932+ // a reflection function value of -1.0 corresponds to
933+ // an open end (and no discontinuity in bore profile).
934+ if ( output < -1.0f) output = -1.0f;
935+
936+ return output;
937+}
938+
939+float tReedTable_tanh_tick (tReedTable* const p, float input)
940+{
941+ // The input is differential pressure across the reed.
942+ float output = p->offset + (p->slope * input);
943+
944+ // If output is > 1, the reed has slammed shut and the
945+ // reflection function value saturates at 1.0.
946+ return tanhf(output);
947+}
948+
949+void tReedTable_setOffset (tReedTable* const p, float offset)
950+{
951+ p->offset = offset;
952+}
953+
954+void tReedTable_setSlope (tReedTable* const p, float slope)
955+{
956+ p->slope = slope;
957+}
958+
959+
960+
961+/* Simple Living String*/
962+
963+void tSimpleLivingString_init(tSimpleLivingString* const p, float freq, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode)
964+{
965+ p->curr=0.0f;
966+ tExpSmooth_init(&p->wlSmooth, leaf.sampleRate/freq, 0.01); // smoother for string wavelength (not freq, to avoid expensive divisions)
967+ tSimpleLivingString_setFreq(p, freq);
968+ tDelayL_init(&p->delayLine,p->waveLengthInSamples, 2400);
969+ tOnePole_init(&p->bridgeFilter, dampFreq);
970+ tHighpass_init(&p->DCblocker,13);
971+ p->decay=decay;
972+ tFBleveller_init(&p->fbLev, targetLev, levSmoothFactor, levStrength, levMode);
973+ p->levMode=levMode;
974+}
975+
976+int tSimpleLivingString_setFreq(tSimpleLivingString* const p, float freq)
977+{
978+ if (freq<20) freq=20;
979+ else if (freq>10000) freq=10000;
980+ p->waveLengthInSamples = leaf.sampleRate/freq;
981+ tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
982+ return 0;
983+}
984+
985+int tSimpleLivingString_setWaveLength(tSimpleLivingString* const p, float waveLength)
986+{
987+ if (waveLength<4.8) waveLength=4.8;
988+ else if (waveLength>2400) waveLength=2400;
989+ p->waveLengthInSamples = waveLength;
990+ tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
991+ return 0;
992+}
993+
994+int tSimpleLivingString_setDampFreq(tSimpleLivingString* const p, float dampFreq)
995+{
996+ tOnePole_setFreq(&p->bridgeFilter, dampFreq);
997+ return 0;
998+}
999+
1000+int tSimpleLivingString_setDecay(tSimpleLivingString* const p, float decay)
1001+{
1002+ p->decay=decay;
1003+ return 0;
1004+}
1005+
1006+int tSimpleLivingString_setTargetLev(tSimpleLivingString* const p, float targetLev)
1007+{
1008+ tFBleveller_setTargetLevel(&p->fbLev, targetLev);
1009+ return 0;
1010+}
1011+
1012+int tSimpleLivingString_setLevSmoothFactor(tSimpleLivingString* const p, float levSmoothFactor)
1013+{
1014+ tFBleveller_setFactor(&p->fbLev, levSmoothFactor);
1015+ return 0;
1016+}
1017+
1018+int tSimpleLivingString_setLevStrength(tSimpleLivingString* const p, float levStrength)
1019+{
1020+ tFBleveller_setStrength(&p->fbLev, levStrength);
1021+ return 0;
1022+}
1023+
1024+int tSimpleLivingString_setLevMode(tSimpleLivingString* const p, int levMode)
1025+{
1026+ tFBleveller_setMode(&p->fbLev, levMode);
1027+ p->levMode=levMode;
1028+ return 0;
1029+}
1030+
1031+float tSimpleLivingString_tick(tSimpleLivingString* const p, float input)
1032+{
1033+ float stringOut=tOnePole_tick(&p->bridgeFilter,tDelayL_tickOut(&p->delayLine));
1034+ float stringInput=tHighpass_tick(&p->DCblocker, tFBleveller_tick(&p->fbLev, (p->levMode==0?p->decay*stringOut:stringOut)+input));
1035+ tDelayL_tickIn(&p->delayLine, stringInput);
1036+ tDelayL_setDelay(&p->delayLine, tExpSmooth_tick(&p->wlSmooth));
1037+ p->curr = stringOut;
1038+ return p->curr;
1039+}
1040+
1041+float tSimpleLivingString_sample(tSimpleLivingString* const p)
1042+{
1043+ return p->curr;
1044+}
1045+
1046+/* Living String*/
1047+
1048+void tLivingString_init(tLivingString* const p, float freq, float pickPos, float prepIndex, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode)
1049+{
1050+ p->curr=0.0f;
1051+ tExpSmooth_init(&p->wlSmooth, leaf.sampleRate/freq, 0.01); // smoother for string wavelength (not freq, to avoid expensive divisions)
1052+ tLivingString_setFreq(p, freq);
1053+ tExpSmooth_init(&p->ppSmooth, pickPos, 0.01); // smoother for pick position
1054+ tLivingString_setPickPos(p, pickPos);
1055+ p->prepIndex=prepIndex;
1056+ tDelayL_init(&p->delLF,p->waveLengthInSamples, 2400);
1057+ tDelayL_init(&p->delUF,p->waveLengthInSamples, 2400);
1058+ tDelayL_init(&p->delUB,p->waveLengthInSamples, 2400);
1059+ tDelayL_init(&p->delLB,p->waveLengthInSamples, 2400);
1060+ tOnePole_init(&p->bridgeFilter, dampFreq);
1061+ tOnePole_init(&p->nutFilter, dampFreq);
1062+ tOnePole_init(&p->prepFilterU, dampFreq);
1063+ tOnePole_init(&p->prepFilterL, dampFreq);
1064+ tHighpass_init(&p->DCblockerU,13);
1065+ tHighpass_init(&p->DCblockerL,13);
1066+ p->decay=decay;
1067+ tFBleveller_init(&p->fbLevU, targetLev, levSmoothFactor, levStrength, levMode);
1068+ tFBleveller_init(&p->fbLevL, targetLev, levSmoothFactor, levStrength, levMode);
1069+ p->levMode=levMode;
1070+}
1071+
1072+int tLivingString_setFreq(tLivingString* const p, float freq)
1073+{ // NOTE: It is faster to set wavelength in samples directly
1074+ if (freq<20) freq=20;
1075+ else if (freq>10000) freq=10000;
1076+ p->waveLengthInSamples = leaf.sampleRate/freq;
1077+ tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
1078+ return 0;
1079+}
1080+
1081+int tLivingString_setWaveLength(tLivingString* const p, float waveLength)
1082+{
1083+ if (waveLength<4.8) waveLength=4.8;
1084+ else if (waveLength>2400) waveLength=2400;
1085+ p->waveLengthInSamples = waveLength;
1086+ tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
1087+ return 0;
1088+}
1089+
1090+int tLivingString_setPickPos(tLivingString* const p, float pickPos)
1091+{ // between 0 and 1
1092+ if (pickPos<0.f) pickPos=0.f;
1093+ else if (pickPos>1.f) pickPos=1.f;
1094+ p->pickPos = pickPos;
1095+ tExpSmooth_setDest(&p->ppSmooth, p->pickPos);
1096+ return 0;
1097+}
1098+
1099+int tLivingString_setPrepIndex(tLivingString* const p, float prepIndex)
1100+{ // between 0 and 1
1101+ if (prepIndex<0.f) prepIndex=0.f;
1102+ else if (prepIndex>1.f) prepIndex=1.f;
1103+ p->prepIndex = prepIndex;
1104+ return 0;
1105+}
1106+
1107+int tLivingString_setDampFreq(tLivingString* const p, float dampFreq)
1108+{
1109+ tOnePole_setFreq(&p->bridgeFilter, dampFreq);
1110+ tOnePole_setFreq(&p->nutFilter, dampFreq);
1111+ tOnePole_setFreq(&p->prepFilterU, dampFreq);
1112+ tOnePole_setFreq(&p->prepFilterL, dampFreq);
1113+ return 0;
1114+}
1115+
1116+int tLivingString_setDecay(tLivingString* const p, float decay)
1117+{
1118+ p->decay=decay;
1119+ return 0;
1120+}
1121+
1122+int tLivingString_setTargetLev(tLivingString* const p, float targetLev)
1123+{
1124+ tFBleveller_setTargetLevel(&p->fbLevU, targetLev);
1125+ tFBleveller_setTargetLevel(&p->fbLevL, targetLev);
1126+ return 0;
1127+}
1128+
1129+int tLivingString_setLevSmoothFactor(tLivingString* const p, float levSmoothFactor)
1130+{
1131+ tFBleveller_setFactor(&p->fbLevU, levSmoothFactor);
1132+ tFBleveller_setFactor(&p->fbLevL, levSmoothFactor);
1133+ return 0;
1134+}
1135+
1136+int tLivingString_setLevStrength(tLivingString* const p, float levStrength)
1137+{
1138+ tFBleveller_setStrength(&p->fbLevU, levStrength);
1139+ tFBleveller_setStrength(&p->fbLevL, levStrength);
1140+ return 0;
1141+}
1142+
1143+int tLivingString_setLevMode(tLivingString* const p, int levMode)
1144+{
1145+ tFBleveller_setMode(&p->fbLevU, levMode);
1146+ tFBleveller_setMode(&p->fbLevL, levMode);
1147+ p->levMode=levMode;
1148+ return 0;
1149+}
1150+
1151+float tLivingString_tick(tLivingString* const p, float input)
1152+{
1153+ // from pickPos upwards=forwards
1154+ float fromLF=tDelayL_tickOut(&p->delLF);
1155+ float fromUF=tDelayL_tickOut(&p->delUF);
1156+ float fromUB=tDelayL_tickOut(&p->delUB);
1157+ float fromLB=tDelayL_tickOut(&p->delLB);
1158+ // into upper half of string, from nut, going backwards
1159+ float fromNut=-tFBleveller_tick(&p->fbLevU, (p->levMode==0?p->decay:1)*tHighpass_tick(&p->DCblockerU, tOnePole_tick(&p->nutFilter, fromUF)));
1160+ tDelayL_tickIn(&p->delUB, fromNut);
1161+ // into lower half of string, from pickpoint, going backwards
1162+ float fromLowerPrep=-tOnePole_tick(&p->prepFilterL, fromLF);
1163+ float intoLower=p->prepIndex*fromLowerPrep+(1-p->prepIndex)*fromUB+input;
1164+ tDelayL_tickIn(&p->delLB, intoLower);
1165+ // into lower half of string, from bridge
1166+ float fromBridge=-tFBleveller_tick(&p->fbLevL, (p->levMode==0?p->decay:1)*tHighpass_tick(&p->DCblockerL, tOnePole_tick(&p->bridgeFilter, fromLB)));
1167+ tDelayL_tickIn(&p->delLF, fromBridge);
1168+ // into upper half of string, from pickpoint, going forwards/upwards
1169+ float fromUpperPrep=-tOnePole_tick(&p->prepFilterU, fromUB);
1170+ float intoUpper=p->prepIndex*fromUpperPrep+(1-p->prepIndex)*fromLF+input;
1171+ tDelayL_tickIn(&p->delUF, intoUpper);
1172+ // update all delay lengths
1173+ float pickP=tExpSmooth_tick(&p->ppSmooth);
1174+ float wLen=tExpSmooth_tick(&p->wlSmooth);
1175+ float lowLen=pickP*wLen;
1176+ float upLen=(1-pickP)*wLen;
1177+ tDelayL_setDelay(&p->delLF, lowLen);
1178+ tDelayL_setDelay(&p->delLB, lowLen);
1179+ tDelayL_setDelay(&p->delUF, upLen);
1180+ tDelayL_setDelay(&p->delUB, upLen);
1181+ p->curr = fromBridge;
1182+ return p->curr;
1183+}
1184+
1185+float tLivingString_sample(tLivingString* const p)
1186+{
1187+ return p->curr;
1188+}
1189+
1190+
1191+/* Stack */
1192+
7781193 // If stack contains note, returns index. Else returns -1;
7791194 int tStack_contains(tStack* const ns, uint16_t noteVal)
7801195 {
LEAF/Src/leaf-wavefolder.c+2−2
@@ -16,7 +16,7 @@ · 15 unmodified lines
1616
1717 #endif
1818
19−void tLockhartWavefolderInit(tLockhartWavefolder* const w)
19+void tLockhartWavefolder_init(tLockhartWavefolder* const w)
2020 {
2121 w->Ln1 = 0.0;
2222 w->Fn1 = 0.0;
@@ -54,7 +54,7 @@ double tLockhartWavefolderLambert(double x, double ln) · 31 unmodified lines
5454 return w;
5555 }
5656
57−float tLockhartWavefolderTick(tLockhartWavefolder* const w, float samp)
57+float tLockhartWavefolder_tick(tLockhartWavefolder* const w, float samp)
5858 {
5959 int l;
6060 double u, Ln, Fn, xn;
LEAF/leaf.h+22−20
@@ -9,13 +9,13 @@ · 8 unmodified lines
99 */
1010
1111 #ifndef LEAF_H_INCLUDED
12−#define LEAF_H_INCLUDED
13−
14−#define LEAF_DEBUG 0
15−
16−#if LEAF_DEBUG
17−#include "../LEAF_JUCEPlugin/JuceLibraryCode/JuceHeader.h"
18−#endif
12+#define LEAF_H_INCLUDED
13+
14+#define LEAF_DEBUG 0
15+
16+#if LEAF_DEBUG
17+#include "../LEAF_JUCEPlugin/JuceLibraryCode/JuceHeader.h"
18+#endif
1919
2020 #if _WIN32 || _WIN64
2121
@@ -25,14 +25,15 @@ · 3 unmodified lines
2525 #include ".\Inc\leaf-delay.h"
2626 #include ".\Inc\leaf-filter.h"
2727 #include ".\Inc\leaf-oscillator.h"
28+#include ".\Inc\leaf-oversampler.h"
2829 #include ".\Inc\leaf-reverb.h"
2930 #include ".\Inc\leaf-vocoder.h"
3031 #include ".\Inc\leaf-808.h"
3132 #include ".\Inc\leaf-string.h"
3233 #include ".\Inc\leaf-pitch.h"
3334 #include ".\Inc\leaf-formant.h"
34−#include ".\Inc\leaf-midi.h"
35−#include ".\Inc\leaf-sample.h"
35+#include ".\Inc\leaf-midi.h"
36+#include ".\Inc\leaf-sample.h"
3637 #include ".\Inc\leaf-crusher.h"
3738 #include ".\Inc\leaf-wavefolder.h"
3839 #include ".\Inc\leaf-wavetables.h"
@@ -46,31 +47,32 @@ · 7 unmodified lines
4647 #include "./Inc/leaf-delay.h"
4748 #include "./Inc/leaf-filter.h"
4849 #include "./Inc/leaf-oscillator.h"
50+#include "./Inc/leaf-oversampler.h"
4951 #include "./Inc/leaf-reverb.h"
5052 #include "./Inc/leaf-vocoder.h"
5153 #include "./Inc/leaf-808.h"
5254 #include "./Inc/leaf-string.h"
5355 #include "./Inc/leaf-pitch.h"
5456 #include "./Inc/leaf-formant.h"
55−#include "./Inc/leaf-midi.h"
56−#include "./Inc/leaf-sample.h"
57+#include "./Inc/leaf-midi.h"
58+#include "./Inc/leaf-sample.h"
5759 #include "./Inc/leaf-crusher.h"
5860 #include "./Inc/leaf-wavefolder.h"
5961 #include "./Inc/leaf-wavetables.h"
6062 #include "./Inc/leaf-crusher.h"
6163
62−#endif
64+#endif
6365
64−#ifdef __cplusplus
65−extern "C" {
66−#endif
66+#ifdef __cplusplus
67+extern "C" {
68+#endif
6769
6870 void LEAF_init (float sampleRate, int blocksize, float(*randomNumberFunction)(void));
6971 void LEAF_setSampleRate (float sampleRate);
70−float LEAF_getSampleRate (void);
71−
72−#ifdef __cplusplus
73−}
74−#endif
72+float LEAF_getSampleRate (void);
73+
74+#ifdef __cplusplus
75+}
76+#endif
7577
7678 #endif // LEAF_H_INCLUDED
LEAF_JUCEPlugin/Source/MyTest.cpp+1−0
@@ -191,3 +191,4 @@ static void run_pool_test(void) · 190 unmodified lines
191191
192192 leaf_pool_dump();
193193 }
194+

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