| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- /*************************************************************************/
- /* */
- /* Language Technologies Institute */
- /* Carnegie Mellon University */
- /* Copyright (c) 2001 */
- /* All Rights Reserved. */
- /* */
- /* Permission is hereby granted, free of charge, to use and distribute */
- /* this software and its documentation without restriction, including */
- /* without limitation the rights to use, copy, modify, merge, publish, */
- /* distribute, sublicense, and/or sell copies of this work, and to */
- /* permit persons to whom this work is furnished to do so, subject to */
- /* the following conditions: */
- /* 1. The code must retain the above copyright notice, this list of */
- /* conditions and the following disclaimer. */
- /* 2. Any modifications must be clearly marked as such. */
- /* 3. Original authors' names are not deleted. */
- /* 4. The authors' names are not used to endorse or promote products */
- /* derived from this software without specific prior written */
- /* permission. */
- /* */
- /* CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK */
- /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
- /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
- /* SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE */
- /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
- /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
- /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
- /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
- /* THIS SOFTWARE. */
- /* */
- /*************************************************************************/
- /* Author: Alan W Black (awb@cs.cmu.edu) */
- /* Date: January 2001 */
- /*************************************************************************/
- /* */
- /* An F0 model */
- /* This is derived fromthe f2b model freely distributed in Festival */
- /* */
- /*************************************************************************/
- #include "cst_hrg.h"
- #include "cst_phoneset.h"
- #include "us_f0.h"
- static void apply_lr_model(cst_item *s,
- const us_f0_lr_term *f0_lr_terms,
- float *start,
- float *mid,
- float *end)
- {
- int i;
- const cst_val *v=0;
- float fv;
- /* Interceptors */
- *start = f0_lr_terms[0].start;
- *mid = f0_lr_terms[0].mid;
- *end = f0_lr_terms[0].end;
- for (i=1; f0_lr_terms[i].feature; i++)
- {
- if (!cst_streq(f0_lr_terms[i].feature,f0_lr_terms[i-1].feature))
- v = ffeature(s,f0_lr_terms[i].feature);
- if (f0_lr_terms[i].type)
- {
- if (cst_streq(val_string(v),f0_lr_terms[i].type))
- fv = 1.0;
- else
- fv = 0.0;
- }
- else
- fv = val_float(v);
- (*start) += fv*f0_lr_terms[i].start;
- (*mid) += fv*f0_lr_terms[i].mid;
- (*end) += fv*f0_lr_terms[i].end;
- /* printf("f %s start %f mid %f end %f\n",
- f0_lr_terms[i].feature,
- *start,*mid,*end); */
- }
- }
- static void add_target_point(cst_relation *targ,float pos, float f0)
- {
- cst_item *t;
- /* printf("target %f at %f\n",f0,pos); */
- t = relation_append(targ,NULL);
- item_set_float(t,"pos",pos);
- /* them there can sometimes do silly things, so guard for that */
- if (f0 > 500.0)
- item_set_float(t,"f0",500.0);
- else if (f0 < 50.0)
- item_set_float(t,"f0",50.0);
- else
- item_set_float(t,"f0",f0);
- }
- /* model mean and stddev take from f2b/kal_diphone */
- #define model_mean 170.0
- #define model_stddev 34
- #define map_f0(v,m,s) ((((v-model_mean)/model_stddev)*s)+m)
- static int post_break(cst_item *syl)
- {
- if ((item_prev(syl) == 0) ||
- (cst_streq("pau",
- ffeature_string(syl,
- "R:SylStructure.daughter.R:Segment.p.name"))))
- return TRUE;
- else
- return FALSE;
- }
- static int pre_break(cst_item *syl)
- {
- if ((item_next(syl) == 0) ||
- (cst_streq("pau",
- ffeature_string(syl,
- "R:SylStructure.daughtern.R:Segment.n.name"))))
- return TRUE;
- else
- return FALSE;
- }
- static float vowel_mid(cst_item *syl)
- {
- /* return time point mid way in vowel in this syl */
- cst_item *s;
- cst_item *ts;
- const cst_phoneset *ps = item_phoneset(syl);
- ts = item_daughter(item_as(syl,"SylStructure"));
- for (s=ts; s; s = item_next(s))
- {
- if (cst_streq("+", phone_feature_string(ps,item_feat_string(s,"name"),
- "vc")))
- {
- return (item_feat_float(s,"end")+
- ffeature_float(s,"R:Segment.p.end"))/2.0;
- }
- }
- /* no segments, shouldn't happen */
- if (ts == 0)
- return 0;
- /* no vowel in syllable, shouldn't happen */
- return (item_feat_float(ts,"end")+
- ffeature_float(ts,"R:Segment.p.end"))/2.0;
- }
- cst_utterance *us_f0_model(cst_utterance *u)
- {
- /* F0 target model: Black and Hunt ICSLP96, three points per syl */
- cst_item *syl, *t, *nt;
- cst_relation *targ_rel;
- float mean, stddev, local_mean, local_stddev;
- float start, mid, end, lend;
- float seg_end;
- if (feat_present(u->features,"no_f0_target_model"))
- return u;
- targ_rel = utt_relation_create(u,"Target");
- mean = get_param_float(u->features,"int_f0_target_mean", 100.0);
- mean *= get_param_float(u->features,"f0_shift", 1.0);
- stddev = get_param_float(u->features,"int_f0_target_stddev", 12.0);
-
- lend = 0;
- for (syl=relation_head(utt_relation(u,"Syllable"));
- syl;
- syl = item_next(syl))
- {
- /* printf("word %s, accent %s endtone %s\n",
- ffeature_string(syl,"R:SylStructure.parent.name"),
- ffeature_string(syl,"accent"),
- ffeature_string(syl,"endtone")); */
- if (!item_daughter(item_as(syl,"SylStructure")))
- continue; /* no segs in syl */
- local_mean = ffeature_float(syl,"R:SylStructure.parent.R:Token.parent.local_f0_shift");
- if (local_mean)
- local_mean *= mean;
- else
- local_mean = mean;
- local_stddev = ffeature_float(syl,"R:SylStructure.parent.R:Token.parent.local_f0_range");
- if (local_stddev == 0.0)
- local_stddev = stddev;
- apply_lr_model(syl,f0_lr_terms,&start,&mid,&end);
- if (post_break(syl))
- lend = map_f0(start,local_mean,local_stddev);
- add_target_point(targ_rel,
- ffeature_float(syl,
- "R:SylStructure.daughter.R:Segment.p.end"),
- map_f0((start+lend)/2.0,local_mean,local_stddev));
- add_target_point(targ_rel,
- vowel_mid(syl),
- map_f0(mid,local_mean,local_stddev));
- lend = map_f0(end,local_mean,local_stddev);
- if (pre_break(syl))
- add_target_point(targ_rel,
- ffeature_float(syl,"R:SylStructure.daughtern.end"),
- map_f0(end,local_mean,local_stddev));
- }
-
- /* Guarantee targets go from start to end of utterance */
- t = relation_head(targ_rel);
- if (t == 0)
- add_target_point(targ_rel,0,mean);
- else if (item_feat_float(t,"pos") > 0)
- {
- nt = item_prepend(t,NULL);
- item_set_float(nt,"pos",0.0);
- item_set_float(nt,"f0",item_feat_float(t,"f0"));
- }
-
- t = relation_tail(targ_rel);
- seg_end = item_feat_float(relation_tail(utt_relation(u,"Segment")),"end");
- if (item_feat_float(t,"pos") < seg_end)
- add_target_point(targ_rel,seg_end,item_feat_float(t,"f0"));
- return u;
- }
|