History

First commit.

mulshine committed 7 years ago

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

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

Unified · Split

LEAF/Src_cpp/leaf-vocoder.cpp+386−0
@@ -0,0 +1,386 @@
1+/*
2+ ==============================================================================
3+
4+ LEAFInstrument.c
5+ Created: 20 Jan 2017 12:01:54pm
6+ Author: Michael R Mulshine
7+
8+ ==============================================================================
9+*/
10+
11+#if _WIN32 || _WIN64
12+
13+#include "..\Inc\leaf-vocoder.h"
14+#include "..\leaf.h"
15+
16+#else
17+
18+#include "../Inc/leaf-vocoder.h"
19+#include "../leaf.h"
20+
21+#endif
22+
23+
24+
25+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
26+ *
27+ *
28+ *
29+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
30+
31+void tTalkbox_init(tTalkbox* const v)
32+{
33+ v->param[0] = 0.5f; //wet
34+ v->param[1] = 0.0f; //dry
35+ v->param[2] = 0; // Swap
36+ v->param[3] = 1.0f; //quality
37+
38+ tTalkbox_update(v);
39+}
40+
41+void tTalkbox_free(tTalkbox* const v)
42+{
43+ leaf_free(v);
44+}
45+
46+void tTalkbox_update(tTalkbox* const v) ///update internal parameters...
47+{
48+ float fs = leaf.sampleRate;
49+ if(fs < 8000.0f) fs = 8000.0f;
50+ if(fs > 96000.0f) fs = 96000.0f;
51+
52+ int32_t n = (int32_t)(0.01633f * fs);
53+ if(n > TALKBOX_BUFFER_LENGTH) n = TALKBOX_BUFFER_LENGTH;
54+
55+ //O = (VstInt32)(0.0005f * fs);
56+ v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * fs);
57+
58+ if(n != v->N) //recalc hanning window
59+ {
60+ v->N = n;
61+ float dp = TWO_PI / v->N;
62+ float p = 0.0f;
63+ for(n=0; n<v->N; n++)
64+ {
65+ v->window[n] = 0.5f - 0.5f * cosf(p);
66+ p += dp;
67+ }
68+ }
69+ v->wet = 0.5f * v->param[0] * v->param[0];
70+ v->dry = 2.0f * v->param[1] * v->param[1];
71+}
72+
73+void tTalkbox_suspend(tTalkbox* const v) ///clear any buffers...
74+{
75+ v->pos = v->K = 0;
76+ v->emphasis = 0.0f;
77+ v->FX = 0;
78+
79+ v->u0 = v->u1 = v->u2 = v->u3 = v->u4 = 0.0f;
80+ v->d0 = v->d1 = v->d2 = v->d3 = v->d4 = 0.0f;
81+
82+ for (int32_t i = 0; i < TALKBOX_BUFFER_LENGTH; i++)
83+ {
84+ v->buf0[i] = 0;
85+ v->buf1[i] = 0;
86+ v->car0[i] = 0;
87+ v->car1[i] = 0;
88+ }
89+}
90+
91+
92+#define ORD_MAX 100 // Was 50. Increasing this gets rid of glitchiness, lowering it breaks it; not sure how it affects performance
93+void tTalkbox_lpc(float *buf, float *car, int32_t n, int32_t o)
94+{
95+ float z[ORD_MAX], r[ORD_MAX], k[ORD_MAX], G, x;
96+ int32_t i, j, nn=n;
97+
98+ for(j=0; j<=o; j++, nn--) //buf[] is already emphasized and windowed
99+ {
100+ z[j] = r[j] = 0.0f;
101+ for(i=0; i<nn; i++) r[j] += buf[i] * buf[i+j]; //autocorrelation
102+ }
103+ r[0] *= 1.001f; //stability fix
104+
105+ float min = 0.00001f;
106+ if(r[0] < min) { for(i=0; i<n; i++) buf[i] = 0.0f; return; }
107+
108+ tTalkbox_lpcDurbin(r, o, k, &G); //calc reflection coeffs
109+
110+ for(i=0; i<=o; i++)
111+ {
112+ if(k[i] > 0.995f) k[i] = 0.995f; else if(k[i] < -0.995f) k[i] = -.995f;
113+ }
114+
115+ for(i=0; i<n; i++)
116+ {
117+ x = G * car[i];
118+ for(j=o; j>0; j--) //lattice filter
119+ {
120+ x -= k[j] * z[j-1];
121+ z[j] = z[j-1] + k[j] * x;
122+ }
123+ buf[i] = z[0] = x; //output buf[] will be windowed elsewhere
124+ }
125+}
126+
127+
128+void tTalkbox_lpcDurbin(float *r, int p, float *k, float *g)
129+{
130+ int i, j;
131+ float a[ORD_MAX], at[ORD_MAX], e=r[0];
132+
133+ for(i=0; i<=p; i++) a[i] = at[i] = 0.0f; //probably don't need to clear at[] or k[]
134+
135+ for(i=1; i<=p; i++)
136+ {
137+ k[i] = -r[i];
138+
139+ for(j=1; j<i; j++)
140+ {
141+ at[j] = a[j];
142+ k[i] -= a[j] * r[i-j];
143+ }
144+ if(fabs(e) < 1.0e-20f) { e = 0.0f; break; }
145+ k[i] /= e; // This might be costing us
146+
147+ a[i] = k[i];
148+ for(j=1; j<i; j++) a[j] = at[j] + k[i] * at[i-j];
149+
150+ e *= 1.0f - k[i] * k[i];
151+ }
152+
153+ if(e < 1.0e-20f) e = 0.0f;
154+ *g = sqrtf(e);
155+}
156+
157+float tTalkbox_tick(tTalkbox* const v, float synth, float voice)
158+{
159+
160+ int32_t p0=v->pos, p1 = (v->pos + v->N/2) % v->N;
161+ float e=v->emphasis, w, o, x, dr, fx=v->FX;
162+ float p, q, h0=0.3f, h1=0.77f;
163+
164+ o = voice;
165+ x = synth;
166+
167+ dr = o;
168+
169+ p = v->d0 + h0 * x; v->d0 = v->d1; v->d1 = x - h0 * p;
170+ q = v->d2 + h1 * v->d4; v->d2 = v->d3; v->d3 = v->d4 - h1 * q;
171+ v->d4 = x;
172+ x = p + q;
173+
174+ if(v->K++)
175+ {
176+ v->K = 0;
177+
178+ v->car0[p0] = v->car1[p1] = x; //carrier input
179+
180+ x = o - e; e = o; //6dB/oct pre-emphasis
181+
182+ w = v->window[p0]; fx = v->buf0[p0] * w; v->buf0[p0] = x * w; //50% overlapping hanning windows
183+ if(++p0 >= v->N) { tTalkbox_lpc(v->buf0, v->car0, v->N, v->O); p0 = 0; }
184+
185+ w = 1.0f - w; fx += v->buf1[p1] * w; v->buf1[p1] = x * w;
186+ if(++p1 >= v->N) { tTalkbox_lpc(v->buf1, v->car1, v->N, v->O); p1 = 0; }
187+ }
188+
189+ p = v->u0 + h0 * fx; v->u0 = v->u1; v->u1 = fx - h0 * p;
190+ q = v->u2 + h1 * v->u4; v->u2 = v->u3; v->u3 = v->u4 - h1 * q;
191+ v->u4 = fx;
192+ x = p + q;
193+
194+ o = x;
195+
196+ v->emphasis = e;
197+ v->pos = p0;
198+ v->FX = fx;
199+
200+ float den = 1.0e-10f; //(float)pow(10.0f, -10.0f * param[4]);
201+ if(fabs(v->d0) < den) v->d0 = 0.0f; //anti-denormal (doesn't seem necessary but P4?)
202+ if(fabs(v->d1) < den) v->d1 = 0.0f;
203+ if(fabs(v->d2) < den) v->d2 = 0.0f;
204+ if(fabs(v->d3) < den) v->d3 = 0.0f;
205+ if(fabs(v->u0) < den) v->u0 = 0.0f;
206+ if(fabs(v->u1) < den) v->u1 = 0.0f;
207+ if(fabs(v->u2) < den) v->u2 = 0.0f;
208+ if(fabs(v->u3) < den) v->u3 = 0.0f;
209+ return o;
210+}
211+
212+void tTalkbox_setQuality(tTalkbox* const v, float quality)
213+{
214+ v->param[3] = quality;
215+ v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * leaf.sampleRate);
216+}
217+
218+
219+void tVocoder_init (tVocoder* const v)
220+{
221+ v->param[0] = 0.33f; //input select
222+ v->param[1] = 0.50f; //output dB
223+ v->param[2] = 0.40f; //hi thru
224+ v->param[3] = 0.40f; //hi band
225+ v->param[4] = 0.16f; //envelope
226+ v->param[5] = 0.55f; //filter q
227+ v->param[6] = 0.6667f;//freq range
228+ v->param[7] = 0.33f; //num bands
229+
230+ tVocoder_update(v);
231+}
232+
233+void tVocoder_update (tVocoder* const v)
234+{
235+ float tpofs = 6.2831853f * leaf.invSampleRate;
236+
237+ float rr, th, re;
238+
239+ float sh;
240+
241+ int32_t i;
242+
243+ v->gain = (float)pow(10.0f, 2.0f * v->param[1] - 3.0f * v->param[5] - 2.0f);
244+
245+ v->thru = (float)pow(10.0f, 0.5f + 2.0f * v->param[1]);
246+ v->high = v->param[3] * v->param[3] * v->param[3] * v->thru;
247+ v->thru *= v->param[2] * v->param[2] * v->param[2];
248+
249+ if(v->param[7]<0.5f)
250+ {
251+ v->nbnd=8;
252+ re=0.003f;
253+ v->f[1][2] = 3000.0f;
254+ v->f[2][2] = 2200.0f;
255+ v->f[3][2] = 1500.0f;
256+ v->f[4][2] = 1080.0f;
257+ v->f[5][2] = 700.0f;
258+ v->f[6][2] = 390.0f;
259+ v->f[7][2] = 190.0f;
260+ }
261+ else
262+ {
263+ v->nbnd=16;
264+ re=0.0015f;
265+ v->f[ 1][2] = 5000.0f; //+1000
266+ v->f[ 2][2] = 4000.0f; //+750
267+ v->f[ 3][2] = 3250.0f; //+500
268+ v->f[ 4][2] = 2750.0f; //+450
269+ v->f[ 5][2] = 2300.0f; //+300
270+ v->f[ 6][2] = 2000.0f; //+250
271+ v->f[ 7][2] = 1750.0f; //+250
272+ v->f[ 8][2] = 1500.0f; //+250
273+ v->f[ 9][2] = 1250.0f; //+250
274+ v->f[10][2] = 1000.0f; //+250
275+ v->f[11][2] = 750.0f; //+210
276+ v->f[12][2] = 540.0f; //+190
277+ v->f[13][2] = 350.0f; //+155
278+ v->f[14][2] = 195.0f; //+100
279+ v->f[15][2] = 95.0f;
280+ }
281+
282+ if(v->param[4]<0.05f) //freeze
283+ {
284+ for(i=0;i<v->nbnd;i++) v->f[i][12]=0.0f;
285+ }
286+ else
287+ {
288+ v->f[0][12] = (float)pow(10.0, -1.7 - 2.7f * v->param[4]); //envelope speed
289+
290+ rr = 0.022f / (float)v->nbnd; //minimum proportional to frequency to stop distortion
291+ for(i=1;i<v->nbnd;i++)
292+ {
293+ v->f[i][12] = (float)(0.025 - rr * (double)i);
294+ if(v->f[0][12] < v->f[i][12]) v->f[i][12] = v->f[0][12];
295+ }
296+ v->f[0][12] = 0.5f * v->f[0][12]; //only top band is at full rate
297+ }
298+
299+ rr = 1.0 - pow(10.0f, -1.0f - 1.2f * v->param[5]);
300+ sh = (float)pow(2.0f, 3.0f * v->param[6] - 1.0f); //filter bank range shift
301+
302+ for(i=1;i<v->nbnd;i++)
303+ {
304+ v->f[i][2] *= sh;
305+ th = acos((2.0 * rr * cos(tpofs * v->f[i][2])) / (1.0 + rr * rr));
306+ v->f[i][0] = (float)(2.0 * rr * cos(th)); //a0
307+ v->f[i][1] = (float)(-rr * rr); //a1
308+ //was .98
309+ v->f[i][2] *= 0.96f; //shift 2nd stage slightly to stop high resonance peaks
310+ th = acos((2.0 * rr * cos(tpofs * v->f[i][2])) / (1.0 + rr * rr));
311+ v->f[i][2] = (float)(2.0 * rr * cos(th));
312+ }
313+}
314+
315+float tVocoder_tick (tVocoder* const v, float synth, float voice)
316+{
317+ float a, b, o=0.0f, aa, bb, oo = v->kout, g = v->gain, ht = v->thru, hh = v->high, tmp;
318+ uint32_t i, k = v->kval, nb = v->nbnd;
319+
320+ a = voice; //speech
321+ b = synth; //synth
322+
323+ tmp = a - v->f[0][7]; //integrate modulator for HF band and filter bank pre-emphasis
324+ v->f[0][7] = a;
325+ a = tmp;
326+
327+ if(tmp<0.0f) tmp = -tmp;
328+ v->f[0][11] -= v->f[0][12] * (v->f[0][11] - tmp); //high band envelope
329+ o = v->f[0][11] * (ht * a + hh * (b - v->f[0][3])); //high band + high thru
330+
331+ v->f[0][3] = b; //integrate carrier for HF band
332+
333+ if(++k & 0x1) //this block runs at half sample rate
334+ {
335+ oo = 0.0f;
336+ aa = a + v->f[0][9] - v->f[0][8] - v->f[0][8]; //apply zeros here instead of in each reson
337+ v->f[0][9] = v->f[0][8]; v->f[0][8] = a;
338+ bb = b + v->f[0][5] - v->f[0][4] - v->f[0][4];
339+ v->f[0][5] = v->f[0][4]; v->f[0][4] = b;
340+
341+ for(i=1; i<nb; i++) //filter bank: 4th-order band pass
342+ {
343+ tmp = v->f[i][0] * v->f[i][3] + v->f[i][1] * v->f[i][4] + bb;
344+ v->f[i][4] = v->f[i][3];
345+ v->f[i][3] = tmp;
346+ tmp += v->f[i][2] * v->f[i][5] + v->f[i][1] * v->f[i][6];
347+ v->f[i][6] = v->f[i][5];
348+ v->f[i][5] = tmp;
349+
350+ tmp = v->f[i][0] * v->f[i][7] + v->f[i][1] * v->f[i][8] + aa;
351+ v->f[i][8] = v->f[i][7];
352+ v->f[i][7] = tmp;
353+ tmp += v->f[i][2] * v->f[i][9] + v->f[i][1] * v->f[i][10];
354+ v->f[i][10] = v->f[i][9];
355+ v->f[i][9] = tmp;
356+
357+ if(tmp<0.0f) tmp = -tmp;
358+ v->f[i][11] -= v->f[i][12] * (v->f[i][11] - tmp);
359+ oo += v->f[i][5] * v->f[i][11];
360+ }
361+ }
362+ o += oo * g; //effect of interpolating back up to Fs would be minimal (aliasing >16kHz)
363+
364+ v->kout = oo;
365+ v->kval = k & 0x1;
366+ if(fabs(v->f[0][11])<1.0e-10) v->f[0][11] = 0.0f; //catch HF envelope denormal
367+
368+ for(i=1;i<nb;i++)
369+ if(fabs(v->f[i][3])<1.0e-10 || fabs(v->f[i][7])<1.0e-10)
370+ for(k=3; k<12; k++) v->f[i][k] = 0.0f; //catch reson & envelope denormals
371+
372+ if(fabs(o)>10.0f) tVocoder_suspend(v); //catch instability
373+
374+ return o;
375+
376+}
377+
378+void tVocoder_suspend (tVocoder* const v)
379+{
380+ int32_t i, j;
381+
382+ for(i=0; i<v->nbnd; i++) for(j=3; j<12; j++) v->f[i][j] = 0.0f; //zero band filters and envelopes
383+ v->kout = 0.0f;
384+ v->kval = 0;
385+}
386+

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