515 lines
19 KiB
C
515 lines
19 KiB
C
|
/*************************************************************************/
|
||
|
/* */
|
||
|
/* 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 */
|
||
|
/*************************************************************************/
|
||
|
/* Feature functions used by various cart trees etc */
|
||
|
/* These have been create as needed, and as some of the trees are */
|
||
|
/* from University of Edinburgh's Festival system their names and */
|
||
|
/* semantics follow them */
|
||
|
/*************************************************************************/
|
||
|
|
||
|
/* ----------------------------------------------------------------- */
|
||
|
/* The English TTS System "Flite+hts_engine" */
|
||
|
/* developed by HTS Working Group */
|
||
|
/* http://hts-engine.sourceforge.net/ */
|
||
|
/* ----------------------------------------------------------------- */
|
||
|
/* */
|
||
|
/* Copyright (c) 2005-2013 Nagoya Institute of Technology */
|
||
|
/* Department of Computer Science */
|
||
|
/* */
|
||
|
/* 2005-2008 Tokyo Institute of Technology */
|
||
|
/* Interdisciplinary Graduate School of */
|
||
|
/* Science and Engineering */
|
||
|
/* */
|
||
|
/* All rights reserved. */
|
||
|
/* */
|
||
|
/* Redistribution and use in source and binary forms, with or */
|
||
|
/* without modification, are permitted provided that the following */
|
||
|
/* conditions are met: */
|
||
|
/* */
|
||
|
/* - Redistributions of source code must retain the above copyright */
|
||
|
/* notice, this list of conditions and the following disclaimer. */
|
||
|
/* - Redistributions in binary form must reproduce the above */
|
||
|
/* copyright notice, this list of conditions and the following */
|
||
|
/* disclaimer in the documentation and/or other materials provided */
|
||
|
/* with the distribution. */
|
||
|
/* - Neither the name of the HTS working group nor the names of its */
|
||
|
/* contributors may be used to endorse or promote products derived */
|
||
|
/* from this software without specific prior written permission. */
|
||
|
/* */
|
||
|
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND */
|
||
|
/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, */
|
||
|
/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
|
||
|
/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
|
||
|
/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS */
|
||
|
/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */
|
||
|
/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
|
||
|
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
|
||
|
/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
|
||
|
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */
|
||
|
/* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY */
|
||
|
/* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||
|
/* POSSIBILITY OF SUCH DAMAGE. */
|
||
|
/* ----------------------------------------------------------------- */
|
||
|
|
||
|
#include "cst_hrg.h"
|
||
|
#include "cst_phoneset.h"
|
||
|
#include "cst_regex.h"
|
||
|
#include "cst_ffeatures.h"
|
||
|
#include "us_ffeatures.h"
|
||
|
|
||
|
static const cst_val *gpos(const cst_item *word);
|
||
|
|
||
|
DEF_STATIC_CONST_VAL_STRING(val_string_numeric,"numeric");
|
||
|
DEF_STATIC_CONST_VAL_STRING(val_string_number,"number");
|
||
|
DEF_STATIC_CONST_VAL_STRING(val_string_month,"month");
|
||
|
DEF_STATIC_CONST_VAL_STRING(val_string_day,"day");
|
||
|
DEF_STATIC_CONST_VAL_STRING(val_string_other,"_other_");
|
||
|
DEF_STATIC_CONST_VAL_STRING(val_string_a,"a");
|
||
|
DEF_STATIC_CONST_VAL_STRING(val_string_flight,"flight");
|
||
|
DEF_STATIC_CONST_VAL_STRING(val_string_to,"to");
|
||
|
|
||
|
DEF_STATIC_CONST_VAL_STRING(val_string_content,"content");
|
||
|
|
||
|
static const cst_val *gpos(const cst_item *word)
|
||
|
{
|
||
|
/* Guess at part of speech (function/content) */
|
||
|
const char *w;
|
||
|
int s,t;
|
||
|
|
||
|
w = item_feat_string(word,"name");
|
||
|
|
||
|
for (s=0; us_gpos[s]; s++)
|
||
|
{
|
||
|
for (t=1; us_gpos[s][t]; t++)
|
||
|
if (cst_streq(w,val_string(us_gpos[s][t])))
|
||
|
return us_gpos[s][0];
|
||
|
}
|
||
|
|
||
|
return (cst_val *)&val_string_content;
|
||
|
}
|
||
|
|
||
|
static const cst_val *num_digits(const cst_item *token)
|
||
|
{
|
||
|
const char *name = item_feat_string(token,"name");
|
||
|
|
||
|
return val_int_n(cst_strlen(name));
|
||
|
}
|
||
|
|
||
|
static const cst_val *month_range(const cst_item *token)
|
||
|
{
|
||
|
int v = item_feat_int(token,"name");
|
||
|
|
||
|
if ((v > 0) && ( v < 32))
|
||
|
return VAL_STRING_1;
|
||
|
else
|
||
|
return VAL_STRING_0;
|
||
|
}
|
||
|
|
||
|
static const cst_val *token_pos_guess(const cst_item *token)
|
||
|
{
|
||
|
const char *name = item_feat_string(token,"name");
|
||
|
char *dc = cst_downcase(name);
|
||
|
const cst_val *r;
|
||
|
|
||
|
if (cst_regex_match(cst_rx_digits,dc))
|
||
|
r = &val_string_numeric;
|
||
|
else if ((cst_regex_match(cst_rx_double,dc)) ||
|
||
|
(cst_regex_match(cst_rx_double,dc)))
|
||
|
r = &val_string_number;
|
||
|
else if (cst_streq(dc,"jan") ||
|
||
|
cst_streq(dc,"january") ||
|
||
|
cst_streq(dc,"feb") ||
|
||
|
cst_streq(dc,"february") ||
|
||
|
cst_streq(dc,"mar") ||
|
||
|
cst_streq(dc,"march") ||
|
||
|
cst_streq(dc,"apr") ||
|
||
|
cst_streq(dc,"april") ||
|
||
|
cst_streq(dc,"may") ||
|
||
|
cst_streq(dc,"jun") ||
|
||
|
cst_streq(dc,"june") ||
|
||
|
cst_streq(dc,"jul") ||
|
||
|
cst_streq(dc,"july") ||
|
||
|
cst_streq(dc,"aug") ||
|
||
|
cst_streq(dc,"august") ||
|
||
|
cst_streq(dc,"sep") ||
|
||
|
cst_streq(dc,"sept") ||
|
||
|
cst_streq(dc,"september") ||
|
||
|
cst_streq(dc,"oct") ||
|
||
|
cst_streq(dc,"october") ||
|
||
|
cst_streq(dc,"nov") ||
|
||
|
cst_streq(dc,"november") ||
|
||
|
cst_streq(dc,"dec") ||
|
||
|
cst_streq(dc,"december"))
|
||
|
r = &val_string_month;
|
||
|
else if (cst_streq(dc,"sun") ||
|
||
|
cst_streq(dc,"sunday") ||
|
||
|
cst_streq(dc,"mon") ||
|
||
|
cst_streq(dc,"monday") ||
|
||
|
cst_streq(dc,"tue") ||
|
||
|
cst_streq(dc,"tues") ||
|
||
|
cst_streq(dc,"tuesday") ||
|
||
|
cst_streq(dc,"wed") ||
|
||
|
cst_streq(dc,"wednesday") ||
|
||
|
cst_streq(dc,"thu") ||
|
||
|
cst_streq(dc,"thurs") ||
|
||
|
cst_streq(dc,"thursday") ||
|
||
|
cst_streq(dc,"fri") ||
|
||
|
cst_streq(dc,"friday") ||
|
||
|
cst_streq(dc,"sat") ||
|
||
|
cst_streq(dc,"saturday"))
|
||
|
r = &val_string_day;
|
||
|
/* ignoring the "token_most_common" condition, does get used */
|
||
|
else if (cst_streq(dc,"a"))
|
||
|
r = &val_string_a;
|
||
|
else if (cst_streq(dc,"flight"))
|
||
|
r = &val_string_flight;
|
||
|
else if (cst_streq(dc,"to"))
|
||
|
r = &val_string_to;
|
||
|
else
|
||
|
r = &val_string_other;
|
||
|
cst_free(dc);
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
#ifdef FLITE_PLUS_HTS_ENGINE
|
||
|
|
||
|
const cst_val *accented(const cst_item *p); /* defined in cst_ffeatures.c */
|
||
|
|
||
|
int item_after_length(const cst_item *n){
|
||
|
int i = 0;
|
||
|
if(n == NULL) return 0;
|
||
|
for(;n;n=n->n,i++);
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
const cst_item *item_first(const cst_item *n){
|
||
|
if(n == 0) return 0;
|
||
|
for(;n->p != 0;n=n->p);
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
/* 11 12 13 53 54 */
|
||
|
static const cst_val *syl_numphones(const cst_item *syl){
|
||
|
return val_string_n(item_after_length(item_daughter(item_as(syl,"SylStructure"))));
|
||
|
}
|
||
|
|
||
|
/* 14 */
|
||
|
static const cst_val *pos_in_word(const cst_item *syl){
|
||
|
const cst_item *ss,*p;
|
||
|
int c = 0;
|
||
|
|
||
|
ss = item_as(syl,"SylStructure");
|
||
|
for(p = item_daughter(item_parent(ss));p;p = item_next(p),c++){
|
||
|
if(p == ss) return val_string_n(c);
|
||
|
}
|
||
|
return val_string_n(c);
|
||
|
}
|
||
|
|
||
|
/* 21 by Toda-san */
|
||
|
static const cst_val *lisp_distance_to_p_stress(const cst_item *syl){
|
||
|
const cst_item *s, *fs;
|
||
|
int c;
|
||
|
|
||
|
s=item_as(syl,"Syllable");
|
||
|
fs = path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.daughter.R:SylStructure.daughter");
|
||
|
if (item_equal(s,fs)) return val_string_n(0);
|
||
|
s=item_prev(s);
|
||
|
for (c=1; s && (!item_equal(s,fs)) && (c < CST_CONST_INT_MAX);
|
||
|
s=item_prev(s),c++)
|
||
|
if (strcmp("1", ffeature_string(s,"stress")) == 0) return val_string_n(c);
|
||
|
if (strcmp("1", ffeature_string(s,"stress")) == 0) return val_string_n(c);
|
||
|
else return val_string_n(0);
|
||
|
}
|
||
|
|
||
|
/* 22 by Toda-san */
|
||
|
static const cst_val *lisp_distance_to_n_stress(const cst_item *syl){
|
||
|
const cst_item *s, *fs;
|
||
|
int c;
|
||
|
|
||
|
s=item_as(syl,"Syllable");
|
||
|
fs = path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.daughtern.R:SylStructure.daughtern");
|
||
|
if (item_equal(s,fs)) return val_string_n(0);
|
||
|
s=item_next(s);
|
||
|
for (c=1; s && (!item_equal(s,fs)) && (c < CST_CONST_INT_MAX);
|
||
|
s=item_next(s),c++)
|
||
|
if (strcmp("1", ffeature_string(s,"stress")) == 0) return val_string_n(c);
|
||
|
if (strcmp("1", ffeature_string(s,"stress")) == 0) return val_string_n(c);
|
||
|
else return val_string_n(0);
|
||
|
}
|
||
|
|
||
|
/* 23 by Toda-san */
|
||
|
static const cst_val *lisp_distance_to_p_accent(const cst_item *syl){
|
||
|
const cst_item *s, *fs;
|
||
|
int c;
|
||
|
|
||
|
s=item_as(syl,"Syllable");
|
||
|
fs = path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.daughter.R:SylStructure.daughter");
|
||
|
if (item_equal(s,fs)) return val_string_n(0);
|
||
|
s=item_prev(s);
|
||
|
for (c=1; s && (!item_equal(s,fs)) && (c < CST_CONST_INT_MAX);
|
||
|
s=item_prev(s),c++)
|
||
|
if (val_int(accented(s))) return val_string_n(c);
|
||
|
if (val_int(accented(s))) return val_string_n(c);
|
||
|
else return val_string_n(0);
|
||
|
}
|
||
|
|
||
|
/* 24 by Toda-san */
|
||
|
static const cst_val *lisp_distance_to_n_accent(const cst_item *syl){
|
||
|
const cst_item *s, *fs;
|
||
|
int c;
|
||
|
|
||
|
s=item_as(syl,"Syllable");
|
||
|
fs = path_to_item(syl,"R:SylStructure.parent.R:Phrase.parent.daughtern.R:SylStructure.daughtern");
|
||
|
if (item_equal(s,fs)) return val_string_n(0);
|
||
|
s=item_next(s);
|
||
|
for (c=1; s && (!item_equal(s,fs)) && (c < CST_CONST_INT_MAX);
|
||
|
s=item_next(s),c++)
|
||
|
if (val_int(accented(s))) return val_string_n(c);
|
||
|
if (val_int(accented(s))) return val_string_n(c);
|
||
|
else return val_string_n(0);
|
||
|
}
|
||
|
|
||
|
/* 25 */
|
||
|
static char syl_vowel_str[16];
|
||
|
static cst_val syl_vowel_val;
|
||
|
static const cst_val *syl_vowel(const cst_item *syl){
|
||
|
/* the vowel in the syllable */
|
||
|
const cst_item *ss,*p;
|
||
|
int size;
|
||
|
|
||
|
CST_VAL_TYPE(&syl_vowel_val) = CST_VAL_TYPE_STRING;
|
||
|
ss = item_as(syl,"SylStructure");
|
||
|
for(p = item_daughter(ss),size = 0;p;p = item_next(p),size++){
|
||
|
if(strchr("aeiou",item_name(p)[0]) != NULL){
|
||
|
strcpy(syl_vowel_str,item_name(p));
|
||
|
CST_VAL_STRING_LVAL(&syl_vowel_val) = syl_vowel_str;
|
||
|
return &syl_vowel_val;
|
||
|
}
|
||
|
}
|
||
|
/* no vowel */
|
||
|
strcpy(syl_vowel_str,"novowel");
|
||
|
CST_VAL_STRING_LVAL(&syl_vowel_val) = syl_vowel_str;
|
||
|
return &syl_vowel_val;
|
||
|
}
|
||
|
|
||
|
/* 32 */
|
||
|
static const cst_val *pos_in_phrase(const cst_item *syl){
|
||
|
const cst_item *ss,*p;
|
||
|
int c = 0;
|
||
|
|
||
|
ss = item_as(syl,"Phrase");
|
||
|
for (p = item_first(ss);p;p=item_next(p),c++)
|
||
|
if(p == ss) return val_string_n(c);
|
||
|
return val_string_n(c);
|
||
|
}
|
||
|
|
||
|
/* 33 */
|
||
|
static const cst_val *words_out(const cst_item *syl){
|
||
|
const cst_item *ss,*p;
|
||
|
int c = 0;
|
||
|
|
||
|
ss = item_as(syl,"Phrase");
|
||
|
for(p = ss;p;p=item_next(p),c++);
|
||
|
return val_string_n(c);
|
||
|
}
|
||
|
|
||
|
/* 34 by Toda-san */
|
||
|
static const cst_val *content_words_in(const cst_item *word){
|
||
|
const cst_item *ss,*p,*fs;
|
||
|
int c;
|
||
|
|
||
|
ss = word;
|
||
|
fs = path_to_item(word,"R:Phrase.parent.daughter");
|
||
|
|
||
|
for (c=0, p=ss; p && (!item_equal(p,fs)) && (c < CST_CONST_INT_MAX);
|
||
|
p=item_prev(p))
|
||
|
if (cst_streq("content", ffeature_string(p,"gpos"))) c++;
|
||
|
|
||
|
return val_string_n(c); /* its used randomly as int and float */
|
||
|
}
|
||
|
|
||
|
/* 35 by Toda-san */
|
||
|
static const cst_val *content_words_out(const cst_item *word){
|
||
|
const cst_item *ss,*p,*fs;
|
||
|
int c;
|
||
|
|
||
|
ss = word;
|
||
|
fs = path_to_item(word,"R:Phrase.parent.daughtern");
|
||
|
|
||
|
for (c=0, p=ss; p && (!item_equal(p,fs)) && (c < CST_CONST_INT_MAX);
|
||
|
p=item_next(p))
|
||
|
if (cst_streq("content", ffeature_string(p,"gpos"))) c++;
|
||
|
|
||
|
return val_string_n(c); /* its used randomly as int and float */
|
||
|
}
|
||
|
|
||
|
/* 36 */
|
||
|
static const cst_val *lisp_distance_to_p_content(const cst_item *syl){
|
||
|
const cst_item *p;
|
||
|
int c = 0;
|
||
|
|
||
|
for(p=item_prev(item_as(syl,"Phrase"));p;p=item_prev(p)){
|
||
|
c++;
|
||
|
if(gpos(p)==(cst_val*)&val_string_content)
|
||
|
break;
|
||
|
}
|
||
|
return val_string_n(c);
|
||
|
}
|
||
|
|
||
|
/* 37 */
|
||
|
static const cst_val *lisp_distance_to_n_content(const cst_item *syl){
|
||
|
const cst_item *p;
|
||
|
int c = 0;
|
||
|
|
||
|
for(p=item_next(item_as(syl,"Phrase"));p;p=item_next(p)){
|
||
|
c++;
|
||
|
if (gpos(p)==(cst_val*)&val_string_content)
|
||
|
break;
|
||
|
}
|
||
|
return val_string_n(c);
|
||
|
}
|
||
|
|
||
|
/* 38 39 40 59 60 by Toda-san */
|
||
|
static const cst_val *lisp_num_syls_in_phrase(const cst_item *phrase){
|
||
|
const cst_item *sw,*fw;
|
||
|
int c;
|
||
|
|
||
|
sw = path_to_item(phrase,"daughter");
|
||
|
fw = path_to_item(phrase,"daughtern");
|
||
|
|
||
|
for (c=0; sw && (!item_equal(sw,fw)) && (c < CST_CONST_INT_MAX);
|
||
|
sw=item_next(sw)) c += ffeature_int(sw, "word_numsyls");
|
||
|
c += ffeature_int(sw, "word_numsyls");
|
||
|
|
||
|
return val_string_n(c);
|
||
|
}
|
||
|
|
||
|
/* 41 42 43 61 62 by Toda-san */
|
||
|
static const cst_val *lisp_num_words_in_phrase(const cst_item *phrase){
|
||
|
const cst_item *sw,*fw;
|
||
|
int c;
|
||
|
|
||
|
sw = path_to_item(phrase,"daughter");
|
||
|
fw = path_to_item(phrase,"daughtern");
|
||
|
|
||
|
for (c=1; sw && (!item_equal(sw,fw)) && (c < CST_CONST_INT_MAX);
|
||
|
sw=item_next(sw)) c++;
|
||
|
|
||
|
return val_string_n(c);
|
||
|
}
|
||
|
|
||
|
/* 46 by Toda-san */
|
||
|
static const cst_val *lisp_total_syls(const cst_item *phrase){
|
||
|
const cst_item *sp, *fp;
|
||
|
int c;
|
||
|
|
||
|
sp = phrase;
|
||
|
while (item_prev(sp) != NULL) sp = item_prev(sp);
|
||
|
fp = phrase;
|
||
|
while (item_next(fp) != NULL) fp = item_next(fp);
|
||
|
|
||
|
for (c = 0; sp && (!item_equal(sp, fp)) && (c < CST_CONST_INT_MAX);
|
||
|
sp = item_next(sp)) c += ffeature_int(sp, "lisp_num_syls_in_phrase");
|
||
|
c += ffeature_int(sp, "lisp_num_syls_in_phrase");
|
||
|
return val_string_n(c);
|
||
|
}
|
||
|
|
||
|
/* 47 by Toda-san */
|
||
|
static const cst_val *lisp_total_words(const cst_item *phrase){
|
||
|
const cst_item *sp, *fp;
|
||
|
int c;
|
||
|
|
||
|
sp = phrase;
|
||
|
while (item_prev(sp) != NULL) sp = item_prev(sp);
|
||
|
fp = phrase;
|
||
|
while (item_next(fp) != NULL) fp = item_next(fp);
|
||
|
|
||
|
for (c = 0; sp && (!item_equal(sp, fp)) && (c < CST_CONST_INT_MAX);
|
||
|
sp = item_next(sp)) c += ffeature_int(sp, "lisp_num_words_in_phrase");
|
||
|
c += ffeature_int(sp, "lisp_num_words_in_phrase");
|
||
|
return val_string_n(c);
|
||
|
}
|
||
|
|
||
|
/* 48 by Toda-san */
|
||
|
static const cst_val *lisp_total_phrases(const cst_item *phrase){
|
||
|
const cst_item *sp, *fp;
|
||
|
int c;
|
||
|
|
||
|
sp = phrase;
|
||
|
while (item_prev(sp) != NULL) sp = item_prev(sp);
|
||
|
fp = phrase;
|
||
|
while (item_next(fp) != NULL) fp = item_next(fp);
|
||
|
|
||
|
for (c = 1; sp && (!item_equal(sp, fp)) && (c < CST_CONST_INT_MAX);
|
||
|
sp = item_next(sp)) c++;
|
||
|
|
||
|
return val_string_n(c);
|
||
|
}
|
||
|
|
||
|
#endif /* FLITE_PLUS_HTS_ENGINE */
|
||
|
|
||
|
void us_ff_register(cst_features *ffunctions)
|
||
|
{
|
||
|
|
||
|
/* The language independent ones */
|
||
|
basic_ff_register(ffunctions);
|
||
|
|
||
|
ff_register(ffunctions, "gpos",gpos);
|
||
|
ff_register(ffunctions, "num_digits",num_digits);
|
||
|
ff_register(ffunctions, "month_range",month_range);
|
||
|
ff_register(ffunctions, "token_pos_guess",token_pos_guess);
|
||
|
|
||
|
#ifdef FLITE_PLUS_HTS_ENGINE
|
||
|
ff_register(ffunctions, "syl_numphones",syl_numphones); /* 11 12 13 53 54 */
|
||
|
ff_register(ffunctions, "pos_in_word",pos_in_word); /* 14 */
|
||
|
ff_register(ffunctions, "lisp_distance_to_p_stress",lisp_distance_to_p_stress); /* 21 */
|
||
|
ff_register(ffunctions, "lisp_distance_to_n_stress",lisp_distance_to_n_stress); /* 22 */
|
||
|
ff_register(ffunctions, "lisp_distance_to_p_accent",lisp_distance_to_p_accent); /* 23 */
|
||
|
ff_register(ffunctions, "lisp_distance_to_n_accent",lisp_distance_to_n_accent); /* 24 */
|
||
|
ff_register(ffunctions, "syl_vowel",syl_vowel); /* 25 */
|
||
|
ff_register(ffunctions, "pos_in_phrase",pos_in_phrase); /* 32 */
|
||
|
ff_register(ffunctions, "words_out",words_out); /* 33 */
|
||
|
ff_register(ffunctions, "content_words_in",content_words_in); /* 34 */
|
||
|
ff_register(ffunctions, "content_words_out",content_words_out); /* 35 */
|
||
|
ff_register(ffunctions, "lisp_distance_to_p_content",lisp_distance_to_p_content); /* 36 */
|
||
|
ff_register(ffunctions, "lisp_distance_to_n_content",lisp_distance_to_n_content); /* 37 */
|
||
|
ff_register(ffunctions, "lisp_num_syls_in_phrase",lisp_num_syls_in_phrase); /* 38 39 40 59 60 */
|
||
|
ff_register(ffunctions, "lisp_num_words_in_phrase",lisp_num_words_in_phrase); /* 41 42 43 61 62 */
|
||
|
ff_register(ffunctions, "lisp_total_syls",lisp_total_syls); /* 46 */
|
||
|
ff_register(ffunctions, "lisp_total_words",lisp_total_words); /* 47 */
|
||
|
ff_register(ffunctions, "lisp_total_phrases",lisp_total_phrases); /* 48 */
|
||
|
#endif /* FLITE_PLUS_HTS_ENGINE */
|
||
|
}
|