Showing the changes to LEAF/Src_cpp/leaf-vocoder.cpp (1 of 147 files). Show all
Unified · Split
| @@ -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 | |||