"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:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "tilt_synthesis.cc" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.4-release_vs_2.5.0-release.

    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 */