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 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
22+void 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+
41+float tPluck_getLastOut (tPluck *p)
42+{
43+ return p->lastOut;
44+}
45+
46+float 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+
51+void 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.;
65+void 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).
73+void 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.
82+void 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).
98+void tPluck_controlChange (tPluck* const p, int number, float value)
99+{
100+ return;
101+}
102+
103+void tPluckSampleRateChanged(tPluck* const p)
104+{
105+ //tPluckSetFrequency(p, p->lastFreq);
106+}
107+
108+/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tStifKarp ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
109+void 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+
142+void 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+
157+float tStifKarp_getLastOut (tStifKarp* const p)
158+{
159+ return p->lastOut;
160+}
161+
162+float 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+
179+void 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.;
195+void 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).
202+void 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.
211+void 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).
231+void 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).
256+void 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.
266+void 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).
274+void 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+
290+void 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