Edinburgh Speech Tools 2.4-release
 
Loading...
Searching...
No Matches
tilt_synthesis.cc
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
47void 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
57void 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
92void 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
116void 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.
210void 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
230void 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
252void 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
268void 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
290void 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
306static 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
315static 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
324float rfc_dur(EST_Item *e)
325{
326 return e->F("rfc.rise_dur") + e->F("rfc.fall_dur");
327}
328
329float rfc_amp(EST_Item *e)
330{
331 return e->F("rfc.rise_amp") + e->F("rfc.fall_amp");
332}
333
334
335
336int 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*/
const float F(const EST_String &path) const
const EST_String S(const EST_String &name) const
Definition EST_Item.h:143
EST_Features & A(const EST_String &name) const
Definition EST_Item.h:163
const float F(const EST_String &name) const
Definition EST_Item.h:134
void remove_item_feature(const EST_String &name)
EST_Item * head() const
EST_Item * tail() const
void fill(float v)
Definition EST_Track.h:500
float & a(int i, int c=0)
void sub_track(EST_Track &st, int start_frame=0, int nframes=EST_ALL, int start_chan=0, int nchans=EST_ALL)
void set_value(int i)
set frame i to be a value
Definition EST_Track.cc:131
int num_frames() const
return number of frames in track
Definition EST_Track.h:650
void resize(int num_frames, int num_channels, bool preserve=1)
Definition EST_Track.cc:211
void fill_time(float t, int start=1)
Definition EST_Track.cc:786
float shift() const
Definition EST_Track.cc:599
void set_break(int i)
set frame i to be a break
Definition EST_Track.cc:122