History

First commit.

mulshine committed 7 years ago

Commit 127a1131 parent 824e8d1147 files · +49021 −-7Browse files

Showing the changes to LEAF/Src_cpp/leaf-string.cpp (1 of 147 files). Show all

Unified · Split

LEAF/Src_cpp/leaf-string.cpp+294−0
@@ -0,0 +1,294 @@
1/*
2 ==============================================================================
3
4 leaf-string.cpp
5 Created: 30 Nov 2018 10:41:42am
6 Author: airship
7
8 ==============================================================================
9*/
10
11#if _WIN32 || _WIN64
12
13#include "..\Inc\leaf-string.h"
14
15#else
16
17#include "../Inc/leaf-string.h"
18
19#endif
20
21/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tPluck ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
22void tPluck_init (tPluck* const p, float lowestFrequency)
23{
24 if ( lowestFrequency <= 0.0f ) lowestFrequency = 10.0f;
25
26 p->noise = (tNoise*)leaf_alloc(sizeof(tNoise));
27 tNoise_init(p->noise, WhiteNoise);
28
29 p->pickFilter = (tOnePole*) leaf_alloc(sizeof(tOnePole));
30 tOnePole_init(p->pickFilter, 0.0f);
31
32 p->loopFilter = (tOneZero*) leaf_alloc(sizeof(tOneZero));
33 tOneZero_init(p->loopFilter, 0.0f);
34
35 p->delayLine = (tDelayA*) leaf_alloc(sizeof(tDelayA));
36 tDelayA_init(p->delayLine, 0.0f, leaf.sampleRate * 2);
37
38 tPluck_setFrequency(p, 220.0f);
39}
40
41float tPluck_getLastOut (tPluck *p)
42{
43 return p->lastOut;
44}
45
46float tPluck_tick (tPluck *p)
47{
48 return (p->lastOut = 3.0f * tDelayA_tick(p->delayLine, tOneZero_tick(p->loopFilter, tDelayA_getLastOut(p->delayLine) * p->loopGain ) ));
49}
50
51void tPluck_pluck (tPluck* const p, float amplitude)
52{
53 if ( amplitude < 0.0f) amplitude = 0.0f;
54 else if (amplitude > 1.0f) amplitude = 1.0f;
55
56 tOnePole_setPole(p->pickFilter, 0.999f - (amplitude * 0.15f));
57 tOnePole_setGain(p->pickFilter, amplitude * 0.5f );
58
59 // Fill delay with noise additively with current contents.
60 for ( uint32_t i = 0; i < (uint32_t)tDelayA_getDelay(p->delayLine); i++ )
61 tDelayA_tick(p->delayLine, 0.6f * tDelayA_getLastOut(p->delayLine) + tOnePole_tick(p->pickFilter, tNoise_tick(p->noise) ) );
62}
63
64// Start a note with the given frequency and amplitude.;
65void tPluck_noteOn (tPluck* const p, float frequency, float amplitude )
66{
67 p->lastFreq = frequency;
68 tPluck_setFrequency( p, frequency );
69 tPluck_pluck( p, amplitude );
70}
71
72// Stop a note with the given amplitude (speed of decay).
73void tPluck_noteOff (tPluck* const p, float amplitude )
74{
75 if ( amplitude < 0.0f) amplitude = 0.0f;
76 else if (amplitude > 1.0f) amplitude = 1.0f;
77
78 p->loopGain = 1.0f - amplitude;
79}
80
81// Set instrument parameters for a particular frequency.
82void tPluck_setFrequency (tPluck* const p, float frequency )
83{
84 if ( frequency <= 0.0f ) frequency = 0.001f;
85
86 // Delay = length - filter delay.
87 float delay = ( leaf.sampleRate / frequency ) - tOneZero_getPhaseDelay(p->loopFilter, frequency );
88
89 tDelayA_setDelay(p->delayLine, delay );
90
91 p->loopGain = 0.99f + (frequency * 0.000005f);
92
93 if ( p->loopGain >= 0.999f ) p->loopGain = 0.999f;
94
95}
96
97// Perform the control change specified by \e number and \e value (0.0 - 128.0).
98void tPluck_controlChange (tPluck* const p, int number, float value)
99{
100 return;
101}
102
103void tPluckSampleRateChanged(tPluck* const p)
104{
105 //tPluckSetFrequency(p, p->lastFreq);
106}
107
108/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tStifKarp ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
109void tStifKarp_init (tStifKarp* const p, float lowestFrequency)
110{
111 if ( lowestFrequency <= 0.0f ) lowestFrequency = 8.0f;
112
113 p->delayLine = (tDelayA*) leaf_alloc(sizeof(tDelayA));
114 tDelayA_init(p->delayLine, 0.0f, leaf.sampleRate * 2);
115
116 p->combDelay = (tDelayL*) leaf_alloc(sizeof(tDelayL));
117 tDelayL_init(p->combDelay, 0.0f, leaf.sampleRate * 2);
118
119 p->filter = (tOneZero*) leaf_alloc(sizeof(tOneZero));
120 tOneZero_init(p->filter, 0.0f);
121
122 p->noise = (tNoise*) leaf_alloc(sizeof(tNoise));
123 tNoise_init(p->noise, WhiteNoise);
124
125 for (int i = 0; i < 4; i++)
126 {
127 p->biquad[i] = (tBiQuad*) leaf_alloc(sizeof(tBiQuad));
128 tBiQuad_init(p->biquad[i]);
129 }
130
131 p->pluckAmplitude = 0.3f;
132 p->pickupPosition = 0.4f;
133
134 p->stretching = 0.9999f;
135 p->baseLoopGain = 0.995f;
136 p->loopGain = 0.999f;
137
138 tStifKarp_setFrequency( p, 220.0f );
139
140}
141
142void tStifKarp_free (tStifKarp* const p)
143{
144 tDelayA_free(p->delayLine);
145 tDelayL_free(p->combDelay);
146 tOneZero_free(p->filter);
147 tNoise_free(p->noise);
148
149 for (int i = 0; i < 4; i++)
150 {
151 tBiQuad_free(p->biquad[i]);
152 }
153
154 leaf_free(p);
155}
156
157float tStifKarp_getLastOut (tStifKarp* const p)
158{
159 return p->lastOut;
160}
161
162float tStifKarp_tick (tStifKarp* const p)
163{
164 float temp = tDelayA_getLastOut(p->delayLine) * p->loopGain;
165
166 // Calculate allpass stretching.
167 for (int i=0; i<4; i++) temp = tBiQuad_tick(p->biquad[i],temp);
168
169 // Moving average filter.
170 temp = tOneZero_tick(p->filter, temp);
171
172 float out = tDelayA_tick(p->delayLine, temp);
173 out = out - tDelayL_tick(p->combDelay, out);
174 p->lastOut = out;
175
176 return p->lastOut;
177}
178
179void tStifKarp_pluck (tStifKarp* const p, float amplitude)
180{
181 if ( amplitude < 0.0f) amplitude = 0.0f;
182 else if (amplitude > 1.0f) amplitude = 1.0f;
183
184 p->pluckAmplitude = amplitude;
185
186 for ( uint32_t i=0; i < (uint32_t)tDelayA_getDelay(p->delayLine); i++ )
187 {
188 // Fill delay with noise additively with current contents.
189 tDelayA_tick(p->delayLine, (tDelayA_getLastOut(p->delayLine) * 0.6f) + 0.4f * tNoise_tick(p->noise) * p->pluckAmplitude );
190 //delayLine_.tick( combDelay_.tick((delayLine_.lastOut() * 0.6) + 0.4 * noise->tick() * pluckAmplitude_) );
191 }
192}
193
194// Start a note with the given frequency and amplitude.;
195void tStifKarp_noteOn (tStifKarp* const p, float frequency, float amplitude )
196{
197 tStifKarp_setFrequency( p, frequency );
198 tStifKarp_pluck( p, amplitude );
199}
200
201// Stop a note with the given amplitude (speed of decay).
202void tStifKarp_noteOff (tStifKarp* const p, float amplitude )
203{
204 if ( amplitude < 0.0f) amplitude = 0.0f;
205 else if (amplitude > 1.0f) amplitude = 1.0f;
206
207 p->loopGain = 1.0f - amplitude;
208}
209
210// Set instrument parameters for a particular frequency.
211void tStifKarp_setFrequency (tStifKarp* const p, float frequency )
212{
213 if ( frequency <= 0.0f ) frequency = 0.001f;
214
215 p->lastFrequency = frequency;
216 p->lastLength = leaf.sampleRate / p->lastFrequency;
217 float delay = p->lastLength - 0.5f;
218 tDelayA_setDelay(p->delayLine, delay );
219
220 // MAYBE MODIFY LOOP GAINS
221 p->loopGain = p->baseLoopGain + (frequency * 0.000005f);
222 if (p->loopGain >= 1.0f) p->loopGain = 0.99999f;
223
224 tStifKarp_setStretch(p, p->stretching);
225
226 tDelayL_setDelay(p->combDelay, 0.5f * p->pickupPosition * p->lastLength );
227
228}
229
230// Set the stretch "factor" of the string (0.0 - 1.0).
231void tStifKarp_setStretch (tStifKarp* const p, float stretch )
232{
233 p->stretching = stretch;
234 float coefficient;
235 float freq = p->lastFrequency * 2.0f;
236 float dFreq = ( (0.5f * leaf.sampleRate) - freq ) * 0.25f;
237 float temp = 0.5f + (stretch * 0.5f);
238 if ( temp > 0.9999f ) temp = 0.9999f;
239
240 for ( int i=0; i<4; i++ )
241 {
242 coefficient = temp * temp;
243 tBiQuad_setA2(p->biquad[i], coefficient);
244 tBiQuad_setB0(p->biquad[i], coefficient);
245 tBiQuad_setB2(p->biquad[i], 1.0f);
246
247 coefficient = -2.0f * temp * cos(TWO_PI * freq / leaf.sampleRate);
248 tBiQuad_setA1(p->biquad[i], coefficient);
249 tBiQuad_setB1(p->biquad[i], coefficient);
250
251 freq += dFreq;
252 }
253}
254
255// Set the pluck or "excitation" position along the string (0.0 - 1.0).
256void tStifKarp_setPickupPosition (tStifKarp* const p, float position )
257{
258 if (position < 0.0f) p->pickupPosition = 0.0f;
259 else if (position <= 1.0f) p->pickupPosition = position;
260 else p->pickupPosition = 1.0f;
261
262 tDelayL_setDelay(p->combDelay, 0.5f * p->pickupPosition * p->lastLength);
263}
264
265// Set the base loop gain.
266void tStifKarp_setBaseLoopGain (tStifKarp* const p, float aGain )
267{
268 p->baseLoopGain = aGain;
269 p->loopGain = p->baseLoopGain + (p->lastFrequency * 0.000005f);
270 if ( p->loopGain > 0.99999f ) p->loopGain = 0.99999f;
271}
272
273// Perform the control change specified by \e number and \e value (0.0 - 128.0).
274void tStifKarp_controlChange (tStifKarp* const p, SKControlType type, float value)
275{
276 if ( value < 0.0f ) value = 0.0f;
277 else if (value > 128.0f) value = 128.0f;
278
279 float normalizedValue = value * INV_128;
280
281 if (type == SKPickPosition) // 4
282 tStifKarp_setPickupPosition( p, normalizedValue );
283 else if (type == SKStringDamping) // 11
284 tStifKarp_setBaseLoopGain( p, 0.97f + (normalizedValue * 0.03f) );
285 else if (type == SKDetune) // 1
286 tStifKarp_setStretch( p, 0.91f + (0.09f * (1.0f - normalizedValue)) );
287
288}
289
290void tStifKarpSampleRateChanged (tStifKarp* const c)
291{
292 tStifKarp_setFrequency(c, c->lastFrequency);
293 tStifKarp_setStretch(c, c->stretching);
294}

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