/* HTS_mgc2mgc: frequency and generalized cepstral transformation */ static void HTS_mgc2mgc(HTS_Vocoder * v, double *c1, const int m1, const double a1, const double g1, double *c2, const int m2, const double a2, const double g2) { double a; if (a1 == a2) { HTS_gnorm(c1, c1, m1, g1); HTS_gc2gc(v, c1, m1, g1, c2, m2, g2); HTS_ignorm(c2, c2, m2, g2); } else { a = (a2 - a1) / (1 - a1 * a2); HTS_freqt(v, c1, m1, c2, m2, a); HTS_gnorm(c2, c2, m2, g1); HTS_gc2gc(v, c2, m2, g1, c2, m2, g2); HTS_ignorm(c2, c2, m2, g2); } }
/* HTS_lsp2mgc: transform LSP to MGC */ static void HTS_lsp2mgc(HTS_Vocoder * v, double *lsp, double *mgc, const int m, const double alpha) { int i; /* lsp2lpc */ HTS_lsp2lpc(v, lsp + 1, mgc, m); if (v->use_log_gain) mgc[0] = exp(lsp[0]); else mgc[0] = lsp[0]; /* mgc2mgc */ if (NORMFLG1) HTS_ignorm(mgc, mgc, m, v->gamma); else if (MULGFLG1) mgc[0] = (1.0 - mgc[0]) * ((double) v->stage); if (MULGFLG1) for (i = m; i >= 1; i--) mgc[i] *= -((double) v->stage); HTS_mgc2mgc(v, mgc, m, alpha, v->gamma, mgc, m, alpha, v->gamma); if (NORMFLG2) HTS_gnorm(mgc, mgc, m, v->gamma); else if (MULGFLG2) mgc[0] = mgc[0] * v->gamma + 1.0; if (MULGFLG2) for (i = m; i >= 1; i--) mgc[i] *= v->gamma; }
/* HTS_Vocoder_synthesize: pulse/noise excitation and MLSA/MGLSA filster based waveform synthesis */ void HTS_Vocoder_synthesize(HTS_Vocoder * v, size_t m, double lf0, double *spectrum, size_t nlpf, double *lpf, double alpha, double beta, double volume, double *rawdata, HTS_Audio * audio) { double x; int i, j; short xs; int rawidx = 0; double p; /* lf0 -> pitch */ if (lf0 == LZERO) p = 0.0; else if (lf0 <= MIN_LF0) p = v->rate / MIN_F0; else if (lf0 >= MAX_LF0) p = v->rate / MAX_F0; else p = v->rate / exp(lf0); /* first time */ if (v->is_first == TRUE) { HTS_Vocoder_initialize_excitation(v, p, nlpf); if (v->stage == 0) { /* for MCP */ HTS_mc2b(spectrum, v->c, m, alpha); } else { /* for LSP */ HTS_movem(spectrum, v->c, m + 1); HTS_lsp2mgc(v, v->c, v->c, m, alpha); HTS_mc2b(v->c, v->c, m, alpha); HTS_gnorm(v->c, v->c, m, v->gamma); for (i = 1; i <= m; i++) v->c[i] *= v->gamma; } v->is_first = FALSE; } HTS_Vocoder_start_excitation(v, p); if (v->stage == 0) { /* for MCP */ HTS_Vocoder_postfilter_mcp(v, spectrum, m, alpha, beta); HTS_mc2b(spectrum, v->cc, m, alpha); for (i = 0; i <= m; i++) v->cinc[i] = (v->cc[i] - v->c[i]) / v->fprd; } else { /* for LSP */ HTS_Vocoder_postfilter_lsp(v, spectrum, m, alpha, beta); HTS_check_lsp_stability(spectrum, m); HTS_lsp2mgc(v, spectrum, v->cc, m, alpha); HTS_mc2b(v->cc, v->cc, m, alpha); HTS_gnorm(v->cc, v->cc, m, v->gamma); for (i = 1; i <= m; i++) v->cc[i] *= v->gamma; for (i = 0; i <= m; i++) v->cinc[i] = (v->cc[i] - v->c[i]) / v->fprd; } for (j = 0; j < v->fprd; j++) { x = HTS_Vocoder_get_excitation(v, lpf); if (v->stage == 0) { /* for MCP */ if (x != 0.0) x *= exp(v->c[0]); x = HTS_mlsadf(x, v->c, m, alpha, PADEORDER, v->d1); } else { /* for LSP */ if (!NGAIN) x *= v->c[0]; x = HTS_mglsadf(x, v->c, m, alpha, v->stage, v->d1); } x *= volume; /* output */ if (rawdata) rawdata[rawidx++] = x; if (audio) { if (x > 32767.0) xs = 32767; else if (x < -32768.0) xs = -32768; else xs = (short) x; HTS_Audio_write(audio, xs); } for (i = 0; i <= m; i++) v->c[i] += v->cinc[i]; } HTS_Vocoder_end_excitation(v, p); HTS_movem(v->cc, v->c, m + 1); }
/* HTS_Vocoder_synthesize: pulse/noise excitation and MLSA/MGLSA filster based waveform synthesis */ void HTS_Vocoder_synthesize(HTS_Vocoder *v, const int m, double lf0, double *spectrum, double alpha, double beta, short *rawdata) { double x; int i, j; short xs; int rawidx = 0; double p; /* lf0 -> pitch */ if (lf0 == LZERO) p = 0.0; else p = v->rate / exp(lf0); /* first time */ if (v->p1 < 0.0) { if (v->gauss & (v->seed != 1)) v->next = HTS_srnd((unsigned) v->seed); HTS_Vocoder_initialize_excitation(v); if (v->stage != 0) { /* for LSP */ if (v->use_log_gain) v->c[0] = LZERO; else v->c[0] = ZERO; for (i = 0; i <= m; i++) v->c[i] = i * PI / (m + 1); HTS_lsp2mgc(v, v->c, v->c, m, alpha); HTS_mc2b(v->c, v->c, m, alpha); HTS_gnorm(v->c, v->c, m, v->gamma); for (i = 1; i <= m; i++) v->c[i] *= v->gamma; } } HTS_Vocoder_start_excitation(v, p); if (v->stage == 0) { /* for MCP */ HTS_Vocoder_postfilter_mcp(v, spectrum, m, alpha, beta); HTS_mc2b(spectrum, v->cc, m, alpha); for (i = 0; i <= m; i++) v->cinc[i] = (v->cc[i] - v->c[i]) * v->iprd / v->fprd; } else { /* for LSP */ HTS_lsp2mgc(v, spectrum, v->cc, m, alpha); HTS_mc2b(v->cc, v->cc, m, alpha); HTS_gnorm(v->cc, v->cc, m, v->gamma); for (i = 1; i <= m; i++) v->cc[i] *= v->gamma; for (i = 0; i <= m; i++) v->cinc[i] = (v->cc[i] - v->c[i]) * v->iprd / v->fprd; } for (j = 0, i = (v->iprd + 1) / 2; j < v->fprd; j++) { x = HTS_Vocoder_get_excitation(v, j, i); if (v->stage == 0) { /* for MCP */ if (x != 0.0) x *= exp(v->c[0]); x = HTS_mlsadf(x, v->c, m, alpha, PADEORDER, v->d1, v->pade); } else { /* for LSP */ if (!NGAIN) x *= v->c[0]; x = HTS_mglsadf(x, v->c, m, alpha, v->stage, v->d1); } xs = (short) (1.00*x); if (rawdata) rawdata[rawidx++] = xs; if (v->audio) HTS_Audio_write(v->audio, xs); if (!--i) { for (i = 0; i <= m; i++) v->c[i] += v->cinc[i]; i = v->iprd; } } HTS_Vocoder_end_excitation(v); HTS_movem(v->cc, v->c, m + 1); }