| @@ -25,6 +25,13 @@ · 24 unmodified lines |
| 25 | 25 | //============================================================================================================ |
| 26 | 26 | |
| 27 | 27 | //LPC vocoder adapted from MDA's excellent open source talkbox plugin code |
| 28 | + |
| 29 | +#define ORD_MAX 34 // Was 100. |
| 30 | +// order is defined by the set_quality function. |
| 31 | +// it's set to max out at 0.0005 of sample rate (if you don't go above 1.0f in the quality setting) == at 48000 that's 24. |
| 32 | +// -JS |
| 33 | + |
| 34 | + |
| 28 | 35 | void tTalkbox_init(tTalkbox* const voc, int bufsize) |
| 29 | 36 | { |
| 30 | 37 | tTalkbox_initToPool(voc, bufsize, &leaf.mempool); |
| @@ -47,7 +54,8 @@ void tTalkbox_initToPool (tTalkbox* const voc, int bufsize, tMempool* con · 16 unmodified lines |
| 47 | 54 | v->warpFactor = 0.0f; |
| 48 | 55 | v->warpOn = 0; |
| 49 | 56 | v->bufsize = bufsize; |
| 50 | | − |
| 57 | + v->freeze = 0; |
| 58 | + v->G = 0.0f; |
| 51 | 59 | v->car0 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m); |
| 52 | 60 | v->car1 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m); |
| 53 | 61 | v->window = (float*) mpool_alloc(sizeof(float) * v->bufsize, m); |
| @@ -56,7 +64,9 @@ void tTalkbox_initToPool (tTalkbox* const voc, int bufsize, tMempool* con · 2 unmodified lines |
| 56 | 64 | |
| 57 | 65 | v->dl = (double*) mpool_alloc(sizeof(double) * v->bufsize, m); |
| 58 | 66 | v->Rt = (double*) mpool_alloc(sizeof(double) * v->bufsize, m); |
| 59 | | − |
| 67 | + |
| 68 | + v->k = (float*) mpool_alloc(sizeof(float) * ORD_MAX, m); |
| 69 | + |
| 60 | 70 | tTalkbox_update(voc); |
| 61 | 71 | tTalkbox_suspend(voc); |
| 62 | 72 | } |
| @@ -74,7 +84,7 @@ void tTalkbox_freeFromPool (tTalkbox* const voc, tMempool* const mp) · 11 unmodified lines |
| 74 | 84 | |
| 75 | 85 | mpool_free((char*)v->dl, m); |
| 76 | 86 | mpool_free((char*)v->Rt, m); |
| 77 | | − |
| 87 | + mpool_free((char*)v->k, m); |
| 78 | 88 | mpool_free((char*)v, m); |
| 79 | 89 | } |
| 80 | 90 | |
| @@ -132,89 +142,173 @@ void tTalkbox_suspend(tTalkbox* const voc) ///clear any buffers... · 51 unmodified lines |
| 132 | 142 | //wAutocorrelate(&pfSrc[stIndex],siglen,R,P,0); |
| 133 | 143 | void tTalkbox_warpedAutocorrelate(float * x, double* dl, double* Rt, unsigned int L, float * R, unsigned int P, float lambda) |
| 134 | 144 | { |
| 135 | | −// double dl[L]; |
| 136 | | −// double Rt[L]; |
| 137 | 145 | double r1,r2,r1t; |
| 138 | 146 | R[0]=0; |
| 139 | 147 | Rt[0]=0; |
| 140 | 148 | r1=0; |
| 141 | 149 | r2=0; |
| 142 | 150 | r1t=0; |
| 143 | | − for(int32_t k=0; k<L;k++) |
| 151 | + for(uint32_t m=0; m<L;m++) |
| 144 | 152 | { |
| 145 | | − Rt[0] += (double)(x[k]) * (double)(x[k]); |
| 153 | + Rt[0] += (double)(x[m]) * (double)(x[m]); |
| 146 | 154 | |
| 147 | | − dl[k]= r1 - (double)(lambda) * (double)(x[k]-r2); |
| 148 | | − r1 = x[k]; |
| 149 | | − r2 = dl[k]; |
| 155 | + dl[m]= r1 - (double)(lambda) * (double)(x[m]-r2); |
| 156 | + r1 = x[m]; |
| 157 | + r2 = dl[m]; |
| 150 | 158 | } |
| 151 | | − for(int32_t i=1; i<=P; i++) |
| 159 | + for(uint32_t i=1; i<=P; i++) |
| 152 | 160 | { |
| 153 | 161 | Rt[i]=0; |
| 154 | 162 | r1=0; |
| 155 | 163 | r2=0; |
| 156 | | − for(unsigned int k=0; k<L;k++) |
| 164 | + for(unsigned int m=0; m<L;m++) |
| 157 | 165 | { |
| 158 | | − Rt[i] += (double) (dl[k]) * (double)(x[k]); |
| 166 | + Rt[i] += (double) (dl[m]) * (double)(x[m]); |
| 159 | 167 | |
| 160 | | − r1t = dl[k]; |
| 161 | | − dl[k]= r1 - (double)(lambda) * (double)(r1t-r2); |
| 168 | + r1t = dl[m]; |
| 169 | + dl[m]= r1 - (double)(lambda) * (double)(r1t-r2); |
| 162 | 170 | r1 = r1t; |
| 163 | | − r2 = dl[k]; |
| 171 | + r2 = dl[m]; |
| 164 | 172 | } |
| 165 | 173 | } |
| 166 | | − for(int32_t i=0; i<=P; i++) |
| 174 | + for(uint32_t i=0; i<=P; i++) |
| 167 | 175 | { |
| 168 | 176 | R[i]=(float)(Rt[i]); |
| 169 | 177 | } |
| 170 | 178 | |
| 171 | 179 | } |
| 172 | 180 | |
| 173 | | − |
| 174 | | − |
| 175 | | −#define ORD_MAX 35 // Was 100. |
| 176 | | −// order is defined by the set_quality function. |
| 177 | | −// it's set to max out at 0.0005 of sample rate (if you don't go above 1.0f in the quality setting) == at 48000 that's 24. |
| 178 | | −// -JS |
| 179 | | −void tTalkbox_lpc(float *buf, float *car, double* dl, double* Rt, int32_t n, int32_t o, float warp, int warpOn) |
| 181 | +void tTalkbox_lpcDurbin(float *r, int p, float *k, float *g) |
| 180 | 182 | { |
| 181 | | − float z[ORD_MAX], r[ORD_MAX], k[ORD_MAX], G, x; |
| 182 | | − int32_t i, j, nn=n; |
| 183 | | − |
| 184 | | − if (warpOn == 0) |
| 183 | + int i, j; |
| 184 | + float a[ORD_MAX], at[ORD_MAX], e=r[0]; |
| 185 | + |
| 186 | + for(i=0; i<=p; i++) |
| 185 | 187 | { |
| 186 | | − for(j=0; j<=o; j++, nn--) //buf[] is already emphasized and windowed |
| 187 | | − { |
| 188 | | − z[j] = r[j] = 0.0f; |
| 189 | | − for(i=0; i<nn; i++) r[j] += buf[i] * buf[i+j]; //autocorrelation |
| 190 | | − } |
| 188 | + a[i] = 0.0f; //probably don't need to clear at[] or k[] |
| 191 | 189 | } |
| 192 | | − else |
| 190 | + k[0] = 0.0f; |
| 191 | + at[0] = 0.0f; |
| 192 | + for(i=1; i<=p; i++) |
| 193 | 193 | { |
| 194 | | − for(j=0; j<=o; j++, nn--) //buf[] is already emphasized and windowed |
| 194 | + k[i] = -r[i]; |
| 195 | + |
| 196 | + for(j=1; j<i; j++) |
| 195 | 197 | { |
| 196 | | − z[j] = r[j] = 0.0f; |
| 198 | + at[j] = a[j]; |
| 199 | + k[i] -= a[j] * r[i-j]; |
| 197 | 200 | } |
| 198 | | − tTalkbox_warpedAutocorrelate(buf, dl, Rt, n, r, o, warp); |
| 201 | + if(fabs(e) < 1.0e-20f) { e = 0.0f; break; } |
| 202 | + k[i] /= e; |
| 203 | + |
| 204 | + a[i] = k[i]; |
| 205 | + for(j=1; j<i; j++) a[j] = at[j] + k[i] * at[i-j]; |
| 206 | + |
| 207 | + e *= 1.0f - k[i] * k[i]; |
| 199 | 208 | } |
| 200 | 209 | |
| 201 | | − r[0] *= 1.001f; //stability fix |
| 210 | + if(e < 1.0e-20f) e = 0.0f; |
| 211 | + *g = sqrtf(e); |
| 212 | +} |
| 213 | + |
| 214 | +float tTalkbox_tick(tTalkbox* const voc, float synth, float voice) |
| 215 | +{ |
| 216 | + _tTalkbox* v = *voc; |
| 202 | 217 | |
| 203 | | − float min = 0.00001f; |
| 204 | | − if(r[0] < min) { for(i=0; i<n; i++) buf[i] = 0.0f; return; } |
| 218 | + int32_t p0=v->pos, p1 = (v->pos + v->N/2) % v->N; |
| 219 | + float e=v->emphasis, w, o, x, fx=v->FX; |
| 220 | + float p, q, h0=0.3f, h1=0.77f; |
| 205 | 221 | |
| 206 | | − tTalkbox_lpcDurbin(r, o, k, &G); //calc reflection coeffs |
| 222 | + o = voice; |
| 223 | + x = synth; |
| 224 | + |
| 225 | + |
| 226 | + |
| 227 | + p = v->d0 + h0 * x; v->d0 = v->d1; v->d1 = x - h0 * p; |
| 228 | + q = v->d2 + h1 * v->d4; v->d2 = v->d3; v->d3 = v->d4 - h1 * q; |
| 229 | + v->d4 = x; |
| 230 | + x = p + q; |
| 207 | 231 | |
| 208 | | − //this is for stability to keep reflection coefficients inside the unit circle |
| 209 | | − //but in Harma's papers I've seen 0.998. just needs to be less than 1 it seems but maybe some wiggle room to avoid instability from floating point precision -JS |
| 210 | | − for(i=0; i<=o; i++) |
| 232 | + if(v->K++) |
| 211 | 233 | { |
| 212 | | − if(k[i] > 0.995f) k[i] = 0.995f; else if(k[i] < -0.995f) k[i] = -.995f; |
| 234 | + v->K = 0; |
| 235 | + |
| 236 | + v->car0[p0] = v->car1[p1] = x; //carrier input |
| 237 | + |
| 238 | + x = o - e; e = o; //6dB/oct pre-emphasis |
| 239 | + |
| 240 | + w = v->window[p0]; fx = v->buf0[p0] * w; v->buf0[p0] = x * w; //50% overlapping hanning windows |
| 241 | + if(++p0 >= v->N) { tTalkbox_lpc(v->buf0, v->car0, v->dl, v->Rt, v->N, v->O, v->warpFactor, v->warpOn, v->k, v->freeze, &v->G); p0 = 0; } |
| 242 | + |
| 243 | + w = 1.0f - w; fx += v->buf1[p1] * w; v->buf1[p1] = x * w; |
| 244 | + if(++p1 >= v->N) { tTalkbox_lpc(v->buf1, v->car1, v->dl, v->Rt, v->N, v->O, v->warpFactor, v->warpOn, v->k, v->freeze, &v->G); p1 = 0; } |
| 213 | 245 | } |
| 214 | 246 | |
| 247 | + p = v->u0 + h0 * fx; v->u0 = v->u1; v->u1 = fx - h0 * p; |
| 248 | + q = v->u2 + h1 * v->u4; v->u2 = v->u3; v->u3 = v->u4 - h1 * q; |
| 249 | + v->u4 = fx; |
| 250 | + x = p + q; |
| 251 | + |
| 252 | + o = x; |
| 253 | + |
| 254 | + v->emphasis = e; |
| 255 | + v->pos = p0; |
| 256 | + v->FX = fx; |
| 257 | + |
| 258 | + |
| 259 | + return o; |
| 260 | +} |
| 261 | + |
| 262 | + |
| 263 | +void tTalkbox_lpc(float *buf, float *car, double* dl, double* Rt, int32_t n, int32_t o, float warp, int warpOn, float *k, int freeze, float *G) |
| 264 | +{ |
| 265 | + float z[ORD_MAX], r[ORD_MAX], x; |
| 266 | + int32_t i, j, nn=n; |
| 267 | + |
| 268 | + |
| 269 | + if (warpOn == 0) |
| 270 | + { |
| 271 | + for(j=0; j<=o; j++, nn--) //buf[] is already emphasized and windowed |
| 272 | + { |
| 273 | + z[j] = r[j] = 0.0f; |
| 274 | + for(i=0; i<nn; i++) r[j] += buf[i] * buf[i+j]; //autocorrelation |
| 275 | + } |
| 276 | + } |
| 277 | + else |
| 278 | + { |
| 279 | + for(j=0; j<=o; j++, nn--) //buf[] is already emphasized and windowed |
| 280 | + { |
| 281 | + z[j] = r[j] = 0.0f; |
| 282 | + } |
| 283 | + tTalkbox_warpedAutocorrelate(buf, dl, Rt, n, r, o, warp); |
| 284 | + } |
| 285 | + |
| 286 | + r[0] *= 1.001f; //stability fix |
| 287 | + |
| 288 | + float min = 0.000001f; |
| 289 | + if (!freeze) |
| 290 | + { |
| 291 | + if(r[0] < min) |
| 292 | + { |
| 293 | + for(i=0; i<n; i++) |
| 294 | + { |
| 295 | + buf[i] = 0.0f; |
| 296 | + return; |
| 297 | + } |
| 298 | + } |
| 299 | + |
| 300 | + tTalkbox_lpcDurbin(r, o, k, G); //calc reflection coeffs |
| 301 | + |
| 302 | + //this is for stability to keep reflection coefficients inside the unit circle |
| 303 | + //in mda's code it's .995 but in Harma's papers I've seen 0.998. just needs to be less than 1 it seems but maybe some wiggle room to avoid instability from floating point precision -JS |
| 304 | + for(i=0; i<=o; i++) |
| 305 | + { |
| 306 | + if(k[i] > 0.998f) k[i] = 0.998f; else if(k[i] < -0.998f) k[i] = -.998f; |
| 307 | + } |
| 308 | + } |
| 215 | 309 | for(i=0; i<n; i++) |
| 216 | 310 | { |
| 217 | | − x = G * car[i]; |
| 311 | + x = G[0] * car[i]; |
| 218 | 312 | for(j=o; j>0; j--) //lattice filter |
| 219 | 313 | { |
| 220 | 314 | x -= k[j] * z[j-1]; |
| @@ -224,18 +318,213 @@ void tTalkbox_lpc(float *buf, float *car, double* dl, double* Rt, int32_t n, int · 3 unmodified lines |
| 224 | 318 | } |
| 225 | 319 | } |
| 226 | 320 | |
| 321 | +void tTalkbox_setQuality(tTalkbox* const voc, float quality) |
| 322 | +{ |
| 323 | + _tTalkbox* v = *voc; |
| 324 | + v->param[3] = quality; |
| 325 | + v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * leaf.sampleRate); |
| 326 | + if (v->O >= ORD_MAX) |
| 327 | + { |
| 328 | + v->O = ORD_MAX-1; |
| 329 | + } |
| 330 | +} |
| 227 | 331 | |
| 228 | | −void tTalkbox_lpcDurbin(float *r, int p, float *k, float *g) |
| 332 | +void tTalkbox_setWarpFactor(tTalkbox* const voc, float warpFactor) |
| 333 | +{ |
| 334 | + _tTalkbox* v = *voc; |
| 335 | + |
| 336 | + v->warpFactor = warpFactor; |
| 337 | +} |
| 338 | + |
| 339 | +void tTalkbox_setWarpOn(tTalkbox* const voc, float warpOn) |
| 340 | +{ |
| 341 | + _tTalkbox* v = *voc; |
| 342 | + |
| 343 | + v->warpOn = warpOn; |
| 344 | +} |
| 345 | + |
| 346 | +void tTalkbox_setFreeze(tTalkbox* const voc, float freeze) |
| 347 | +{ |
| 348 | + _tTalkbox* v = *voc; |
| 349 | + |
| 350 | + v->freeze = freeze; |
| 351 | +} |
| 352 | + |
| 353 | + |
| 354 | + |
| 355 | +//// |
| 356 | + |
| 357 | +// LPC vocoder adapted from MDA's excellent open source talkbox plugin code |
| 358 | +// order is defined by the set_quality function. |
| 359 | +// it's set to max out at 0.0005 of sample rate (if you don't go above 1.0f in the quality setting) == at 48000 that's 24. |
| 360 | + |
| 361 | +//the "float" version has no double calculations for faster computation on single-precision FPUs |
| 362 | + |
| 363 | +// -JS |
| 364 | + |
| 365 | + |
| 366 | +void tTalkboxFloat_init(tTalkboxFloat* const voc, int bufsize) |
| 367 | +{ |
| 368 | + tTalkboxFloat_initToPool(voc, bufsize, &leaf.mempool); |
| 369 | +} |
| 370 | + |
| 371 | +void tTalkboFloat_free(tTalkboxFloat* const voc) |
| 372 | +{ |
| 373 | + tTalkboxFloat_freeFromPool(voc, &leaf.mempool); |
| 374 | +} |
| 375 | + |
| 376 | +void tTalkboxFloat_initToPool (tTalkboxFloat* const voc, int bufsize, tMempool* const mp) |
| 377 | +{ |
| 378 | + _tMempool* m = *mp; |
| 379 | + _tTalkboxFloat* v = *voc = (_tTalkboxFloat*) mpool_alloc(sizeof(_tTalkboxFloat), m); |
| 380 | + |
| 381 | + v->param[0] = 0.5f; //wet |
| 382 | + v->param[1] = 0.0f; //dry |
| 383 | + v->param[2] = 0; // Swap |
| 384 | + v->param[3] = 1.0f; //quality |
| 385 | + v->warpFactor = 0.0f; |
| 386 | + v->warpOn = 0; |
| 387 | + v->bufsize = bufsize; |
| 388 | + v->freeze = 0; |
| 389 | + v->G = 0.0f; |
| 390 | + v->car0 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m); |
| 391 | + v->car1 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m); |
| 392 | + v->window = (float*) mpool_alloc(sizeof(float) * v->bufsize, m); |
| 393 | + v->buf0 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m); |
| 394 | + v->buf1 = (float*) mpool_alloc(sizeof(float) * v->bufsize, m); |
| 395 | + |
| 396 | + v->dl = (float*) mpool_alloc(sizeof(float) * v->bufsize, m); |
| 397 | + v->Rt = (float*) mpool_alloc(sizeof(float) * v->bufsize, m); |
| 398 | + |
| 399 | + v->k = (float*) mpool_alloc(sizeof(float) * ORD_MAX, m); |
| 400 | + |
| 401 | + tTalkboxFloat_update(voc); |
| 402 | + tTalkboxFloat_suspend(voc); |
| 403 | +} |
| 404 | + |
| 405 | +void tTalkboxFloat_freeFromPool (tTalkboxFloat* const voc, tMempool* const mp) |
| 406 | +{ |
| 407 | + _tMempool* m = *mp; |
| 408 | + _tTalkboxFloat* v = *voc; |
| 409 | + |
| 410 | + mpool_free((char*)v->buf1, m); |
| 411 | + mpool_free((char*)v->buf0, m); |
| 412 | + mpool_free((char*)v->window, m); |
| 413 | + mpool_free((char*)v->car1, m); |
| 414 | + mpool_free((char*)v->car0, m); |
| 415 | + |
| 416 | + mpool_free((char*)v->dl, m); |
| 417 | + mpool_free((char*)v->Rt, m); |
| 418 | + mpool_free((char*)v->k, m); |
| 419 | + mpool_free((char*)v, m); |
| 420 | +} |
| 421 | + |
| 422 | +void tTalkboxFloat_update(tTalkboxFloat* const voc) ///update internal parameters... |
| 423 | +{ |
| 424 | + _tTalkboxFloat* v = *voc; |
| 425 | + |
| 426 | + float fs = leaf.sampleRate; |
| 427 | + if(fs < 8000.0f) fs = 8000.0f; |
| 428 | + if(fs > 96000.0f) fs = 96000.0f; |
| 429 | + |
| 430 | + int32_t n = (int32_t)(0.01633f * fs); //this sets the window time to 16ms if the buffer is large enough. Buffer needs to be at least 784 samples at 48000 |
| 431 | + if(n > v->bufsize) n = v->bufsize; |
| 432 | + |
| 433 | + //O = (VstInt32)(0.0005f * fs); |
| 434 | + v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * fs); |
| 435 | + |
| 436 | + if(n != v->N) //recalc hanning window |
| 437 | + { |
| 438 | + v->N = n; |
| 439 | + float dp = TWO_PI / v->N; |
| 440 | + float p = 0.0f; |
| 441 | + for(n=0; n<v->N; n++) |
| 442 | + { |
| 443 | + v->window[n] = 0.5f - 0.5f * cosf(p); |
| 444 | + p += dp; |
| 445 | + } |
| 446 | + } |
| 447 | + v->wet = 0.5f * v->param[0] * v->param[0]; |
| 448 | + v->dry = 2.0f * v->param[1] * v->param[1]; |
| 449 | +} |
| 450 | + |
| 451 | +void tTalkboxFloat_suspend(tTalkboxFloat* const voc) ///clear any buffers... |
| 452 | +{ |
| 453 | + _tTalkboxFloat* v = *voc; |
| 454 | + |
| 455 | + v->pos = v->K = 0; |
| 456 | + v->emphasis = 0.0f; |
| 457 | + v->FX = 0; |
| 458 | + |
| 459 | + v->u0 = v->u1 = v->u2 = v->u3 = v->u4 = 0.0f; |
| 460 | + v->d0 = v->d1 = v->d2 = v->d3 = v->d4 = 0.0f; |
| 461 | + |
| 462 | + for (int32_t i = 0; i < v->bufsize; i++) |
| 463 | + { |
| 464 | + v->buf0[i] = 0; |
| 465 | + v->buf1[i] = 0; |
| 466 | + v->car0[i] = 0; |
| 467 | + v->car1[i] = 0; |
| 468 | + } |
| 469 | +} |
| 470 | + |
| 471 | +// warped autocorrelation adapted from ten.enegatum@liam's post on music-dsp 2004-04-07 09:37:51 |
| 472 | +//find the order-P autocorrelation array, R, for the sequence x of length L and warping of lambda |
| 473 | +//wAutocorrelate(&pfSrc[stIndex],siglen,R,P,0); |
| 474 | +void tTalkboxFloat_warpedAutocorrelate(float * x, float* dl, float* Rt, unsigned int L, float * R, unsigned int P, float lambda) |
| 475 | +{ |
| 476 | + float r1,r2,r1t; |
| 477 | + R[0]=0; |
| 478 | + Rt[0]=0; |
| 479 | + r1=0; |
| 480 | + r2=0; |
| 481 | + r1t=0; |
| 482 | + for(uint32_t m=0; m<L;m++) |
| 483 | + { |
| 484 | + Rt[0] += (x[m]) * (x[m]); |
| 485 | + |
| 486 | + dl[m]= r1 - lambda * (x[m]-r2); |
| 487 | + r1 = x[m]; |
| 488 | + r2 = dl[m]; |
| 489 | + } |
| 490 | + for(uint32_t i=1; i<=P; i++) |
| 491 | + { |
| 492 | + Rt[i]=0; |
| 493 | + r1=0; |
| 494 | + r2=0; |
| 495 | + for(unsigned int m=0; m<L;m++) |
| 496 | + { |
| 497 | + Rt[i] += (dl[m]) * (x[m]); |
| 498 | + |
| 499 | + r1t = dl[m]; |
| 500 | + dl[m]= r1 - lambda * (r1t-r2); |
| 501 | + r1 = r1t; |
| 502 | + r2 = dl[m]; |
| 503 | + } |
| 504 | + } |
| 505 | + for(uint32_t i=0; i<=P; i++) |
| 506 | + { |
| 507 | + R[i]=Rt[i]; |
| 508 | + } |
| 509 | + |
| 510 | +} |
| 511 | + |
| 512 | +void tTalkboxFloat_lpcDurbin(float *r, int p, float *k, float *g) |
| 229 | 513 | { |
| 230 | 514 | int i, j; |
| 231 | 515 | float a[ORD_MAX], at[ORD_MAX], e=r[0]; |
| 232 | | − |
| 233 | | − for(i=0; i<=p; i++) a[i] = 0.0f; //probably don't need to clear at[] or k[] |
| 516 | + |
| 517 | + for(i=0; i<=p; i++) |
| 518 | + { |
| 519 | + a[i] = 0.0f; //probably don't need to clear at[] |
| 520 | + |
| 521 | + } |
| 522 | + k[0] = 0.0f; |
| 234 | 523 | at[0] = 0.0f; |
| 235 | 524 | for(i=1; i<=p; i++) |
| 236 | 525 | { |
| 237 | 526 | k[i] = -r[i]; |
| 238 | | − |
| 527 | + |
| 239 | 528 | for(j=1; j<i; j++) |
| 240 | 529 | { |
| 241 | 530 | at[j] = a[j]; |
| @@ -243,69 +532,127 @@ void tTalkbox_lpcDurbin(float *r, int p, float *k, float *g) · 1 unmodified line |
| 243 | 532 | } |
| 244 | 533 | if(fabs(e) < 1.0e-20f) { e = 0.0f; break; } |
| 245 | 534 | k[i] /= e; |
| 246 | | − |
| 535 | + |
| 247 | 536 | a[i] = k[i]; |
| 248 | 537 | for(j=1; j<i; j++) a[j] = at[j] + k[i] * at[i-j]; |
| 249 | | − |
| 538 | + |
| 250 | 539 | e *= 1.0f - k[i] * k[i]; |
| 251 | 540 | } |
| 252 | | − |
| 541 | + |
| 253 | 542 | if(e < 1.0e-20f) e = 0.0f; |
| 254 | 543 | *g = sqrtf(e); |
| 255 | 544 | } |
| 256 | 545 | |
| 257 | | −float tTalkbox_tick(tTalkbox* const voc, float synth, float voice) |
| 546 | +float tTalkboxFloat_tick(tTalkboxFloat* const voc, float synth, float voice) |
| 258 | 547 | { |
| 259 | | − _tTalkbox* v = *voc; |
| 260 | | − |
| 548 | + _tTalkboxFloat* v = *voc; |
| 549 | + |
| 261 | 550 | int32_t p0=v->pos, p1 = (v->pos + v->N/2) % v->N; |
| 262 | 551 | float e=v->emphasis, w, o, x, fx=v->FX; |
| 263 | 552 | float p, q, h0=0.3f, h1=0.77f; |
| 264 | | − |
| 553 | + |
| 265 | 554 | o = voice; |
| 266 | 555 | x = synth; |
| 267 | | − |
| 556 | + |
| 268 | 557 | |
| 269 | 558 | |
| 270 | 559 | p = v->d0 + h0 * x; v->d0 = v->d1; v->d1 = x - h0 * p; |
| 271 | 560 | q = v->d2 + h1 * v->d4; v->d2 = v->d3; v->d3 = v->d4 - h1 * q; |
| 272 | 561 | v->d4 = x; |
| 273 | 562 | x = p + q; |
| 274 | | − |
| 563 | + |
| 275 | 564 | if(v->K++) |
| 276 | 565 | { |
| 277 | 566 | v->K = 0; |
| 278 | | − |
| 567 | + |
| 279 | 568 | v->car0[p0] = v->car1[p1] = x; //carrier input |
| 280 | | − |
| 569 | + |
| 281 | 570 | x = o - e; e = o; //6dB/oct pre-emphasis |
| 282 | | − |
| 571 | + |
| 283 | 572 | w = v->window[p0]; fx = v->buf0[p0] * w; v->buf0[p0] = x * w; //50% overlapping hanning windows |
| 284 | | − if(++p0 >= v->N) { tTalkbox_lpc(v->buf0, v->car0, v->dl, v->Rt, v->N, v->O, v->warpFactor, v->warpOn); p0 = 0; } |
| 285 | | − |
| 573 | + if(++p0 >= v->N) { tTalkboxFloat_lpc(v->buf0, v->car0, v->dl, v->Rt, v->N, v->O, v->warpFactor, v->warpOn, v->k, v->freeze, &v->G); p0 = 0; } |
| 574 | + |
| 286 | 575 | w = 1.0f - w; fx += v->buf1[p1] * w; v->buf1[p1] = x * w; |
| 287 | | − if(++p1 >= v->N) { tTalkbox_lpc(v->buf1, v->car1, v->dl, v->Rt, v->N, v->O, v->warpFactor, v->warpOn); p1 = 0; } |
| 576 | + if(++p1 >= v->N) { tTalkboxFloat_lpc(v->buf1, v->car1, v->dl, v->Rt, v->N, v->O, v->warpFactor, v->warpOn, v->k, v->freeze, &v->G); p1 = 0; } |
| 288 | 577 | } |
| 289 | | − |
| 578 | + |
| 290 | 579 | p = v->u0 + h0 * fx; v->u0 = v->u1; v->u1 = fx - h0 * p; |
| 291 | 580 | q = v->u2 + h1 * v->u4; v->u2 = v->u3; v->u3 = v->u4 - h1 * q; |
| 292 | 581 | v->u4 = fx; |
| 293 | 582 | x = p + q; |
| 294 | | − |
| 583 | + |
| 295 | 584 | o = x; |
| 296 | | − |
| 585 | + |
| 297 | 586 | v->emphasis = e; |
| 298 | 587 | v->pos = p0; |
| 299 | 588 | v->FX = fx; |
| 300 | | − |
| 589 | + |
| 301 | 590 | |
| 302 | 591 | return o; |
| 303 | 592 | } |
| 304 | 593 | |
| 305 | | −void tTalkbox_setQuality(tTalkbox* const voc, float quality) |
| 594 | + |
| 595 | +void tTalkboxFloat_lpc(float *buf, float *car, float* dl, float* Rt, int32_t n, int32_t o, float warp, int warpOn, float *k, int freeze, float *G) |
| 306 | 596 | { |
| 307 | | − _tTalkbox* v = *voc; |
| 308 | | − |
| 597 | + float z[ORD_MAX], r[ORD_MAX], x; |
| 598 | + int32_t i, j, nn=n; |
| 599 | + |
| 600 | + |
| 601 | + if (warpOn == 0) |
| 602 | + { |
| 603 | + for(j=0; j<=o; j++, nn--) //buf[] is already emphasized and windowed |
| 604 | + { |
| 605 | + z[j] = r[j] = 0.0f; |
| 606 | + for(i=0; i<nn; i++) r[j] += buf[i] * buf[i+j]; //autocorrelation |
| 607 | + } |
| 608 | + } |
| 609 | + else |
| 610 | + { |
| 611 | + for(j=0; j<=o; j++, nn--) //buf[] is already emphasized and windowed |
| 612 | + { |
| 613 | + z[j] = r[j] = 0.0f; |
| 614 | + } |
| 615 | + tTalkboxFloat_warpedAutocorrelate(buf, dl, Rt, n, r, o, warp); |
| 616 | + } |
| 617 | + |
| 618 | + r[0] *= 1.001f; //stability fix |
| 619 | + |
| 620 | + float min = 0.000001f; |
| 621 | + if (!freeze) |
| 622 | + { |
| 623 | + if(r[0] < min) |
| 624 | + { |
| 625 | + for(i=0; i<n; i++) |
| 626 | + { |
| 627 | + buf[i] = 0.0f; |
| 628 | + return; |
| 629 | + } |
| 630 | + } |
| 631 | + |
| 632 | + tTalkbox_lpcDurbin(r, o, k, G); //calc reflection coeffs |
| 633 | + |
| 634 | + //this is for stability to keep reflection coefficients inside the unit circle |
| 635 | + //but in Harma's papers I've seen 0.998. just needs to be less than 1 it seems but maybe some wiggle room to avoid instability from floating point precision -JS |
| 636 | + for(i=0; i<=o; i++) |
| 637 | + { |
| 638 | + if(k[i] > 0.998f) k[i] = 0.998f; else if(k[i] < -0.998f) k[i] = -.998f; |
| 639 | + } |
| 640 | + } |
| 641 | + for(i=0; i<n; i++) |
| 642 | + { |
| 643 | + x = G[0] * car[i]; |
| 644 | + for(j=o; j>0; j--) //lattice filter |
| 645 | + { |
| 646 | + x -= k[j] * z[j-1]; |
| 647 | + z[j] = z[j-1] + k[j] * x; |
| 648 | + } |
| 649 | + buf[i] = z[0] = x; //output buf[] will be windowed elsewhere |
| 650 | + } |
| 651 | +} |
| 652 | + |
| 653 | +void tTalkboxFloat_setQuality(tTalkboxFloat* const voc, float quality) |
| 654 | +{ |
| 655 | + _tTalkboxFloat* v = *voc; |
| 309 | 656 | v->param[3] = quality; |
| 310 | 657 | v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * leaf.sampleRate); |
| 311 | 658 | if (v->O >= ORD_MAX) |
| @@ -314,20 +661,27 @@ void tTalkbox_setQuality(tTalkbox* const voc, float quality) · 2 unmodified lines |
| 314 | 661 | } |
| 315 | 662 | } |
| 316 | 663 | |
| 317 | | −void tTalkbox_setWarpFactor(tTalkbox* const voc, float warpFactor) |
| 664 | +void tTalkboxFloat_setWarpFactor(tTalkboxFloat* const voc, float warpFactor) |
| 318 | 665 | { |
| 319 | | − _tTalkbox* v = *voc; |
| 666 | + _tTalkboxFloat* v = *voc; |
| 320 | 667 | |
| 321 | 668 | v->warpFactor = warpFactor; |
| 322 | 669 | } |
| 323 | 670 | |
| 324 | | −void tTalkbox_setWarpOn(tTalkbox* const voc, float warpOn) |
| 671 | +void tTalkboxFloat_setWarpOn(tTalkboxFloat* const voc, float warpOn) |
| 325 | 672 | { |
| 326 | | − _tTalkbox* v = *voc; |
| 673 | + _tTalkboxFloat* v = *voc; |
| 327 | 674 | |
| 328 | 675 | v->warpOn = warpOn; |
| 329 | 676 | } |
| 330 | 677 | |
| 678 | +void tTalkboxFloat_setFreeze(tTalkboxFloat* const voc, float freeze) |
| 679 | +{ |
| 680 | + _tTalkboxFloat* v = *voc; |
| 681 | + |
| 682 | + v->freeze = freeze; |
| 683 | +} |
| 684 | + |
| 331 | 685 | |
| 332 | 686 | //============================================================================================================ |
| 333 | 687 | // VOCODER |
| @@ -374,7 +728,7 @@ void tVocoder_update (tVocoder* const voc) · 40 unmodified lines |
| 374 | 728 | |
| 375 | 729 | float tpofs = 6.2831853f * leaf.invSampleRate; |
| 376 | 730 | |
| 377 | | − float rr, th, re; |
| 731 | + float rr, th; |
| 378 | 732 | |
| 379 | 733 | float sh; |
| 380 | 734 | |
| @@ -389,7 +743,7 @@ void tVocoder_update (tVocoder* const voc) · 8 unmodified lines |
| 389 | 743 | if(v->param[7]<0.5f) |
| 390 | 744 | { |
| 391 | 745 | v->nbnd=8; |
| 392 | | − re=0.003f; |
| 746 | + |
| 393 | 747 | v->f[1][2] = 3000.0f; |
| 394 | 748 | v->f[2][2] = 2200.0f; |
| 395 | 749 | v->f[3][2] = 1500.0f; |
| @@ -401,7 +755,7 @@ void tVocoder_update (tVocoder* const voc) · 5 unmodified lines |
| 401 | 755 | else |
| 402 | 756 | { |
| 403 | 757 | v->nbnd=16; |
| 404 | | − re=0.0015f; |
| 758 | + |
| 405 | 759 | v->f[ 1][2] = 5000.0f; //+1000 |
| 406 | 760 | v->f[ 2][2] = 4000.0f; //+750 |
| 407 | 761 | v->f[ 3][2] = 3250.0f; //+500 |
| @@ -588,6 +942,35 @@ float tRosenbergGlottalPulse_tick (tRosenbergGlottalPulse* const gp) · 180 unmodified lines |
| 588 | 942 | return output; |
| 589 | 943 | } |
| 590 | 944 | |
| 945 | + |
| 946 | +float tRosenbergGlottalPulse_tickHQ (tRosenbergGlottalPulse* const gp) |
| 947 | +{ |
| 948 | + _tRosenbergGlottalPulse* g = *gp; |
| 949 | + |
| 950 | + float output = 0.0f; |
| 951 | + |
| 952 | + // Phasor increment |
| 953 | + g->phase += g->inc; |
| 954 | + while (g->phase >= 1.0f) g->phase -= 1.0f; |
| 955 | + while (g->phase < 0.0f) g->phase += 1.0f; |
| 956 | + |
| 957 | + if (g->phase < g->openLength) |
| 958 | + { |
| 959 | + output = 0.5f*(1.0f-cosf(PI * g->phase)); |
| 960 | + } |
| 961 | + |
| 962 | + else if (g->phase < g->pulseLength) |
| 963 | + { |
| 964 | + output = cosf(HALF_PI * (g->phase-g->openLength)* g->invPulseLengthMinusOpenLength); |
| 965 | + } |
| 966 | + |
| 967 | + else |
| 968 | + { |
| 969 | + output = 0.0f; |
| 970 | + } |
| 971 | + return output; |
| 972 | +} |
| 973 | + |
| 591 | 974 | void tRosenbergGlottalPulse_setFreq (tRosenbergGlottalPulse* const gp, float freq) |
| 592 | 975 | { |
| 593 | 976 | _tRosenbergGlottalPulse* g = *gp; |
| @@ -999,7 +1382,7 @@ static int pitchshift_attackdetect(_tPitchShift* ps) · 405 unmodified lines |
| 999 | 1382 | |
| 1000 | 1383 | void tPitchShift_init (tPitchShift* const psr, tPeriodDetection* pd, float* out, int bufSize) |
| 1001 | 1384 | { |
| 1002 | | − tPitchShift_freeFromPool(psr, &leaf.mempool); |
| 1385 | + tPitchShift_initToPool(psr, pd, out, bufSize, &leaf.mempool); |
| 1003 | 1386 | } |
| 1004 | 1387 | |
| 1005 | 1388 | void tPitchShift_free(tPitchShift* const psr) |
| @@ -1386,6 +1769,7 @@ void tAutotune_initToPool (tAutotune* const rt, int numVoices, int buf · 380 unmodified lines |
| 1386 | 1769 | } |
| 1387 | 1770 | |
| 1388 | 1771 | r->inputPeriod = 0.0f; |
| 1772 | + r->shiftOn = 0; |
| 1389 | 1773 | } |
| 1390 | 1774 | |
| 1391 | 1775 | void tAutotune_freeFromPool (tAutotune* const rt, tMempool* const mp) |