1 /*  ---------------------------------------------------------------  */
2 /*      The HMM-Based Speech Synthesis System (HTS): version 1.1b    */
3 /*                        HTS Working Group                          */
4 /*                                                                   */
5 /*                   Department of Computer Science                  */
6 /*                   Nagoya Institute of Technology                  */
7 /*                                and                                */
8 /*    Interdisciplinary Graduate School of Science and Engineering   */
9 /*                   Tokyo Institute of Technology                   */
10 /*                      Copyright (c) 2001-2003                      */
11 /*                        All Rights Reserved.                       */
12 /*                                                                   */
13 /*  Permission is hereby granted, free of charge, to use and         */
14 /*  distribute this software and its documentation without           */
15 /*  restriction, including without limitation the rights to use,     */
16 /*  copy, modify, merge, publish, distribute, sublicense, and/or     */
17 /*  sell copies of this work, and to permit persons to whom this     */
18 /*  work is furnished to do so, subject to the following conditions: */
19 /*                                                                   */
20 /*    1. The code must retain the above copyright notice, this list  */
21 /*       of conditions and the following disclaimer.                 */
22 /*                                                                   */
23 /*    2. Any modifications must be clearly marked as such.           */
24 /*                                                                   */
25 /*  NAGOYA INSTITUTE OF TECHNOLOGY, TOKYO INSITITUTE OF TECHNOLOGY,  */
26 /*  HTS WORKING GROUP, AND THE CONTRIBUTORS TO THIS WORK DISCLAIM    */
27 /*  ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL       */
28 /*  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
29 /*  SHALL NAGOYA INSTITUTE OF TECHNOLOGY, TOKYO INSITITUTE OF        */
30 /*  TECHNOLOGY, HTS WORKING GROUP, NOR THE CONTRIBUTORS BE LIABLE    */
31 /*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY        */
32 /*  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,  */
33 /*  WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS   */
34 /*  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR          */
35 /*  PERFORMANCE OF THIS SOFTWARE.                                    */
36 /*                                                                   */
37 /*  ---------------------------------------------------------------  */
38 /*   vocoder.c : mel-cepstral vocoder                                */
39 /*              (pulse/noise excitation & MLSA filter)               */
40 /*                                                                   */
41 /*                                    2003/06/11 by Heiga Zen        */
42 /*  ---------------------------------------------------------------  */
43 
44 #include <cstdio>
45 #include <cstdlib>
46 #include <cmath>
47 #include "EST_walloc.h"
48 
49 #include "misc.h"
50 #include "model.h"
51 #include "defaults.h"
52 #include "global.h"
53 #include "vocoder.h"
54 
init_vocoder(int m,VocoderSetup * vs)55 void init_vocoder(int m, VocoderSetup *vs)
56 {
57    vs->fprd = FPERIOD;
58    vs->iprd = IPERIOD;
59    vs->seed = SEED;
60    vs->pd   = PADEORDER;
61 
62    vs->next = SEED;
63    vs->gauss = GAUSS;
64 
65    vs->pade[ 0]=1.0;
66    vs->pade[ 1]=1.0; vs->pade[ 2]=0.0;
67    vs->pade[ 3]=1.0; vs->pade[ 4]=0.0;      vs->pade[ 5]=0.0;
68    vs->pade[ 6]=1.0; vs->pade[ 7]=0.0;      vs->pade[ 8]=0.0;      vs->pade[ 9]=0.0;
69    vs->pade[10]=1.0; vs->pade[11]=0.4999273; vs->pade[12]=0.1067005; vs->pade[13]=0.01170221; vs->pade[14]=0.0005656279;
70    vs->pade[15]=1.0; vs->pade[16]=0.4999391; vs->pade[17]=0.1107098; vs->pade[18]=0.01369984; vs->pade[19]=0.0009564853;
71    vs->pade[20]=0.00003041721;
72 
73    vs->rate=RATE;
74 
75    vs->c = walloc(double,3*(m+1)+3*(vs->pd+1)+vs->pd*(m+2));
76 
77    vs->p1 = -1;
78    vs->sw = 0;
79    vs->x  = 0x55555555;
80 }
81 
vocoder(double p,float * mc,int m,FILE * rawfp,globalP * gp,VocoderSetup * vs)82 void vocoder (double p, float *mc, int m, FILE *rawfp, globalP *gp, VocoderSetup *vs)
83 {
84    double inc, x;
85    int i, j, k;
86    short xs;
87    double a = gp->ALPHA;
88 
89    if (p!=0.0)
90       p = vs->rate / p;  /* f0 -> pitch */
91 
92    if (vs->p1 < 0) {
93       if (vs->gauss & (vs->seed != 1)) vs->next = srnd ((unsigned)vs->seed);
94 
95       vs->p1   = p;
96       vs->pc   = vs->p1;
97       vs->cc   = vs->c + m + 1;
98       vs->cinc = vs->cc + m + 1;
99       vs->d1   = vs->cinc + m + 1;
100 
101       mc2b(mc, vs->c, m, a);
102 
103       return;
104    }
105 
106    mc2b(mc, vs->cc, m, a);
107 
108    for (k=0; k<=m; k++)
109       vs->cinc[k] = (vs->cc[k]-vs->c[k])*(double)vs->iprd/(double)vs->fprd;
110 
111    if (vs->p1!=0.0 && p!=0.0) {
112       inc = (p-vs->p1)*(double)vs->iprd/(double)vs->fprd;
113    }
114    else {
115       inc = 0.0;
116       vs->pc = p;
117       vs->p1 = 0.0;
118    }
119 
120    for (j=vs->fprd, i=(vs->iprd+1)/2; j--;) {
121       if (vs->p1 == 0.0) {
122           if (vs->gauss)
123              x = (double) nrandom(vs);
124           else
125              x = mseq(vs);
126       }
127       else {
128           if ((vs->pc += 1.0)>=vs->p1) {
129              x = sqrt (vs->p1);
130              vs->pc = vs->pc - vs->p1;
131           }
132           else
133               x = 0.0;
134       }
135 
136       x *= exp(vs->c[0]);
137 
138       x = mlsadf(x, vs->c, m, a, vs->pd, vs->d1, vs);
139       xs = (short) x;
140 
141       fwrite(&xs, sizeof(short), 1, rawfp);
142 
143       fflush(stdout);
144 
145       if (!--i) {
146          vs->p1 += inc;
147          for (k=0;k<=m;k++) vs->c[k] += vs->cinc[k];
148          i = vs->iprd;
149       }
150    }
151 
152    vs->p1 = p;
153    movem(vs->cc,vs->c,m+1);
154 }
155 
mlsafir(double x,double * b,int m,double a,double * d)156 double mlsafir (double x, double *b, int m, double a, double *d)
157 {
158    double y = 0.0;
159    double aa;
160    register int i;
161 
162    aa = 1 - a*a;
163 
164    d[0] = x;
165    d[1] = aa*d[0] + a*d[1];
166 
167    for (i=2; i<=m; i++) {
168       d[i] = d[i] + a*(d[i+1]-d[i-1]);
169       y += d[i]*b[i];
170    }
171 
172    for (i=m+1; i>1; i--) d[i] = d[i-1];
173 
174    return (y);
175 }
176 
mlsadf1(double x,double * b,int m,double a,int pd,double * d,VocoderSetup * vs)177 double mlsadf1(double x, double *b, int m, double a, int pd, double *d, VocoderSetup *vs)
178 {
179    double v, out = 0.0, *pt, aa;
180    register int i;
181 
182    aa = 1 - a*a;
183    pt = &d[pd+1];
184 
185    for (i=pd; i>=1; i--) {
186       d[i] = aa*pt[i-1] + a*d[i];
187       pt[i] = d[i] * b[1];
188       v = pt[i] * vs->ppade[i];
189 
190       x += (1 & i) ? v : -v;
191       out += v;
192    }
193 
194    pt[0] = x;
195    out += x;
196 
197    return(out);
198 }
199 
mlsadf2(double x,double * b,int m,double a,int pd,double * d,VocoderSetup * vs)200 double mlsadf2 (double x, double *b, int m, double a, int pd, double *d, VocoderSetup *vs)
201 {
202    double v, out = 0.0, *pt, aa;
203    register int i;
204 
205    aa = 1 - a*a;
206    pt = &d[pd * (m+2)];
207 
208    for (i=pd; i>=1; i--) {
209       pt[i] = mlsafir (pt[i-1], b, m, a, &d[(i-1)*(m+2)]);
210       v = pt[i] * vs->ppade[i];
211 
212       x  += (1&i) ? v : -v;
213       out += v;
214    }
215 
216    pt[0] = x;
217    out  += x;
218 
219    return(out);
220 }
221 
mlsadf(double x,double * b,int m,double a,int pd,double * d,VocoderSetup * vs)222 double mlsadf(double x, double *b, int m, double a, int pd, double *d, VocoderSetup *vs)
223 {
224 
225    vs->ppade = &(vs->pade[pd*(pd+1)/2]);
226 
227    x = mlsadf1 (x, b, m, a, pd, d, vs);
228    x = mlsadf2 (x, b, m, a, pd, &d[2*(pd+1)], vs);
229 
230    return (x);
231 }
232 
nrandom(VocoderSetup * vs)233 double nrandom (VocoderSetup *vs)
234 {
235     unsigned long rr;
236    if (vs->sw == 0) {
237       vs->sw = 1;
238       do {
239 	  rr = vs->next;
240          vs->r1 = 2 * rnd(&rr) - 1;
241          vs->r2 = 2 * rnd(&rr) - 1;
242 	 vs->next = rr;
243          vs->s  = vs->r1 * vs->r1 + vs->r2 * vs->r2;
244       } while (vs->s > 1 || vs->s == 0);
245 
246       vs->s = sqrt (-2 * log(vs->s) / vs->s);
247       return ( vs->r1 * vs->s );
248    }
249    else {
250       vs->sw = 0;
251       return ( vs->r2 * vs->s );
252    }
253 }
254 
rnd(unsigned long * next)255 double rnd (unsigned long *next)
256 {
257    double r;
258 
259    *next = *next * 1103515245L + 12345;
260    r = (*next / 65536L) % 32768L;
261 
262    return ( r/RANDMAX );
263 }
264 
srnd(unsigned long seed)265 unsigned long srnd ( unsigned long seed )
266 {
267    return (seed);
268 }
269 
270 
mseq(VocoderSetup * vs)271 int mseq (VocoderSetup *vs)
272 {
273    register int x0, x28;
274 
275    vs->x >>= 1;
276 
277    if (vs->x & B0)
278       x0 = 1;
279    else
280       x0 = -1;
281 
282    if (vs->x & B28)
283       x28 = 1;
284    else
285       x28 = -1;
286 
287    if (x0 + x28)
288       vs->x &= B31_;
289    else
290       vs->x |= B31;
291 
292    return (x0);
293 }
294 
mc2b(float * mc,double * b,int m,double a)295 void mc2b( float *mc, double *b, int m, double a)
296 {
297    b[m] = mc[m];
298 
299    for (m--; m>=0; m--)
300       b[m] = mc[m] - a * b[m+1];
301 }
302 
303 /* -------------------- End of "vocoder.c" -------------------- */
304