"Fossies" - the Fresh Open Source Software Archive 
Member "speech_tools/intonation/tilt/tilt_synthesis.cc" (4 Sep 2017, 14051 Bytes) of package /linux/misc/speech_tools-2.5.0-release.tar.gz:
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1996 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* Author : Paul Taylor */
34 /* Date : February 1996 - August 98 */
35 /* RFC Synthesis */
36 /* */
37 /*=======================================================================*/
38
39 #include "tilt.h"
40 #include "EST_unix.h"
41 #include "EST_math.h"
42 #include "EST_tilt.h"
43 #include "EST_Track.h"
44 #include "EST_error.h"
45
46
47 void tilt_synthesis(EST_Track &fz, EST_Relation &ev, float f_shift,
48 int no_conn)
49 {
50 tilt_to_rfc(ev);
51
52 rfc_synthesis(fz, ev, f_shift, no_conn);
53
54 ev.remove_item_feature("rfc");
55 }
56
57 void synthesize_rf_event(EST_Track &fz, EST_Features &ev, float peak_f0)
58 {
59 float t, amp, f_shift, a=0, start_f0;
60 float dur=0; // for egcs
61 int j;
62
63 f_shift = fz.shift();
64
65 dur = ev.F("rise_dur");
66 amp = ev.F("rise_amp");
67 start_f0 = peak_f0 - amp;
68
69 for (j = 0, t = 0.0; t < dur; t += f_shift, ++j)
70 {
71 a = unit_curve(amp, dur, t) + start_f0;
72 if (a > fz.a(j)) // overlap check
73 fz.a(j) = a;
74 fz.set_value(j);
75 }
76
77 dur = ev.F("fall_dur");
78 amp = ev.F("fall_amp");
79
80 for (t = 0.0; t < dur; t += f_shift, ++j)
81 {
82 a = unit_curve(amp, dur, t) + peak_f0;
83 if (a > fz.a(j)) // overlap check
84 fz.a(j) = a;
85 fz.set_value(j);
86 }
87 // hack to fill final values because of timing rounding errors
88 for (; j < fz.num_frames(); ++j)
89 fz.a(j) = a;
90 }
91
92 void fill_connection_values(EST_Track &fz, float start_f0, float start_pos,
93 float end_f0, float end_pos)
94 {
95 float f_shift, m;
96 int j;
97 f_shift = fz.shift();
98 if ((end_pos - start_pos) == 0)
99 m = 0.0;
100 else
101 m = (end_f0 - start_f0) / (end_pos - start_pos);
102 for (j = 0; j < fz.num_frames()-1; ++j)
103 {
104 fz.a(j) = (m * (float) j * f_shift) + start_f0;
105 fz.set_value(j);
106 }
107 fz.a(fz.num_frames()-1) = end_f0;
108 fz.set_value(fz.num_frames()-1);
109 // hack to fill final values because of timing rounding errors
110 //a = fz.a(j -1); // I Think this is ezafi
111 //for (; j < fz.num_frames(); ++j)
112 //fz.a(j) = a;
113 }
114
115
116 void rfc_synthesis(EST_Track &fz, EST_Relation &ev, float f_shift, int no_conn)
117 {
118 EST_Item *e,*nn;
119 EST_Track sub;
120 float start_pos=0, start_f0=0;
121 int start_index, end_index;
122 float end_pos, end_f0;
123 int n;
124
125 if (event_item(*ev.tail()))
126 n = (int)(ceil((ev.tail()->F("time") +
127 ev.tail()->F("rfc.fall_dur",0)) / f_shift)) + 1;
128 else
129 n = (int)(ceil(ev.tail()->F("time")/ f_shift)) + 1;
130
131 fz.resize(n, 1);
132 fz.set_equal_space(true);
133 fz.fill(0.0);
134 fz.fill_time(f_shift);
135
136 // set default to be break (silence)
137 for (int i = 0; i < fz.num_frames(); ++i)
138 fz.set_break(i);
139
140 // synthesize events
141 for (e = ev.head(); e != 0; e = inext(e))
142 {
143 if (event_item(*e))
144 {
145 start_pos = e->F("time") - e->F("rfc.rise_dur");
146 end_pos = e->F("time") + e->F("rfc.fall_dur");
147
148 if ((start_pos / f_shift-(int)start_pos / f_shift)>.5)
149 start_index=int(start_pos / f_shift+1);
150 else
151 start_index = (int) start_pos / f_shift;
152 if(end_pos / f_shift-(int)end_pos / f_shift>.5)
153 end_index = int( end_pos / f_shift+1);
154 else
155 end_index = (int) end_pos / f_shift;
156 // cout << "a: " << fz.equal_space() << endl;
157
158 fz.sub_track(sub, start_index, (end_index - start_index) + 1,
159 0, EST_ALL);
160
161 // cout << "a: " << fz.equal_space() << endl;
162 // cout << "b: " << sub.equal_space() << endl;
163
164 synthesize_rf_event(sub, e->A("rfc"), e->F("ev.f0"));
165 }
166 }
167
168 if (no_conn)
169 return;
170
171 // synthesize connections
172 for (e = ev.head(); inext(e) != 0; e = inext(e))
173 {
174 if (e->S("name") == "phrase_end")
175 continue;
176 nn = inext(e);
177
178 // calculate start and stop times, with additional
179 // optional adjustment for rise and falls on events
180
181 start_f0 = e->F("ev.f0") + e->F("rfc.fall_amp", 0.0);
182 start_pos= e->F("time") + e->F("rfc.fall_dur", 0.0);
183
184 end_f0 = nn->F("ev.f0") - nn->F("rfc.rise_amp", 0.0);
185 end_pos = nn->F("time") - nn->F("rfc.rise_dur", 0.0);
186
187 if ((start_pos / f_shift-(int)start_pos / f_shift)>.5)
188 start_index=int(start_pos / f_shift+1);
189 else
190 start_index = (int) start_pos / f_shift;
191 if(end_pos / f_shift-(int)end_pos / f_shift>.5)
192 end_index = int( end_pos / f_shift+1);
193 else
194 end_index = (int) end_pos / f_shift;
195
196
197 if (start_index >= end_index) // no connection needed
198 continue;
199
200 fz.sub_track(sub, start_index, end_index - start_index+1 , 0, EST_ALL);
201
202 fill_connection_values(sub, start_f0, start_pos, end_f0, end_pos);
203 }
204 }
205
206 /*
207
208 // find event portions of fz in contour, cut out, and send one by one
209 // to individual labeller.
210 void fill_rise_fall_values(EST_Track &fz, float amp, float dur, float
211 start_f0, float start_pos, float f_shift, EST_String type, int nframes)
212 {
213 float t, a;
214
215 // this ensures rounding errors don't multiply
216 int j = (int) rint(start_pos / f_shift);
217 int n = 0;
218
219 // for (t = 0.0; t < (dur + (f_shift /2.0)); t += f_shift, ++j, ++n)
220 for (t = 0.0; n < nframes; t += f_shift, ++j, ++n)
221 {
222 a = unit_curve(type, amp, dur, t) + start_f0;
223 if (a > fz.a(j)) // overlap check
224 fz.a(j) = a;
225 fz.set_value(j);
226 }
227 cout << "curve frames: " << n << endl;
228 }
229
230 void fill_connection_values(EST_Track &fz, float start_f0, float start_pos,
231 float end_f0, float end_pos,
232 float f_shift)
233 {
234 // this ensures rounding errors don't multiply
235 int j = (int) rint(start_pos / f_shift);
236
237 float m = (end_f0 - start_f0) / (end_pos - start_pos);
238
239 if (!finite(m))
240 m = 0.0;
241
242 int pos = fz.index(start_pos);
243
244 for (j = pos; j < (fz.index(end_pos) + 1); ++j)
245 {
246 fz.a(j) = (m * (float) (j -pos) * f_shift) + start_f0;
247 fz.set_value(j);
248 }
249 }
250
251
252 void fill_rise_fall_values(EST_Track &fz, float amp, float start_f0)
253 {
254 float t, a;
255 int j;
256 float f_shift = fz.shift();
257 float dur = fz.num_frames() * f_shift;
258
259 for (j = 0, t = 0.0; j < fz.num_frames(); t += f_shift, ++j)
260 {
261 a = unit_curve("RISE", amp, dur, t) + start_f0;
262 if (a > fz.a(j)) // overlap check
263 fz.a(j) = a;
264 fz.set_value(j);
265 }
266 }
267
268 void fill_connection_values(EST_Track &fz, float start_f0, float end_f0)
269 {
270 // this ensures rounding errors don't multiply
271 int j;
272 float f_shift = fz.shift();
273 float dur = fz.num_frames() * f_shift;
274
275 float m = (end_f0 - start_f0) / dur;
276
277 if (!finite(m))
278 m = 0.0;
279
280 for (j = 0 j < fz.num_frames(); ++j)
281 {
282 fz.a(j) = (m * (float)j * f_shift) + start_f0;
283 fz.set_value(j);
284 }
285
286 }
287
288
289 #if 0
290 void start_f0_pos(EST_Item *e, const EST_String &type, float &start_f0,
291 float &start_pos)
292 {
293 if (type == "RISE")
294 {
295 start_f0 = e->F("ev.f0");
296 start_pos = e->F("position") - e->F("rfc.rise_dur");
297 }
298 else
299 {
300 start_f0 = e->F("ev.f0") + e->F("rfc.rise_amp");
301 start_pos = e->F("position");
302 }
303 }
304 #endif
305
306 static float find_start_pos(EST_Item *e, const EST_String &type)
307 {
308 //cout << "find start position for " << *e << endl;
309 if (type == "RISE")
310 return e->F("position") - e->F("rfc.rise_dur");
311 else
312 return e->F("position");
313 }
314
315 static float find_start_f0(EST_Item *e, const EST_String &type)
316 {
317 //cout << "find start f0 for " << *e<< endl;
318 if (type == "RISE")
319 return e->F("ev.f0");
320 else
321 return e->F("ev.f0") + e->F("rfc.rise_amp");
322 }
323
324 float rfc_dur(EST_Item *e)
325 {
326 return e->F("rfc.rise_dur") + e->F("rfc.fall_dur");
327 }
328
329 float rfc_amp(EST_Item *e)
330 {
331 return e->F("rfc.rise_amp") + e->F("rfc.fall_amp");
332 }
333
334
335
336 int rfc_synthesis_ld(EST_Track &fz, EST_Relation &ev, float f_shift, int no_conn)
337 {
338 EST_Item *e,*nn;
339 EST_Track sub;
340 float start_pos=0, start_f0=0;
341 EST_String type;
342 (void)no_conn;
343 int start_index, nframes, end_index;
344 float length, end_pos;
345
346 float last_time = ev.tail()->F("position") + rfc_dur(ev.tail());
347 int n = (int)(2 + (last_time / f_shift));
348 fz.resize(n, 1);
349 fz.fill(0.0);
350 fz.fill_time(f_shift);
351
352 fill_rfc_types(ev);
353
354 // set default to be break (silence)
355 for (int i = 0; i < fz.num_frames(); ++i)
356 fz.set_break(i);
357
358 for (e = ev.head(); e != 0; e = inext(e))
359 {
360 // cout << "\ntype: " << e->fS("rfc.type") << endl;
361 //cout << "\ntype: " << *e << endl;
362 if (e->f("rfc.type",1) == "RISEFALL")
363 {
364 start_f0 = find_start_f0(e,"RISE");
365 start_pos = find_start_pos(e,"RISE");
366
367 start_index = (int) rint(start_pos / f_shift);
368 nframes = (int)((e->F("rfc.rise_dur")+ (f_shift /2.0))/f_shift);
369 fz.sub_track(sub, start_index, nframes, 0, EST_ALL);
370
371 fill_rise_fall_values(sub, e->F("rfc.rise_amp"), start_f0);
372 cout << "rise subtrack: " << sub;
373
374 start_index = (int) rint(find_start_pos(e, "FALL") / f_shift);
375 nframes = (int)((e->F("rfc.fall_dur") +(f_shift /2.0))/f_shift);
376 fz.sub_track(sub, start_index, nframes, 0, EST_ALL);
377
378 fill_rise_fall_values(sub, e->F("rfc.fall_amp"),
379 find_start_f0(e,"FALL"));
380
381 cout << "fall subtrack: " << sub;
382
383
384 fill_rise_fall_values(sub, e->F("rfc.fall_amp"), e->F("rfc.fall_dur"),
385 find_start_f0(e,"FALL"),
386 find_start_pos(e,"FALL"),
387 f_shift, "FALL", nframes);
388
389
390 }
391 else if (e->f("rfc.type",1) == "RISE")
392 {
393 start_f0 = find_start_f0(e,"RISE");
394 start_pos = find_start_pos(e,"RISE");
395
396 start_index = (int) rint(start_pos / f_shift);
397 nframes = (int)((e->F("rfc.rise_dur")+ (f_shift /2.0))/f_shift);
398 fz.sub_track(sub, start_index, nframes, 0, EST_ALL);
399
400 fill_rise_fall_values(sub, e->F("rfc.rise_amp"), start_f0);
401
402
403 fill_rise_fall_values(fz, e->F("rfc.rise_amp"),
404 e->F("rfc.rise_dur"),
405 start_f0, start_pos,
406 f_shift, "RISE", nframes);
407
408
409 }
410 else if (e->f("rfc.type",1) == "FALL")
411 {
412 start_f0 = find_start_f0(e, "FALL");
413 start_pos = find_start_pos(e, "FALL");
414
415 nframes = (int)((e->F("rfc.fall_dur")+ (f_shift /2.0))/f_shift);
416 start_index = (int) rint(find_start_pos(e, "FALL") / f_shift);
417 fz.sub_track(sub, start_index, nframes, 0, EST_ALL);
418
419 fill_rise_fall_values(fz, e->F("rfc.fall_amp"),
420 e->F("ev.f0"));
421
422 fill_rise_fall_values(fz, e->F("rfc.fall_amp"),
423 e->F("rfc.fall_dur"), e->F("ev.f0"),
424 e->F("position"), f_shift,
425 "FALL", nframes);
426
427 }
428 else
429 {
430 EST_Item *nn,*pp;
431
432 if (no_conn)
433 continue;
434
435 if (e->f("name",1) == "phrase_end")
436 {
437 if (e->f_present("ev.f0"))
438 {
439 pp = e->prev();
440
441 fill_connection_values(fz, start_f0 + rfc_amp(pp),
442 start_pos
443 + rfc_dur(pp), e->F("ev.f0"),
444 e->F("position"), f_shift);
445
446 }
447 }
448 else if (e->f("name", 1) == "phrase_start")
449 {
450 //cout << "phrase start:\n" << *e << endl;
451 if ((nn = inext(e)) == 0)
452 EST_error("phrase start command occurs as last item "
453 "in rfc synthesis\n");
454 else if (event_item(*nn))
455 {
456 start_f0 = find_start_f0(nn,"RISE");
457 start_pos = find_start_pos(nn,"RISE");
458 }
459 else
460 {
461 start_f0 = nn->F("ev.f0");
462 start_pos = nn->F("position");
463 }
464
465 fill_connection_values(fz, e->F("ev.f0"),
466 e->F("position"),
467 start_f0,start_pos, f_shift);
468
469 }
470 else if (e->f("name") == "pause")
471 {}
472 else
473 EST_error("Unable to synthesis intonation element %s\n",
474 (const char *)(e->fS("name")));
475 continue;
476 }
477 if (((nn = inext(e)) != 0) && (event_item(*nn)))
478 {
479 float f0 = start_f0+rfc_amp(e);
480 float pos = start_pos + rfc_dur(e);
481 float end_f0 = find_start_f0(nn,"RISE");
482 float end_pos = find_start_pos(nn,"RISE");
483 fill_connection_values(fz, f0, pos, end_f0, end_pos, f_shift);
484 }
485 }
486 }
487 */