ref: c5bd2add37725041c1924132a8a4fd67548fb975
dir: /src/synth/cst_ffeatures.c/
/*************************************************************************/ /* */ /* Language Technologies Institute */ /* Carnegie Mellon University */ /* Copyright (c) 2007 */ /* 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: November 2007 */ /*************************************************************************/ /* */ /* Some language independent features */ /* */ #include "cst_hrg.h" #include "cst_phoneset.h" #include "cst_regex.h" static const cst_val *word_break(const cst_item *word); static const cst_val *word_punc(const cst_item *word); static const cst_val *word_numsyls(const cst_item *word); static const cst_val *ssyl_in(const cst_item *syl); static const cst_val *syl_in(const cst_item *syl); static const cst_val *syl_out(const cst_item *syl); static const cst_val *syl_break(const cst_item *syl); static const cst_val *syl_codasize(const cst_item *syl); static const cst_val *syl_onsetsize(const cst_item *syl); static const cst_val *accented(const cst_item *p); DEF_STATIC_CONST_VAL_STRING(val_string_onset,"onset"); DEF_STATIC_CONST_VAL_STRING(val_string_coda,"coda"); DEF_STATIC_CONST_VAL_STRING(val_string_initial,"initial"); DEF_STATIC_CONST_VAL_STRING(val_string_single,"single"); DEF_STATIC_CONST_VAL_STRING(val_string_final,"final"); DEF_STATIC_CONST_VAL_STRING(val_string_mid,"mid"); DEF_STATIC_CONST_VAL_STRING(val_string_empty,""); const cst_val *ph_vc(const cst_item *p) { return phone_feature(item_phoneset(p),item_name(p),"vc"); } const cst_val *ph_vlng(const cst_item *p) { return phone_feature(item_phoneset(p),item_name(p),"vlng"); } const cst_val *ph_vheight(const cst_item *p) { return phone_feature(item_phoneset(p),item_name(p),"vheight"); } const cst_val *ph_vrnd(const cst_item *p) { return phone_feature(item_phoneset(p),item_name(p),"vrnd"); } const cst_val *ph_vfront(const cst_item *p) { return phone_feature(item_phoneset(p),item_name(p),"vfront"); } const cst_val *ph_ctype(const cst_item *p) { return phone_feature(item_phoneset(p),item_name(p),"ctype"); } const cst_val *ph_cplace(const cst_item *p) { return phone_feature(item_phoneset(p),item_name(p),"cplace"); } const cst_val *ph_cvox(const cst_item *p) { return phone_feature(item_phoneset(p),item_name(p),"cvox"); } const cst_val *cg_duration(const cst_item *p) { /* Note this constructs float vals, these will be freed when the */ /* cart cache is freed, so this should only be used in carts */ if (!p) return float_val(0.0); else if (!item_prev(p)) return item_feat(p,"end"); else return float_val(item_feat_float(p,"end") - item_feat_float(item_prev(p),"end")); } DEF_STATIC_CONST_VAL_STRING(val_string_pos_b,"b"); DEF_STATIC_CONST_VAL_STRING(val_string_pos_m,"m"); DEF_STATIC_CONST_VAL_STRING(val_string_pos_e,"e"); const cst_val *cg_state_pos(const cst_item *p) { const char *name; name = item_feat_string(p,"name"); if (!cst_streq(name,ffeature_string(p,"p.name"))) return (cst_val *)&val_string_pos_b; if (cst_streq(name,ffeature_string(p,"n.name"))) return (cst_val *)&val_string_pos_m; else return (cst_val *)&val_string_pos_e; } const cst_val *cg_state_place(const cst_item *p) { float start, end; int thisone; start = (float)ffeature_int(p,"R:mcep_link.parent.daughter1.frame_number"); end = (float)ffeature_int(p,"R:mcep_link.parent.daughtern.frame_number"); thisone = item_feat_int(p,"frame_number"); if ((end-start) == 0.0) return float_val(0.0); else return float_val((thisone-start)/(end-start)); } const cst_val *cg_state_index(const cst_item *p) { float start; int thisone; start = (float)ffeature_int(p,"R:mcep_link.parent.daughter1.frame_number"); thisone = item_feat_int(p,"frame_number"); return float_val(thisone-start); } const cst_val *cg_state_rindex(const cst_item *p) { float end; int thisone; end = (float)ffeature_int(p,"R:mcep_link.parent.daughtern.frame_number"); thisone = item_feat_int(p,"frame_number"); return float_val(end-thisone); } const cst_val *cg_phone_place(const cst_item *p) { float start, end; int thisone; start = (float)ffeature_int(p,"R:mcep_link.parent.R:segstate.parent.daughter1.R:mcep_link.daughter1.frame_number"); end = (float)ffeature_int(p,"R:mcep_link.parent.R:segstate.parent.daughtern.R:mcep_link.daughtern.frame_number"); thisone = item_feat_int(p,"frame_number"); if ((end-start) == 0.0) return float_val(0.0); else return float_val((thisone-start)/(end-start)); } const cst_val *cg_phone_index(const cst_item *p) { float start; int thisone; start = (float)ffeature_int(p,"R:mcep_link.parent.R:segstate.parent.daughter1.R:mcep_link.daughter1.frame_number"); thisone = item_feat_int(p,"frame_number"); return float_val(thisone-start); } const cst_val *cg_phone_rindex(const cst_item *p) { float end; int thisone; end = (float)ffeature_int(p,"R:mcep_link.parent.R:segstate.parent.daughtern.R:mcep_link.daughtern.frame_number"); thisone = item_feat_int(p,"frame_number"); return float_val(end-thisone); } const cst_val *cg_is_pau(const cst_item *p) { if (p && cst_streq("pau",item_feat_string(p,"name"))) return &val_int_1; else return &val_int_0; } const cst_val *cg_find_phrase_number(const cst_item *p) { const cst_item *v; int x = 0; for (v=item_prev(p); v; v=item_prev(v)) x++; return val_int_n(x); } const cst_val *cg_position_in_phrasep(const cst_item *p) { float pstart, pend, phrasenumber; float x; #define CG_FRAME_SHIFT 0.005 pstart = ffeature_float(p,"R:mcep_link.parent.R:segstate.parent.R:SylStructure.parent.parent.R:Phrase.parent.daughter1.R:SylStructure.daughter1.daughter1.R:Segment.p.end"); pend = ffeature_float(p,"R:mcep_link.parent.R:segstate.parent.R:SylStructure.parent.parent.R:Phrase.parent.daughtern.R:SylStructure.daughtern.daughtern.R:Segment.end"); phrasenumber = ffeature_float(p,"R:mcep_link.parent.R:segstate.parent.R:SylStructure.parent.parent.R:Phrase.parent.lisp_cg_find_phrase_number"); if ((pend - pstart) == 0.0) return float_val(-1.0); else { x = phrasenumber + ((CG_FRAME_SHIFT*item_feat_float(p,"frame_number"))-pstart) / (pend - pstart); return float_val(x); } } const cst_val *cg_position_in_phrase(const cst_item *p) { float pstart, pend; float x; #define CG_FRAME_SHIFT 0.005 pstart = ffeature_float(p,"R:mcep_link.parent.R:segstate.parent.R:SylStructure.parent.parent.R:Phrase.parent.daughter1.R:SylStructure.daughter1.daughter1.R:Segment.p.end"); pend = ffeature_float(p,"R:mcep_link.parent.R:segstate.parent.R:SylStructure.parent.parent.R:Phrase.parent.daughtern.R:SylStructure.daughtern.daughtern.R:Segment.end"); if ((pend - pstart) == 0.0) return float_val(-1.0); else { x = 0 + ((CG_FRAME_SHIFT*item_feat_float(p,"frame_number"))-pstart) / (pend - pstart); return float_val(x); } } const cst_val *cg_position_in_sentence(const cst_item *p) { float sstart, send; float x; #define CG_FRAME_SHIFT 0.005 sstart = ffeature_float(p,"R:mcep_link.parent.R:segstate.parent.R:SylStructure.parent.parent.R:Word.first.R:SylStructure.daughter1.daughter1.R:Segment.p.end"); send = ffeature_float(p,"R:mcep_link.parent.R:segstate.parent.R:SylStructure.parent.parent.R:Word.last.R:SylStructure.daughtern.daughtern.R:Segment.end"); if ((send - sstart) == 0.0) return float_val(-1.0); else { x = ((CG_FRAME_SHIFT*item_feat_float(p,"frame_number"))-sstart) / (send - sstart); return float_val(x); } } /* Spam specific features, but may be useful for others */ const cst_val *pos_in_word(const cst_item *p) { const cst_item *s; int i=0; p=item_as(p,"Syllable"); s=item_as(path_to_item(p,"R:SylStructure.parent.daughter1"),"Syllable"); for (;s && !item_equal(p,s);s=item_next(s),i++){} return val_string_n(i); } const cst_val *syllable_duration(const cst_item *p) { return float_val(ffeature_float(p,"R:SylStructure.daughtern.R:Segment.end") - ffeature_float(p,"R:SylStructure.daughter1.R:Segment.p.end")); } const cst_val *syl_vowel(const cst_item *p) { const cst_item *s,*ls; s=item_as(path_to_item(p,"R:SylStructure.daughter1"),"Segment"); ls=item_as(path_to_item(p,"R:SylStructure.daughtern"),"Segment"); for(;s && !item_equal(s,ls);s=item_next(s)) { if (cst_streq("+",val_string(ph_vc(s)))) { return string_val(item_name(s)); } } if (cst_streq("+",val_string(ph_vc(s)))) { return string_val(item_name(s)); } return (cst_val *) NULL; } const cst_val *syl_numphones(const cst_item *p) { int i; const cst_item *s,*ls; s=item_as(path_to_item(p,"R:SylStructure.daughter1"),"Segment"); ls=item_as(path_to_item(p,"R:SylStructure.daughtern"),"Segment"); for(i=1;s && !item_equal(s,ls);s=item_next(s)){i++;} return val_string_n(i); } const cst_val *pos_in_phrase(const cst_item *p) { const cst_item *s; int i=0; p=item_as(p,"Word"); s=item_as(path_to_item(p,"R:SylStructure.R:Phrase.parent.daughter1"),"Word"); for (;s && !item_equal(p,s);s=item_next(s),i++){} return val_string_n(i); } const cst_val *cg_syl_ratio(const cst_item *p) { return float_val (( 1 + ffeature_float(p,"syl_in"))/(1 + ffeature_float(p,"syl_in") + ffeature_float(p,"syl_out"))); } const cst_val *cg_phrase_ratio(const cst_item *p) { const cst_item *lp=p; while(item_next(lp)){lp=item_next(lp);} return float_val ((1 + ffeature_float(p,"lisp_cg_find_phrase_number"))/(1 + ffeature_float(lp,"lisp_cg_find_phrase_number"))); } const cst_val *cg_syls_in_phrase(const cst_item *p) { cst_item *s=item_as(item_daughter(p),"Word"); return float_val(1 + ffeature_float(s,"R:SylStructure.daughter1.R:Syllable.syl_out")); } static const cst_val *accented(const cst_item *syl) { if ((item_feat_present(syl,"accent")) || (item_feat_present(syl,"endtone"))) return VAL_STRING_1; else return VAL_STRING_0; } static const cst_val *seg_coda_ctype(const cst_item *seg, const char *ctype) { const cst_item *s; const cst_phoneset *ps = item_phoneset(seg); for (s=item_last_daughter(item_parent(item_as(seg,"SylStructure"))); s; s=item_prev(s)) { if (cst_streq("+",phone_feature_string(ps,item_feat_string(s,"name"), "vc"))) return VAL_STRING_0; if (cst_streq(ctype,phone_feature_string(ps,item_feat_string(s,"name"), "ctype"))) return VAL_STRING_1; } return VAL_STRING_0; } static const cst_val *seg_onset_ctype(const cst_item *seg, const char *ctype) { const cst_item *s; const cst_phoneset *ps = item_phoneset(seg); for (s=item_daughter(item_parent(item_as(seg,"SylStructure"))); s; s=item_next(s)) { if (cst_streq("+",phone_feature_string(ps,item_feat_string(s,"name"), "vc"))) return VAL_STRING_0; if (cst_streq(ctype,phone_feature_string(ps,item_feat_string(s,"name"), "ctype"))) return VAL_STRING_1; } return VAL_STRING_0; } static const cst_val *seg_coda_fric(const cst_item *seg) { return seg_coda_ctype(seg,"f"); } static const cst_val *seg_onset_fric(const cst_item *seg) { return seg_onset_ctype(seg,"f"); } static const cst_val *seg_coda_stop(const cst_item *seg) { return seg_coda_ctype(seg,"s"); } static const cst_val *seg_onset_stop(const cst_item *seg) { return seg_onset_ctype(seg,"s"); } static const cst_val *seg_coda_nasal(const cst_item *seg) { return seg_coda_ctype(seg,"n"); } static const cst_val *seg_onset_nasal(const cst_item *seg) { return seg_onset_ctype(seg,"n"); } static const cst_val *seg_coda_glide(const cst_item *seg) { if (seg_coda_ctype(seg,"r") == VAL_STRING_0) return seg_coda_ctype(seg,"l"); return VAL_STRING_1; } static const cst_val *seg_onset_glide(const cst_item *seg) { if (seg_onset_ctype(seg,"r") == VAL_STRING_0) return seg_onset_ctype(seg,"l"); return VAL_STRING_1; } static const cst_val *seg_onsetcoda(const cst_item *seg) { const cst_item *s; const cst_phoneset *ps = item_phoneset(seg); if (!seg) return VAL_STRING_0; for (s=item_next(item_as(seg,"SylStructure")); s; s=item_next(s)) { if (cst_streq("+",phone_feature_string(ps,item_feat_string(s,"name"), "vc"))) return (cst_val *)&val_string_onset; } return (cst_val *)&val_string_coda; } static const cst_val *pos_in_syl(const cst_item *seg) { const cst_item *s; int c; for (c=-1,s=item_as(seg,"SylStructure"); s; s=item_prev(s),c++); return val_string_n(c); } static const cst_val *position_type(const cst_item *syl) { const cst_item *s = item_as(syl,"SylStructure"); if (s == 0) return (cst_val *)&val_string_single; else if (item_next(s) == 0) { if (item_prev(s) == 0) return (cst_val *)&val_string_single; else return (cst_val *)&val_string_final; } else if (item_prev(s) == 0) return (cst_val *)&val_string_initial; else return (cst_val *)&val_string_mid; } static const cst_val *sub_phrases(const cst_item *syl) { const cst_item *s; int c; for (c=0,s=path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.p"); s && (c < CST_CONST_INT_MAX); s=item_prev(s),c++); return val_string_n(c); } static const cst_val *last_accent(const cst_item *syl) { const cst_item *s; int c; for (c=0,s=item_as(syl,"Syllable"); s && (c < CST_CONST_INT_MAX); s=item_prev(s),c++) { if (val_int(accented(s))) return val_string_n(c); } return val_string_n(c); } static const cst_val *next_accent(const cst_item *syl) { const cst_item *s; int c; s=item_as(syl,"Syllable"); if (s) s = item_next(s); else return val_string_n(0); for (c=0; s && (c < CST_CONST_INT_MAX); s=item_next(s),c++) { if (val_int(accented(s))) return val_string_n(c); } return val_string_n(c); } static const cst_val *syl_final(const cst_item *seg) { /* last segment in a syllable */ const cst_item *s = item_as(seg,"SylStructure"); if (!s || (item_next(s) == NULL)) return VAL_STRING_1; else return VAL_STRING_0; } static const cst_val *syl_initial(const cst_item *seg) { /* first segment in a syllable */ const cst_item *s = item_as(seg,"SylStructure"); if (!s || (item_prev(s) == NULL)) return VAL_STRING_1; else return VAL_STRING_0; } static const cst_val *word_punc(const cst_item *word) { cst_item *ww; const cst_val *v; ww = item_as(word,"Token"); if ((ww != NULL) && (item_next(ww) != 0)) v = &val_string_empty; else v = ffeature(item_parent(ww),"punc"); /* printf("word_punc word %s punc %s\n", item_feat_string(ww,"name"), val_string(v)); */ return v; } static const cst_val *word_break(const cst_item *word) { cst_item *ww,*pp; const char *pname; ww = item_as(word,"Phrase"); if ((ww == NULL) || (item_next(ww) != 0)) return VAL_STRING_1; else { pp = item_parent(ww); pname = val_string(item_feat(pp,"name")); if (cst_streq("BB",pname)) return VAL_STRING_4; else if (cst_streq("B",pname)) return VAL_STRING_3; else return VAL_STRING_1; } } static const cst_val *word_numsyls(const cst_item *word) { cst_item *d; int c; for (c=0,d=item_daughter(item_as(word,"SylStructure")); d; d=item_next(d),c++); return val_int_n(c); } static const cst_val *ssyl_in(const cst_item *syl) { /* Number of stressed syllables since last major break */ const cst_item *ss,*p,*fs; int c; ss = item_as(syl,"Syllable"); fs = path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.daughter.R:SylStructure.daughter"); #if 1 /* fix by uratec */ if(item_equal(ss,fs)) return val_string_n(0); #else /* This should actually include the first syllable, but Festival's doesn't. */ #endif for (c=0, p=item_prev(ss); p && (!item_equal(p,fs)) && (c < CST_CONST_INT_MAX); p=item_prev(p)) { if (cst_streq("1",ffeature_string(p,"stress"))) c++; } return val_string_n(c); /* its used randomly as int and float */ } static const cst_val *ssyl_out(const cst_item *syl) { /* Number of stressed syllables until last major break */ const cst_item *ss,*p,*fs; int c; ss = item_as(syl,"Syllable"); fs = path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.daughtern.R:SylStructure.daughtern"); #if 1 /* fix by uratec */ if(item_equal(ss,fs)) return val_string_n(0); #endif for (c=0, p=item_next(ss); p && (c < CST_CONST_INT_MAX); p=item_next(p)) { if (cst_streq("1",ffeature_string(p,"stress"))) c++; if (item_equal(p,fs)) break; } return val_string_n(c); /* its used randomly as int and float */ } static const cst_val *syl_in(const cst_item *syl) { /* Number of syllables since last major break */ const cst_item *ss,*p,*fs; int c; ss = item_as(syl,"Syllable"); fs = path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.daughter.R:SylStructure.daughter"); for (c=0, p=ss; p && (c < CST_CONST_INT_MAX); p=item_prev(p),c++) if (item_equal(p,fs)) break; return val_string_n(c); } static const cst_val *syl_out(const cst_item *syl) { /* Number of syllables until next major break */ cst_item *ss,*p; const cst_item *fs; int c; ss = item_as(syl,"Syllable"); fs = path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.daughtern.R:SylStructure.daughtern"); for (c=0, p=ss; p && (c < CST_CONST_INT_MAX); p=item_next(p),c++) if (item_equal(p,fs)) break; return val_string_n(c); } static const cst_val *syl_break(const cst_item *syl) { /* Break level after this syllable */ cst_item *ss; ss = item_as(syl,"SylStructure"); if (ss == NULL) return VAL_STRING_1; /* hmm, no sylstructure */ else if (item_next(ss) != NULL) return VAL_STRING_0; /* word internal */ else if (item_parent(ss) == NULL) /* no parent */ return VAL_STRING_1; else return word_break(item_parent(ss)); } static const cst_val *cg_break(const cst_item *syl) { /* phrase prediction is so different between flite and festival */ /* we go with this more robust technique */ cst_item *ss; ss = item_as(syl,"SylStructure"); if (ss == NULL) return VAL_STRING_0; /* hmm, no sylstructure */ else if (item_next(ss) != NULL) return VAL_STRING_0; /* word internal */ else if (path_to_item(ss,"R:SylStructure.parent.R:Word.n") == NULL) return VAL_STRING_4; /* utterance final */ else if (path_to_item(ss,"R:SylStructure.parent.R:Phrase.n") == NULL) return VAL_STRING_3; /* phrase final */ else return VAL_STRING_1; /* word final */ } static const cst_val *syl_codasize(const cst_item *syl) { cst_item *d; int c; for (c=1,d=item_last_daughter(item_as(syl,"SylStructure")); d; d=item_prev(d),c++) { if (cst_streq("+",val_string(ph_vc(d)))) break; } return val_string_n(c); } static const cst_val *syl_onsetsize(const cst_item *syl) { cst_item *d; int c; for (c=0,d=item_daughter(item_as(syl,"SylStructure")); d; d=item_next(d),c++) { if (cst_streq("+",val_string(ph_vc(d)))) break; } return val_string_n(c); } static const cst_val *asyl_in(const cst_item *syl) { /* Number of accented syllables since last major break */ const cst_item *ss,*p,*fs; int c; ss = item_as(syl,"Syllable"); fs = path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.daughter.R:SylStructure.daughter"); #if 1 /* fix by uratec */ if(item_equal(ss,fs)) return val_string_n(0); for (c=0, p=item_prev(ss); #else for (c=0, p=ss; #endif p && (c < CST_CONST_INT_MAX); p=item_prev(p)) { if (val_int(accented(p)) == 1) c++; if (item_equal(p,fs)) break; } return val_string_n(c); } static const cst_val *asyl_out(const cst_item *syl) { /* Number of accented syllables until next major break */ cst_item *ss,*p; const cst_item *fs; int c; ss = item_as(syl,"Syllable"); fs = path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.daughtern.R:SylStructure.daughtern"); #if 1 /* fix by uratec */ if(item_equal(ss,fs)) return val_string_n(0); for (c=0, p=item_next(ss); #else for (c=0, p=ss; #endif p && (c < CST_CONST_INT_MAX); p=item_next(p)) { if (val_int(accented(p)) == 1) c++; if (item_equal(p,fs)) break; } return val_string_n(c); } static const cst_val *segment_duration(const cst_item *seg) { const cst_item *s = item_as(seg,"Segment"); if (!s) return VAL_STRING_0; else if (item_prev(s) == NULL) return item_feat(s,"end"); else { /* It should be okay to construct this as it will get dereferenced when the CART interpreter frees its feature cache. */ return float_val(item_feat_float(s,"end") - item_feat_float(item_prev(s),"end")); } } void basic_ff_register(cst_features *ffunctions) { ff_register(ffunctions, "ph_vc",ph_vc); ff_register(ffunctions, "ph_vlng",ph_vlng); ff_register(ffunctions, "ph_vheight",ph_vheight); ff_register(ffunctions, "ph_vfront",ph_vfront); ff_register(ffunctions, "ph_vrnd",ph_vrnd); ff_register(ffunctions, "ph_ctype",ph_ctype); ff_register(ffunctions, "ph_cplace",ph_cplace); ff_register(ffunctions, "ph_cvox",ph_cvox); ff_register(ffunctions, "lisp_cg_duration", cg_duration); ff_register(ffunctions, "lisp_cg_state_pos", cg_state_pos); ff_register(ffunctions, "lisp_cg_state_place", cg_state_place); ff_register(ffunctions, "lisp_cg_state_index", cg_state_index); ff_register(ffunctions, "lisp_cg_state_rindex", cg_state_rindex); ff_register(ffunctions, "lisp_cg_phone_place", cg_phone_place); ff_register(ffunctions, "lisp_cg_phone_index", cg_phone_index); ff_register(ffunctions, "lisp_cg_phone_rindex", cg_phone_rindex); ff_register(ffunctions, "lisp_cg_position_in_phrasep", cg_position_in_phrasep); ff_register(ffunctions, "lisp_cg_position_in_phrase", cg_position_in_phrase); ff_register(ffunctions, "lisp_cg_position_in_sentence", cg_position_in_sentence); ff_register(ffunctions, "lisp_cg_find_phrase_number", cg_find_phrase_number); ff_register(ffunctions, "lisp_is_pau", cg_is_pau); ff_register(ffunctions, "word_numsyls",word_numsyls); ff_register(ffunctions, "word_break",word_break); ff_register(ffunctions, "word_punc",word_punc); ff_register(ffunctions, "ssyl_in",ssyl_in); ff_register(ffunctions, "ssyl_out",ssyl_out); ff_register(ffunctions, "syl_in",syl_in); ff_register(ffunctions, "syl_out",syl_out); ff_register(ffunctions, "syl_break",syl_break); ff_register(ffunctions, "lisp_cg_break",cg_break); ff_register(ffunctions, "old_syl_break",syl_break); ff_register(ffunctions, "syl_onsetsize",syl_onsetsize); ff_register(ffunctions, "syl_codasize",syl_codasize); ff_register(ffunctions, "accented",accented); ff_register(ffunctions, "asyl_in",asyl_in); ff_register(ffunctions, "asyl_out",asyl_out); ff_register(ffunctions, "lisp_coda_fric",seg_coda_fric); ff_register(ffunctions, "lisp_onset_fric",seg_onset_fric); ff_register(ffunctions, "lisp_coda_stop",seg_coda_stop); ff_register(ffunctions, "lisp_onset_stop",seg_onset_stop); ff_register(ffunctions, "lisp_coda_nasal",seg_coda_nasal); ff_register(ffunctions, "lisp_onset_nasal",seg_onset_nasal); ff_register(ffunctions, "lisp_coda_glide",seg_coda_glide); ff_register(ffunctions, "lisp_onset_glide",seg_onset_glide); ff_register(ffunctions, "seg_onsetcoda",seg_onsetcoda); ff_register(ffunctions, "pos_in_syl",pos_in_syl); ff_register(ffunctions, "position_type",position_type); ff_register(ffunctions, "sub_phrases",sub_phrases); ff_register(ffunctions, "last_accent",last_accent); ff_register(ffunctions, "next_accent",next_accent); ff_register(ffunctions, "syl_final",syl_final); ff_register(ffunctions, "syl_initial",syl_initial); ff_register(ffunctions, "segment_duration",segment_duration); ff_register(ffunctions, "lisp_cg_syl_ratio",cg_syl_ratio); ff_register(ffunctions, "lisp_cg_phrase_ratio",cg_phrase_ratio); ff_register(ffunctions, "lisp_cg_syls_in_phrase",cg_syls_in_phrase); ff_register(ffunctions, "pos_in_phrase",pos_in_phrase); ff_register(ffunctions, "pos_in_word",pos_in_word); ff_register(ffunctions, "syllable_duration",syllable_duration); ff_register(ffunctions, "syl_vowel",syl_vowel); ff_register(ffunctions, "syl_numphones",syl_numphones); }