Edinburgh Speech Tools 2.4-release
tilt_utils.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 */
35/*-----------------------------------------------------------------------*/
36/* Event RFC Utilities */
37/* */
38/*=======================================================================*/
39
40#include <cstdlib>
41#include "EST_math.h"
42#include "tilt.h"
43#include "EST_error.h"
44
45void validate_rfc_stream(EST_Relation &ev);
46
47/*
48float rfc_to_tilt_amp(EST_Item *e)
49{
50 return fabs(e->F("rfc.rise_amp")) + fabs(e->F("rfc.fall_amp"));
51}
52
53float rfc_to_tilt_dur(EST_Item *e)
54{
55 return e->F("rfc.rise_dur") + e->F("rfc.fall_dur");
56}
57
58float rfc_to_a_tilt(EST_Item *e)
59{
60 return (float)(fabs(e->F("rfc.rise_amp")) - fabs(e->F("rfc.fall_amp"))) /
61 (float)(fabs(e->F("rfc.rise_amp")) + fabs(e->F("rfc.fall_amp")));
62}
63
64float rfc_to_d_tilt(EST_Item *e)
65{
66 return (float)(fabs(e->F("rfc.rise_dur")) - fabs(e->F("rfc.fall_dur"))) /
67 (float)(e->F("rfc.rise_dur") + e->F("rfc.fall_dur"));
68}
69
70float rfc_to_t_tilt(EST_Item *e)
71{
72 float t_tilt;
73 t_tilt = (rfc_to_a_tilt(e) + rfc_to_d_tilt(e)) / 2;
74 if (isnan(t_tilt))
75 t_tilt = 0.0;
76 return t_tilt;
77}
78
79float tilt_to_rise_amp(EST_Item *e)
80{
81 return e->F("tilt.amp") * (1 + e->F("tilt.tilt")) / 2.0;
82}
83
84float tilt_to_rise_dur(EST_Item *e)
85{
86 return e->F("tilt.dur") * (1 + e->F("tilt.tilt")) / 2.0;
87}
88
89float tilt_to_fall_amp(EST_Item *e)
90{
91 return -e->F("tilt.amp") * (1 - e->F("tilt.tilt")) / 2.0;
92}
93
94float tilt_to_fall_dur(EST_Item *e)
95{
96 return e->F("tilt.dur") * (1 - e->F("tilt.tilt")) / 2.0;
97}
98
99float tilt_to_peak_f0(EST_Item *e)
100{
101 return e->F("ev:start_f0") + tilt_to_rise_amp(e);
102}
103
104float tilt_to_peak_pos(EST_Item *e)
105{
106 return e->F("start") + tilt_to_rise_dur(e);
107}
108*/
109
110float rfc_to_tilt_amp(EST_Features &e)
111{
112 return fabs(e.F("rise_amp")) + fabs(e.F("fall_amp"));
113}
114
115float rfc_to_tilt_dur(EST_Features &e)
116{
117 return e.F("rise_dur") + e.F("fall_dur");
118}
119
120float rfc_to_a_tilt(EST_Features &e)
121{
122 return (float)(fabs(e.F("rise_amp")) - fabs(e.F("fall_amp"))) /
123 (float)(fabs(e.F("rise_amp")) + fabs(e.F("fall_amp")));
124}
125
126float rfc_to_d_tilt(EST_Features &e)
127{
128 return (float)(fabs(e.F("rise_dur")) - fabs(e.F("fall_dur"))) /
129 (float)(e.F("rise_dur") + e.F("fall_dur"));
130}
131
132float rfc_to_t_tilt(EST_Features &e)
133{
134 float t_tilt;
135 t_tilt = (rfc_to_a_tilt(e) + rfc_to_d_tilt(e)) / 2;
136 if (isnanf(t_tilt))
137 t_tilt = 0.0;
138 return t_tilt;
139}
140
141float tilt_to_rise_amp(EST_Features &e)
142{
143 return e.F("amp") * (1 + e.F("tilt")) / 2.0;
144}
145
146float tilt_to_rise_dur(EST_Features &e)
147{
148 return e.F("dur") * (1 + e.F("tilt")) / 2.0;
149}
150
151float tilt_to_fall_amp(EST_Features &e)
152{
153 return -e.F("amp") * (1 - e.F("tilt")) / 2.0;
154}
155
156float tilt_to_fall_dur(EST_Features &e)
157{
158 return e.F("dur") * (1 - e.F("tilt")) / 2.0;
159}
160
161float tilt_to_peak_f0(EST_Item *e)
162{
163 return e->F("ev:start_f0") + tilt_to_rise_amp(e->A("tilt"));
164}
165
166float tilt_to_peak_pos(EST_Item *e)
167{
168 return e->F("start") + tilt_to_rise_dur(e->A("tilt"));
169}
170
171
172void rfc_to_tilt(EST_Features &rfc, EST_Features &tilt)
173{
174 tilt.set("amp", rfc_to_tilt_amp(rfc));
175 tilt.set("dur", rfc_to_tilt_dur(rfc));
176 tilt.set("tilt", rfc_to_t_tilt(rfc));
177}
178
179void rfc_to_tilt(EST_Relation &ev)
180{
181 EST_Item *e;
182 EST_Features f;
183
184 if (ev.f("intonation_style") != "rfc")
185 EST_error("Can't create Tilt parameters from intonation style: %s\n",
186 (const char *)ev.f.S("intonation_style"));
187
188 for (e = ev.head(); e != 0; e = inext(e))
189 if (event_item(*e))
190 {
191 e->set("tilt", f);
192 rfc_to_tilt(e->A("rfc"), e->A("tilt"));
193 }
194 ev.f.set("intonation_style", "tilt");
195}
196
197void tilt_to_rfc(EST_Features &tilt, EST_Features &rfc)
198{
199 rfc.set("rise_amp", tilt_to_rise_amp(tilt));
200 rfc.set("rise_dur", tilt_to_rise_dur(tilt));
201 rfc.set("fall_amp", tilt_to_fall_amp(tilt));
202 rfc.set("fall_dur", tilt_to_fall_dur(tilt));
203}
204
205
206void tilt_to_rfc(EST_Relation &ev)
207{
208 EST_Item *e;
209 EST_Features f;
210
211 if (ev.f("intonation_style") != "tilt")
212 EST_error("Can't create RFC parameters for intonation_style: %s\n",
213 (const char *)ev.f.S("intonation_style"));
214
215 for (e = ev.head(); e ; e = inext(e))
216 if (event_item(*e))
217 {
218 e->set("rfc", f);
219 tilt_to_rfc(e->A("tilt"), e->A("rfc"));
220 }
221
222 ev.f.set("intonation_style", "rfc"); // say that this now contains rfc
223}
224
225void scale_tilt(EST_Relation &ev, float shift, float scale)
226{
227 EST_Item *e;
228
229 for (e = ev.head(); e; e = inext(e))
230 {
231 e->set("ev.f0", (e->F("ev.f0") + shift));
232 if (e->f_present("int_event"))
233 e->set("tilt.amp", (e->F("tilt.amp") * scale));
234 }
235}
236
237void fill_rfc_types(EST_Relation &ev)
238{
239 EST_Item *e;
240
241 for (e = ev.head(); e; e = inext(e))
242 {
243 if (event_item(*e))
244 {
245 if ((e->F("rfc.rise_amp") > 0.0) && (e->F("rfc.fall_amp") < 0.0))
246 e->set("rfc.type", "RISEFALL");
247 else if (e->F("rfc.rise_amp") > 0.0)
248 e->set("rfc.type", "RISE");
249 else
250 e->set("rfc.type", "FALL");
251 }
252 else
253 e->set("rfc.type", "SIL");
254 }
255}
256
257void int_segment_to_unit(EST_Relation &int_lab, EST_Relation &ev_lab)
258{
259 EST_Item *e, *xnext;
260 (void)ev_lab;
261 float start = 0.0;
262
263 if (int_lab.f("timing_style") != "segment")
264 EST_error("Undefined timing style:%s in relation\n",
265 (const char *)int_lab.f.S("timing_style"));
266
267 for (e = int_lab.head(); e != 0; e = inext(e))
268 {
269 e->set("start", start);
270 start = e->F("end");
271 }
272
273 for (e = int_lab.head(); e != 0; e = xnext)
274 {
275 xnext = inext(e);
276 if (event_item(*e) || sil_item(*e))
277 continue;
278 int_lab.remove_item(e);
279 }
280
281/* for (e = int_lab.head(); e != 0; e = xnext)
282 {
283 if (event_item(*e))
284 ev_lab.append(e);
285 }
286*/
287
288 int_lab.f.set("timing_style", "unit");
289
290}
291
292void fn_start_to_real_start(EST_Relation &ev)
293{
294 for (EST_Item *e = ev.head(); e; e = inext(e))
295 e->set("start", e->F("start"));
296}
297
298void set_fn_start(EST_Relation &ev)
299{
300 for (EST_Item *e = ev.head(); e; e = inext(e))
301 e->set_function("start", "standard+start");
302
303}
304
305// this should move to EST_Relation_aux.cc after REORG. This
306// adds a dummy stream_item with no name.
307void event_to_segment(EST_Relation &ev, float min_length)
308{
309 EST_Item *e, *n;
310 EST_Item *dummy;
311
312 // REORG - replace by stream feature
313 if (ev.f.S("timing_style") != "event")
314 return;
315
316 for (e = ev.head(); inext(e) != 0; e = inext(e))
317 {
318 n = inext(e);
319 if ((n->F("start") - e->F("end")) > min_length)
320 {
321 dummy = e->insert_after();
322// dummy->set("end", 19.0);
323 dummy->set("end", n->F("start"));
324// cout << n->F("start") << endl;
325// sleep(2);
326// dummy->set("start", e->F("end"));
327// cout << *n << endl;
328// cout << *dummy << endl;
329// cout << dummy << endl;
330// sleep(1);
331 }
332/* else // make sure starts and ends are now properly contiguous
333 {
334 float pos = (n->F("start") - e->F("end")) / 2.0;
335// cout << "balanced pos = " << pos << endl;
336 e->set("end", pos);
337 n->set("start", pos);
338 }
339*/
340 }
341// cout << "Event to segment\n";
342// cout << ev;
343 set_fn_start(ev);
344
345 // REORG - replace by stream feature
346 ev.f.set("timing_style", "segment");
347// cout << "Event to segment\n";
348// cout << ev;
349
350}
351
352void remove_rfc_features(EST_Relation &ev)
353{
354 for (EST_Item *e = ev.head(); e != 0; e = inext(e))
355 {
356 e->f_remove("rfc.rise_amp");
357 e->f_remove("rfc.rise_dur");
358 e->f_remove("rfc.fall_amp");
359 e->f_remove("rfc.fall_dur");
360 e->f_remove("rfc.type");
361 }
362}
363
364void remove_tilt_features(EST_Relation &ev)
365{
366 for (EST_Item *e = ev.head(); e != 0; e = inext(e))
367 {
368 e->f_remove("tilt.amp");
369 e->f_remove("tilt.dur");
370 e->f_remove("tilt.tilt");
371 }
372}
373
374float unit_curve(float amp, float dur, float t)
375{
376 float val;
377 float x;
378
379 x = (t / (dur)) * 2.0;
380 if (x < 1.0)
381 val = pow(x, float(2.0));
382 else
383 val = 2 - pow((float(2.0) - x), float(2.0));
384
385 val = (val / 2.0);
386
387 val *= amp;
388 val += 0; // vert dist.
389
390 return val;
391}
392
393float fncurve(float length, float t, float curve)
394{
395 float val;
396 float x;
397
398 x = (t / length) * 2.0;
399
400 if (x < 1.0)
401 val = pow(x, curve);
402 else
403 val = 2 - pow((2 - x), curve);
404
405 val = val / 2.0;
406
407 return val;
408}
409
410int event_item(EST_Item &e)
411{
412 return e.I("int_event", 0);
413}
414int sil_item(EST_Item &e)
415{
416 return ((e.name() == "sil") || (e.name() == "SIL"));
417}
418int connection_item(EST_Item &e)
419{
420 return ((e.name() == "c") || (e.name() == "C"));
421}
void set(const EST_String &name, int ival)
Definition: EST_Features.h:185
const float F(const EST_String &path) const
Definition: EST_Features.h:135
const EST_String S(const EST_String &path) const
Definition: EST_Features.h:157
const int I(const EST_String &name) const
Definition: EST_Item.h:154
void set(const EST_String &name, int ival)
Definition: EST_Item.h:179
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 set_function(const EST_String &name, const EST_String &funcname)
Definition: EST_Item.h:201
void f_remove(const EST_String &name)
Definition: EST_Item.h:222
int f_present(const EST_String &name) const
Definition: EST_Item.h:230
void remove_item(EST_Item *item)
EST_Features f
Definition: EST_Relation.h:103
EST_Item * head() const
Definition: EST_Relation.h:125