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
31void 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
41void tTalkbox_free(tTalkbox* const v)
42{
43 leaf_free(v);
44}
45
46void 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
73void 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
93void 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
128void 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
157float 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
212void 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
219void 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
233void 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
315float 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
378void 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