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
75float tDelayL_tapOut (tDelayL* const, float tapDelay);75float tDelayL_tapOut (tDelayL* const, float tapDelay);
76float tDelayL_addTo (tDelayL* const, float value, uint32_t tapDelay);76float tDelayL_addTo (tDelayL* const, float value, uint32_t tapDelay);
77float tDelayL_tick (tDelayL* const, float sample);77float tDelayL_tick (tDelayL* const, float sample);
78void tDelayL_tickIn (tDelayL* const d, float input);
79float tDelayL_tickOut (tDelayL* const d);
78float tDelayL_getLastOut (tDelayL* const);80float tDelayL_getLastOut (tDelayL* const);
79float tDelayL_getLastIn (tDelayL* const);81float tDelayL_getLastIn (tDelayL* const);
80 82
LEAF/Inc/leaf-globals.h+2−3
@@ -49,15 +49,14 @@ extern const float shaper1[SHAPER1_TABLE_SIZE]; · 48 unmodified lines
49#define MPOLY_NUM_MAX_VOICES 849#define MPOLY_NUM_MAX_VOICES 8
50#define NUM_OSC 450#define NUM_OSC 4
51#define INV_NUM_OSC (1.0f / NUM_OSC)51#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?) this52#define PS_FRAME_SIZE 1024 // SNAC_FRAME_SIZE in leaf-pitch.h should match (or be smaller than?) this
53#define ENV_WINDOW_SIZE 102453#define ENV_WINDOW_SIZE 1024
54#define ENV_HOP_SIZE 25654#define ENV_HOP_SIZE 256
55#define NUM_KNOBS 4
56 55
57#define DELAY_LENGTH 16000 // The maximum delay length of all Delay/DelayL/DelayA components.56#define DELAY_LENGTH 16000 // The maximum delay length of all Delay/DelayL/DelayA components.
58 // Feel free to change to suit memory constraints or desired delay max length / functionality.57 // Feel free to change to suit memory constraints or desired delay max length / functionality.
59 58
60#define TALKBOX_BUFFER_LENGTH 1600 // Every talkbox instance introduces 5 buffers of this size59
61 60
62 61
63union unholy_t { /* a union between a float and an integer */62union 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
50 50
51//==============================================================================51//==============================================================================
52 52
53
53#define MPOOL_POOL_SIZE 50000054#define MPOOL_POOL_SIZE 500000
55
54#define MPOOL_ALIGN_SIZE (8)56#define MPOOL_ALIGN_SIZE (8)
55 57
56//#define size_t unsigned long58//#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
14extern "C" {
15#endif
16
17//==============================================================================
18
19#include "leaf-globals.h"
20#include "leaf-math.h"
21#include "leaf-filter.h"
22
23//==============================================================================
24typedef struct _tOversamplerFilter
25{
26 float cutoff, Q;
27 float ic1eq,ic2eq;
28 float g,k,a1,a2,a3;
29} tOversamplerFilter;
30
31typedef struct _tOversampler2x
32{
33 tOversamplerFilter filters[2];
34} tOversampler2x;
35
36void tOversampler2x_init(tOversampler2x* const);
37float tOversampler2x_tick(tOversampler2x* const, float input, float (*nonLinearTick)(float));
38
39typedef struct _tOversampler4x
40{
41 tOversamplerFilter filters[4];
42} tOversampler4x;
43
44void tOversampler4x_init(tOversampler4x* const);
45float 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 ==============================================================================
2 3
3 leaf-utilities.h4 LEAFUtilities.h
4 Created: 20 Jan 2017 12:02:17pm5 Created: 20 Jan 2017 12:02:17pm
5 Author: Michael R Mulshine6 Author: Michael R Mulshine
6 7
7==============================================================================*/8 ==============================================================================
9*/
8 10
9#ifndef LEAF_UTILITIES_H_INCLUDED11#ifndef LEAFUTILITIES_H_INCLUDED
10#define LEAF_UTILITIES_H_INCLUDED12#define LEAFUTILITIES_H_INCLUDED
11 13
12#ifdef __cplusplus14#ifdef __cplusplus
13extern "C" {15extern "C" {
14#endif16#endif
15 17
16//==============================================================================18// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
17 19
18#include "leaf-globals.h"20#include "leaf-globals.h"
19#include "leaf-math.h"21#include "leaf-math.h"
22#include "leaf-filter.h"
23#include "leaf-delay.h"
20 24
21//==============================================================================25// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
22 26
23// STACK implementation (fixed size)27// STACK implementation (fixed size)
24#define STACK_SIZE 12828#define STACK_SIZE 128
@@ -46,7 +50,7 @@ int tStack_contains (tStack* const, uint16_t item); · 21 unmodified lines
46int tStack_next (tStack* const);50int tStack_next (tStack* const);
47int tStack_get (tStack* const, int which);51int tStack_get (tStack* const, int which);
48 52
49//==============================================================================53// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
50 54
51/* Ramp */55/* Ramp */
52typedef struct _tRamp {56typedef struct _tRamp {
@@ -68,7 +72,148 @@ int tRamp_setTime (tRamp* const, float time); · 15 unmodified lines
68int tRamp_setDest (tRamp* const, float dest);72int tRamp_setDest (tRamp* const, float dest);
69int tRamp_setVal (tRamp* const, float val);73int tRamp_setVal (tRamp* const, float val);
70 74
71//==============================================================================75// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
76
77/* Exponential Smoother */
78typedef struct _tExpSmooth {
79 float factor, oneminusfactor;
80 float curr,dest;
81
82} tExpSmooth;
83
84void tExpSmooth_init (tExpSmooth* const, float val, float factor);
85void tExpSmooth_free (tExpSmooth* const);
86
87float tExpSmooth_tick (tExpSmooth* const);
88float tExpSmooth_sample (tExpSmooth* const);
89int tExpSmooth_setFactor (tExpSmooth* const, float factor);
90int tExpSmooth_setDest (tExpSmooth* const, float dest);
91int tExpSmooth_setVal (tExpSmooth* const, float val);
92
93// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
94
95/* PowerEnvelopeFollower */
96typedef struct _tPwrFollow {
97 float factor, oneminusfactor;
98 float curr;
99
100} tPwrFollow;
101
102void tPwrFollow_init (tPwrFollow* const, float factor);
103void tPwrFollow_free (tPwrFollow* const);
104float tPwrFollow_tick (tPwrFollow* const, float input);
105float tPwrFollow_sample (tPwrFollow* const);
106int tPwrFollow_setFactor (tPwrFollow* const, float factor);
107
108// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
109
110//Reed Table - borrowed from STK
111typedef struct _tReedTable {
112 float offset, slope;
113} tReedTable;
114
115void tReedTable_init (tReedTable* const, float offset, float slope);
116void tReedTable_free (tReedTable* const);
117float tReedTable_tick (tReedTable* const, float input);
118float tReedTable_tanh_tick (tReedTable* const p, float input); //tanh softclip version of reed table - replacing the hard clip in original stk code
119void tReedTable_setOffset (tReedTable* const, float offset);
120void 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
132typedef 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
141void tFBleveller_init (tFBleveller* const, float targetLevel, float factor, float strength, int mode);
142void tFBleveller_free (tFBleveller* const);
143
144float tFBleveller_tick (tFBleveller* const, float input);
145float tFBleveller_sample (tFBleveller* const);
146int tFBleveller_setTargetLevel (tFBleveller* const, float TargetLevel);
147int tFBleveller_setFactor (tFBleveller* const, float factor);
148int tFBleveller_setMode (tFBleveller* const, int mode); // 0 for upwards limiting only, 1 for biderctional limiting
149int tFBleveller_setStrength (tFBleveller* const, float strength);
150
151// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
152
153/* Simple Living String */
154typedef 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
167void tSimpleLivingString_init (tSimpleLivingString* const, float freq, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode);
168void tSimpleLivingString_free (tSimpleLivingString* const);
169float tSimpleLivingString_tick (tSimpleLivingString* const, float input);
170float tSimpleLivingString_sample (tSimpleLivingString* const);
171int tSimpleLivingString_setFreq (tSimpleLivingString* const, float freq);
172int tSimpleLivingString_setWaveLength (tSimpleLivingString* const, float waveLength); // in samples
173int tSimpleLivingString_setDampFreq (tSimpleLivingString* const, float dampFreq);
174int tSimpleLivingString_setDecay (tSimpleLivingString* const, float decay); // should be near 1.0
175int tSimpleLivingString_setTargetLev (tSimpleLivingString* const, float targetLev);
176int tSimpleLivingString_setLevSmoothFactor (tSimpleLivingString* const, float levSmoothFactor);
177int tSimpleLivingString_setLevStrength (tSimpleLivingString* const, float levStrength);
178int tSimpleLivingString_setLevMode (tSimpleLivingString* const, int levMode);
179
180
181// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
182
183/* Living String */
184typedef 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
199void tLivingString_init (tLivingString* const, float freq, float pickPos, float prepIndex, float dampFreq, float decay,
200 float targetLev, float levSmoothFactor, float levStrength, int levMode);
201void tLivingString_free (tLivingString* const);
202float tLivingString_tick (tLivingString* const, float input);
203float tLivingString_sample (tLivingString* const);
204int tLivingString_setFreq (tLivingString* const, float freq);
205int tLivingString_setWaveLength (tLivingString* const, float waveLength); // in samples
206int tLivingString_setPickPos (tLivingString* const, float pickPos);
207int tLivingString_setPrepIndex (tLivingString* const, float prepIndex);
208int tLivingString_setDampFreq (tLivingString* const, float dampFreq);
209int tLivingString_setDecay (tLivingString* const, float decay); // should be near 1.0
210int tLivingString_setTargetLev (tLivingString* const, float targetLev);
211int tLivingString_setLevSmoothFactor (tLivingString* const, float levSmoothFactor);
212int tLivingString_setLevStrength (tLivingString* const, float levStrength);
213int tLivingString_setLevMode (tLivingString* const, int levMode);
214
215
216// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
72 217
73/* Compressor */218/* Compressor */
74typedef struct _tCompressor219typedef struct _tCompressor
@@ -86,7 +231,7 @@ void tCompressor_init (tCompressor* const); · 11 unmodified lines
86void tCompressor_free (tCompressor* const);231void tCompressor_free (tCompressor* const);
87float tCompressor_tick (tCompressor* const, float input);232float tCompressor_tick (tCompressor* const, float input);
88 233
89//==============================================================================234// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
90 235
91/* Attack-Decay envelope */236/* Attack-Decay envelope */
92typedef struct _tEnvelope {237typedef struct _tEnvelope {
@@ -118,7 +263,7 @@ int tEnvelope_setDecay (tEnvelope* const, float decay); · 25 unmodified lines
118int tEnvelope_loop (tEnvelope* const, oBool loop);263int tEnvelope_loop (tEnvelope* const, oBool loop);
119int tEnvelope_on (tEnvelope* const, float velocity);264int tEnvelope_on (tEnvelope* const, float velocity);
120 265
121//==============================================================================266// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
122 267
123/* ADSR */268/* ADSR */
124typedef struct _tADSR269typedef struct _tADSR
@@ -150,7 +295,7 @@ int tADSR_setRelease(tADSR* const, float release); · 25 unmodified lines
150int tADSR_on (tADSR* const, float velocity);295int tADSR_on (tADSR* const, float velocity);
151int tADSR_off (tADSR* const);296int tADSR_off (tADSR* const);
152 297
153//==============================================================================298// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
154 299
155/* Envelope Follower */300/* Envelope Follower */
156typedef struct _tEnvelopeFollower301typedef struct _tEnvelopeFollower
@@ -168,7 +313,7 @@ float tEnvelopeFollower_tick (tEnvelopeFollower* const, float x); · 11 unmodified lines
168int tEnvelopeFollower_decayCoeff (tEnvelopeFollower* const, float decayCoeff);313int tEnvelopeFollower_decayCoeff (tEnvelopeFollower* const, float decayCoeff);
169int tEnvelopeFollower_attackThresh (tEnvelopeFollower* const, float attackThresh);314int tEnvelopeFollower_attackThresh (tEnvelopeFollower* const, float attackThresh);
170 315
171//==============================================================================316// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
172 317
173/* tAtkDtk */318/* tAtkDtk */
174#define DEFBLOCKSIZE 1024319#define DEFBLOCKSIZE 1024
@@ -219,7 +364,7 @@ void tAtkDtk_setThreshold (tAtkDtk* const, float thres); · 44 unmodified lines
219// find largest transient in input block, return index of attack364// find largest transient in input block, return index of attack
220int tAtkDtk_detect (tAtkDtk* const, float *in);365int tAtkDtk_detect (tAtkDtk* const, float *in);
221 366
222//==============================================================================367// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
223 368
224// ENV~ from PD, modified for LEAF369// ENV~ from PD, modified for LEAF
225#define MAXOVERLAP 32370#define MAXOVERLAP 32
@@ -244,14 +389,12 @@ void tEnv_free (tEnv* const); · 18 unmodified lines
244float tEnv_tick (tEnv* const);389float tEnv_tick (tEnv* const);
245void tEnv_processBlock (tEnv* const, float* in);390void tEnv_processBlock (tEnv* const, float* in);
246 391
247//==============================================================================392// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
248 393
249#ifdef __cplusplus394#ifdef __cplusplus
250}395}
251#endif396#endif
252 397
253#endif // LEAF_UTILITIES_H_INCLUDED398#endif // LEAFUTILITIES_H_INCLUDED
254
255//==============================================================================
256 399
257 400
LEAF/Inc/leaf-vocoder.h+1−1
@@ -22,7 +22,7 @@ extern "C" { · 21 unmodified lines
22 22
23/* tTalkbox */23/* tTalkbox */
24#define NUM_TALKBOX_PARAM 424#define NUM_TALKBOX_PARAM 4
25#define TALKBOX_BUFFER_LENGTH 1024 //160025#define TALKBOX_BUFFER_LENGTH 1024 // Every talkbox instance introduces 5 buffers of this size - was originally 1600
26 26
27typedef struct _tTalkbox27typedef struct _tTalkbox
28{28{
LEAF/Src/leaf-delay.c+24−0
@@ -178,6 +178,30 @@ float tDelayL_tick (tDelayL* const d, float input) · 177 unmodified lines
178 return d->lastOut;178 return d->lastOut;
179}179}
180 180
181void 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
189float 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
181int tDelayL_setDelay (tDelayL* const d, float delay)205int tDelayL_setDelay (tDelayL* const d, float delay)
182{206{
183 d->delay = LEAF_clip(0.0f, delay, d->maxDelay);207 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.
20void 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
41float 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
54void 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
60float 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
78void 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
86float 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 ==============================================================================
2 3
3 leaf-utilities.c4 LEAFUtilities.c
4 Created: 20 Jan 2017 12:02:17pm5 Created: 20 Jan 2017 12:02:17pm
5 Author: Michael R Mulshine6 Author: Michael R Mulshine
6 7
7==============================================================================*/8 ==============================================================================
9*/
8 10
9 11
10#if _WIN32 || _WIN6412#if _WIN32 || _WIN64
@@ -29,12 +31,12 @@ float mtof(float f) · 18 unmodified lines
29{31{
30 if (f <= -1500.0f) return(0);32 if (f <= -1500.0f) return(0);
31 else if (f > 1499.0f) return(mtof(1499.0f));33 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));
33}35}
34 36
35float ftom(float f)37float ftom(float f)
36{38{
37 return (f > 0 ? 17.3123405046f * log(.12231220585f * f) : -1500.0f);39 return (f > 0 ? 17.3123405046f * logf(.12231220585f * f) : -1500.0f);
38}40}
39 41
40float powtodb(float f)42float powtodb(float f)
@@ -42,7 +44,7 @@ float powtodb(float f) · 1 unmodified line
42 if (f <= 0) return (0);44 if (f <= 0) return (0);
43 else45 else
44 {46 {
45 float val = 100 + 10.f/LOGTEN * log(f);47 float val = 100 + 10.f/LOGTEN * logf(f);
46 return (val < 0 ? 0 : val);48 return (val < 0 ? 0 : val);
47 }49 }
48}50}
@@ -65,7 +67,7 @@ float dbtopow(float f) · 16 unmodified lines
65 {67 {
66 if (f > 870.0f)68 if (f > 870.0f)
67 f = 870.0f;69 f = 870.0f;
68 return (exp((LOGTEN * 0.1f) * (f-100.0f)));70 return (expf((LOGTEN * 0.1f) * (f-100.0f)));
69 }71 }
70}72}
71 73
@@ -78,7 +80,7 @@ float dbtorms(float f) · 6 unmodified lines
78 if (f > 485.0f)80 if (f > 485.0f)
79 f = 485.0f;81 f = 485.0f;
80 }82 }
81 return (exp((LOGTEN * 0.05f) * (f-100.0f)));83 return (expf((LOGTEN * 0.05f) * (f-100.0f)));
82}84}
83 85
84/* ---------------- env~ - simple envelope follower. ----------------- */86/* ---------------- env~ - simple envelope follower. ----------------- */
@@ -103,7 +105,7 @@ void tEnv_init(tEnv* const x, int ws, int hs, int bs) · 18 unmodified lines
103 105
104 for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;106 for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
105 for (i = 0; i < npoints; i++)107 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;
107 for (; i < npoints+INITVSTAKEN; i++) x->buf[i] = 0;109 for (; i < npoints+INITVSTAKEN; i++) x->buf[i] = 0;
108 110
109 x->x_f = 0;111 x->x_f = 0;
@@ -761,6 +763,8 @@ float tRamp_tick(tRamp* const r) { · 651 unmodified lines
761 r->curr += r->inc;763 r->curr += r->inc;
762 764
763 if (((r->curr >= r->dest) && (r->inc > 0.0f)) || ((r->curr <= r->dest) && (r->inc < 0.0f))) r->inc = 0.0f;765 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
764 768
765 return r->curr;769 return r->curr;
766}770}
@@ -775,6 +779,417 @@ void tRampSampleRateChanged(tRamp* const r) · 8 unmodified lines
775 r->inv_sr_ms = 1.0f / (leaf.sampleRate * 0.001f);779 r->inv_sr_ms = 1.0f / (leaf.sampleRate * 0.001f);
776 r->inc = ((r->dest-r->curr)/r->time * r->inv_sr_ms)*((float)r->samples_per_tick);780 r->inc = ((r->dest-r->curr)/r->time * r->inv_sr_ms)*((float)r->samples_per_tick);
777}781}
782
783
784/* Exponential Smoother */
785void 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
795int 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
806int tExpSmooth_setDest(tExpSmooth* const smooth, float dest)
807{
808 smooth->dest=dest;
809 return 0;
810}
811
812int tExpSmooth_setVal(tExpSmooth* const smooth, float val)
813{
814 smooth->curr=val;
815 return 0;
816}
817
818float tExpSmooth_tick(tExpSmooth* const smooth)
819{
820 smooth->curr = smooth->factor*smooth->dest+smooth->oneminusfactor*smooth->curr;
821 return smooth->curr;
822}
823
824float tExpSmooth_sample(tExpSmooth* const smooth)
825{
826 return smooth->curr;
827}
828
829
830/* Power Follower */
831
832void 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
839int 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
848float 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
854float tPwrFollow_sample(tPwrFollow* const p)
855{
856 return p->curr;
857}
858
859/* Feedback Leveler */
860
861void 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
870int 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
877int tFBleveller_setFactor(tFBleveller* const p, float factor)
878{
879 tPwrFollow_setFactor(&p->pwrFlw,factor);
880 return 0;
881}
882
883int 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
889float 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
897float tFBleveller_sample(tFBleveller* const p)
898{
899 return p->curr;
900}
901
902
903int 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
911void tReedTable_init (tReedTable* const p, float offset, float slope)
912{
913 p->offset = offset;
914 p->slope = slope;
915}
916
917void tReedTable_free (tReedTable* const p)
918{
919 ;
920}
921
922float 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
939float 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
949void tReedTable_setOffset (tReedTable* const p, float offset)
950{
951 p->offset = offset;
952}
953
954void tReedTable_setSlope (tReedTable* const p, float slope)
955{
956 p->slope = slope;
957}
958
959
960
961/* Simple Living String*/
962
963void 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
976int 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
985int 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
994int tSimpleLivingString_setDampFreq(tSimpleLivingString* const p, float dampFreq)
995{
996 tOnePole_setFreq(&p->bridgeFilter, dampFreq);
997 return 0;
998}
999
1000int tSimpleLivingString_setDecay(tSimpleLivingString* const p, float decay)
1001{
1002 p->decay=decay;
1003 return 0;
1004}
1005
1006int tSimpleLivingString_setTargetLev(tSimpleLivingString* const p, float targetLev)
1007{
1008 tFBleveller_setTargetLevel(&p->fbLev, targetLev);
1009 return 0;
1010}
1011
1012int tSimpleLivingString_setLevSmoothFactor(tSimpleLivingString* const p, float levSmoothFactor)
1013{
1014 tFBleveller_setFactor(&p->fbLev, levSmoothFactor);
1015 return 0;
1016}
1017
1018int tSimpleLivingString_setLevStrength(tSimpleLivingString* const p, float levStrength)
1019{
1020 tFBleveller_setStrength(&p->fbLev, levStrength);
1021 return 0;
1022}
1023
1024int tSimpleLivingString_setLevMode(tSimpleLivingString* const p, int levMode)
1025{
1026 tFBleveller_setMode(&p->fbLev, levMode);
1027 p->levMode=levMode;
1028 return 0;
1029}
1030
1031float 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
1041float tSimpleLivingString_sample(tSimpleLivingString* const p)
1042{
1043 return p->curr;
1044}
1045
1046/* Living String*/
1047
1048void 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
1072int 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
1081int 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
1090int 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
1099int 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
1107int 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
1116int tLivingString_setDecay(tLivingString* const p, float decay)
1117{
1118 p->decay=decay;
1119 return 0;
1120}
1121
1122int 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
1129int 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
1136int 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
1143int 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
1151float 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
1185float tLivingString_sample(tLivingString* const p)
1186{
1187 return p->curr;
1188}
1189
1190
1191/* Stack */
1192
778// If stack contains note, returns index. Else returns -1;1193// If stack contains note, returns index. Else returns -1;
779int tStack_contains(tStack* const ns, uint16_t noteVal)1194int tStack_contains(tStack* const ns, uint16_t noteVal)
780{1195{
LEAF/Src/leaf-wavefolder.c+2−2
@@ -16,7 +16,7 @@ · 15 unmodified lines
16 16
17#endif17#endif
18 18
19void tLockhartWavefolderInit(tLockhartWavefolder* const w)19void tLockhartWavefolder_init(tLockhartWavefolder* const w)
20{20{
21 w->Ln1 = 0.0;21 w->Ln1 = 0.0;
22 w->Fn1 = 0.0;22 w->Fn1 = 0.0;
@@ -54,7 +54,7 @@ double tLockhartWavefolderLambert(double x, double ln) · 31 unmodified lines
54 return w;54 return w;
55}55}
56 56
57float tLockhartWavefolderTick(tLockhartWavefolder* const w, float samp)57float tLockhartWavefolder_tick(tLockhartWavefolder* const w, float samp)
58{58{
59 int l;59 int l;
60 double u, Ln, Fn, xn;60 double u, Ln, Fn, xn;
LEAF/leaf.h+22−20
@@ -9,13 +9,13 @@ · 8 unmodified lines
9*/9*/
10 10
11#ifndef LEAF_H_INCLUDED11#ifndef LEAF_H_INCLUDED
12#define LEAF_H_INCLUDED12#define LEAF_H_INCLUDED
13 13
14#define LEAF_DEBUG 014#define LEAF_DEBUG 0
15 15
16#if LEAF_DEBUG16#if LEAF_DEBUG
17#include "../LEAF_JUCEPlugin/JuceLibraryCode/JuceHeader.h"17#include "../LEAF_JUCEPlugin/JuceLibraryCode/JuceHeader.h"
18#endif18#endif
19 19
20#if _WIN32 || _WIN6420#if _WIN32 || _WIN64
21 21
@@ -25,14 +25,15 @@ · 3 unmodified lines
25#include ".\Inc\leaf-delay.h"25#include ".\Inc\leaf-delay.h"
26#include ".\Inc\leaf-filter.h"26#include ".\Inc\leaf-filter.h"
27#include ".\Inc\leaf-oscillator.h"27#include ".\Inc\leaf-oscillator.h"
28#include ".\Inc\leaf-oversampler.h"
28#include ".\Inc\leaf-reverb.h"29#include ".\Inc\leaf-reverb.h"
29#include ".\Inc\leaf-vocoder.h"30#include ".\Inc\leaf-vocoder.h"
30#include ".\Inc\leaf-808.h"31#include ".\Inc\leaf-808.h"
31#include ".\Inc\leaf-string.h"32#include ".\Inc\leaf-string.h"
32#include ".\Inc\leaf-pitch.h"33#include ".\Inc\leaf-pitch.h"
33#include ".\Inc\leaf-formant.h"34#include ".\Inc\leaf-formant.h"
34#include ".\Inc\leaf-midi.h"35#include ".\Inc\leaf-midi.h"
35#include ".\Inc\leaf-sample.h"36#include ".\Inc\leaf-sample.h"
36#include ".\Inc\leaf-crusher.h"37#include ".\Inc\leaf-crusher.h"
37#include ".\Inc\leaf-wavefolder.h"38#include ".\Inc\leaf-wavefolder.h"
38#include ".\Inc\leaf-wavetables.h"39#include ".\Inc\leaf-wavetables.h"
@@ -46,31 +47,32 @@ · 7 unmodified lines
46#include "./Inc/leaf-delay.h"47#include "./Inc/leaf-delay.h"
47#include "./Inc/leaf-filter.h"48#include "./Inc/leaf-filter.h"
48#include "./Inc/leaf-oscillator.h"49#include "./Inc/leaf-oscillator.h"
50#include "./Inc/leaf-oversampler.h"
49#include "./Inc/leaf-reverb.h"51#include "./Inc/leaf-reverb.h"
50#include "./Inc/leaf-vocoder.h"52#include "./Inc/leaf-vocoder.h"
51#include "./Inc/leaf-808.h"53#include "./Inc/leaf-808.h"
52#include "./Inc/leaf-string.h"54#include "./Inc/leaf-string.h"
53#include "./Inc/leaf-pitch.h"55#include "./Inc/leaf-pitch.h"
54#include "./Inc/leaf-formant.h"56#include "./Inc/leaf-formant.h"
55#include "./Inc/leaf-midi.h"57#include "./Inc/leaf-midi.h"
56#include "./Inc/leaf-sample.h"58#include "./Inc/leaf-sample.h"
57#include "./Inc/leaf-crusher.h"59#include "./Inc/leaf-crusher.h"
58#include "./Inc/leaf-wavefolder.h"60#include "./Inc/leaf-wavefolder.h"
59#include "./Inc/leaf-wavetables.h"61#include "./Inc/leaf-wavetables.h"
60#include "./Inc/leaf-crusher.h"62#include "./Inc/leaf-crusher.h"
61 63
62#endif64#endif
63 65
64#ifdef __cplusplus66#ifdef __cplusplus
65extern "C" {67extern "C" {
66#endif68#endif
67 69
68void LEAF_init (float sampleRate, int blocksize, float(*randomNumberFunction)(void));70void LEAF_init (float sampleRate, int blocksize, float(*randomNumberFunction)(void));
69void LEAF_setSampleRate (float sampleRate);71void LEAF_setSampleRate (float sampleRate);
70float LEAF_getSampleRate (void);72float LEAF_getSampleRate (void);
71 73
72#ifdef __cplusplus74#ifdef __cplusplus
73}75}
74#endif76#endif
75 77
76#endif // LEAF_H_INCLUDED78#endif // LEAF_H_INCLUDED
LEAF_JUCEPlugin/Source/MyTest.cpp+1−0
@@ -191,3 +191,4 @@ static void run_pool_test(void) · 190 unmodified lines
191 191
192 leaf_pool_dump();192 leaf_pool_dump();
193}193}
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