// This function returns a single sample from the Vocoder. double MAGE::Vocoder::pop() { int i; if( voiced ) { if( count <= 0 ) { x = sqrt( this->t0 ); count = this->t0; } else { x = 0; count--; } } else { x = MAGE::Random( -1,1 ); count = 0; } if( stage != 0 ) // MGLSA { if( !ngain ) x *= exp( c[0] ); x = mglsadf( x, c, m, alpha, stage, d ); } else // MLSA { if( !ngain ) x *= exp( c[0] ); x = mlsadf( x, c, m, alpha, pd, d ); } //filter interpolation has not reached next filter yet //when next filter is reached, stop interpolation, otherwise //you'll eventually get an unstable filter if( this->nOfPopSinceLastPush < ( fprd/iprd ) ) for( i = 0; i <= m; i++ ) c[i] += inc[i]; this->nOfPopSinceLastPush++; // ATTENTION volume??? correct place??? if( this->volume >= 0 ) return( this->volume * x ); return( x ); }
int main(int argc, char **argv) { int m = ORDER, fprd = FPERIOD, iprd = IPERIOD, stage = STAGE, pd = PADEORDER, i, j; Boolean transpose = TRANSPOSE, ngain = NGAIN, inverse = INVERSE; FILE *fp = stdin, *fpc = NULL; double alpha = ALPHA, gamma = -1 / (double) STAGE, x, *c, *inc, *cc, *d; if ((cmnd = strrchr(argv[0], '/')) == NULL) cmnd = argv[0]; else cmnd++; while (--argc) if (**++argv == '-') { switch (*(*argv + 1)) { case 'm': m = atoi(*++argv); --argc; break; case 'a': alpha = atof(*++argv); --argc; break; case 'c': stage = atoi(*++argv); --argc; break; case 'p': fprd = atoi(*++argv); --argc; break; case 'i': iprd = atoi(*++argv); --argc; break; case 't': transpose = 1 - transpose; break; case 'v': inverse = 1 - inverse; break; case 'k': ngain = 1 - ngain; break; case 'P': pd = atoi(*++argv); --argc; break; case 'h': usage(0); default: fprintf(stderr, "%s : Invalid option '%c'!\n", cmnd, *(*argv + 1)); usage(1); } } else if (fpc == NULL) fpc = getfp(*argv, "rb"); else fp = getfp(*argv, "rb"); if (fpc == NULL) { fprintf(stderr, "%s : Cannot open cepstrum file!\n", cmnd); return (1); } if (inverse) { if (stage == 0) { fprintf(stderr, "%s : gamma should not equal to 0 in Inverse MGLSA!\n", cmnd); usage(1); } } if (stage != 0) { /* MGLSA */ gamma = -1 / (double) stage; } else { /* MLSA */ if ((pd < 4) || (pd > 5)) { fprintf(stderr, "%s : Order of Pade approximation should be 4 or 5!\n", cmnd); return (1); } } c = (stage != 0) ? dgetmem(m + m + m + 3 + (m + 1) * stage) /* MGLSA */ : dgetmem(3 * (m + 1) + 3 * (pd + 1) + pd * (m + 2)); /* MLSA */ cc = c + m + 1; inc = cc + m + 1; d = inc + m + 1; if (freadf(c, sizeof(*c), m + 1, fpc) != m + 1) return (1); mc2b(c, c, m, alpha); if (stage != 0) { /* MGLSA */ gnorm(c, c, m, gamma); c[0] = log(c[0]); for (i = 1; i <= m; i++) c[i] *= gamma; } for (;;) { if (freadf(cc, sizeof(*cc), m + 1, fpc) != m + 1) return (0); mc2b(cc, cc, m, alpha); if (stage != 0) { gnorm(cc, cc, m, gamma); cc[0] = log(cc[0]); for (i = 1; i <= m; i++) cc[i] *= gamma; } for (i = 0; i <= m; i++) inc[i] = (cc[i] - c[i]) * iprd / fprd; for (j = fprd, i = (iprd + 1) / 2; j--;) { if (freadf(&x, sizeof(x), 1, fp) != 1) return (0); if (inverse) { /* IMGLSA */ if (!ngain) x /= exp(c[0]); if (transpose) x = imglsadft(x, c, m, alpha, stage, d); else x = imglsadf(x, c, m, alpha, stage, d); } else { if (stage != 0) { /* MGLSA */ if (!ngain) x *= exp(c[0]); if (transpose) x = mglsadft(x, c, m, alpha, stage, d); else x = mglsadf(x, c, m, alpha, stage, d); } else { /* MLSA */ if (!ngain) x *= exp(c[0]); x = mlsadf(x, c, m, alpha, pd, d); } } fwritef(&x, sizeof(x), 1, stdout); if (!--i) { for (i = 0; i <= m; i++) c[i] += inc[i]; i = iprd; } } movem(cc, c, sizeof(*cc), m + 1); } return (0); }