first commit
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999-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: April 2000 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Item features and paths */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
#include "cst_alloc.h"
|
||||
#include "cst_item.h"
|
||||
#include "cst_relation.h"
|
||||
#include "cst_utterance.h"
|
||||
#include "cst_tokenstream.h"
|
||||
|
||||
CST_VAL_REGISTER_FUNCPTR(ffunc,cst_ffunction)
|
||||
|
||||
DEF_STATIC_CONST_VAL_STRING(ffeature_default_val,"0");
|
||||
|
||||
static const void *internal_ff(const cst_item *item,
|
||||
const char *featpath,int type);
|
||||
|
||||
const char *ffeature_string(const cst_item *item,const char *featpath)
|
||||
{
|
||||
return val_string(ffeature(item,featpath));
|
||||
}
|
||||
int ffeature_int(const cst_item *item,const char *featpath)
|
||||
{
|
||||
return val_int(ffeature(item,featpath));
|
||||
}
|
||||
float ffeature_float(const cst_item *item,const char *featpath)
|
||||
{
|
||||
return val_float(ffeature(item,featpath));
|
||||
}
|
||||
|
||||
cst_item* path_to_item(const cst_item *item,const char *featpath)
|
||||
{
|
||||
return (cst_item *)internal_ff(item,featpath,1);
|
||||
}
|
||||
|
||||
const cst_val *ffeature(const cst_item *item,const char *featpath)
|
||||
{
|
||||
return (cst_val *)internal_ff(item,featpath,0);
|
||||
}
|
||||
|
||||
static const void *internal_ff(const cst_item *item,
|
||||
const char *featpath,int type)
|
||||
{
|
||||
const char *tk, *relation;
|
||||
cst_utterance *utt;
|
||||
const cst_item *pitem;
|
||||
void *void_v;
|
||||
const cst_val *ff;
|
||||
cst_ffunction ffunc;
|
||||
char tokenstring[200]; /* we don't seem to have featpaths longer than 72 */
|
||||
char *tokens[100];
|
||||
int i,j;
|
||||
|
||||
/* This used to use cst_tokenstream but that was too slow */
|
||||
for (i=0; i<199 && featpath[i]; i++)
|
||||
tokenstring[i] = featpath[i];
|
||||
tokenstring[i]='\0';
|
||||
tokens[0] = tokenstring;
|
||||
for (i=0,j=1; tokenstring[i]; i++)
|
||||
{
|
||||
if (strchr(":.",tokenstring[i]))
|
||||
{
|
||||
tokenstring[i] = '\0';
|
||||
tokens[j] = &tokenstring[i+1];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
tokens[j] = NULL;
|
||||
j=0;
|
||||
for (tk = tokens[j], pitem=item;
|
||||
pitem &&
|
||||
(((type == 0) && tokens[j+1]) ||
|
||||
((type == 1) && tk));
|
||||
j++, tk = tokens[j])
|
||||
{
|
||||
if (cst_streq(tk,"n"))
|
||||
pitem = item_next(pitem);
|
||||
else if (cst_streq(tk,"p"))
|
||||
pitem = item_prev(pitem);
|
||||
else if (cst_streq(tk,"pp"))
|
||||
{
|
||||
if (item_prev(pitem))
|
||||
pitem = item_prev(item_prev(pitem));
|
||||
else
|
||||
pitem = NULL;
|
||||
}
|
||||
else if (cst_streq(tk,"nn"))
|
||||
{
|
||||
if (item_next(pitem))
|
||||
pitem = item_next(item_next(pitem));
|
||||
else
|
||||
pitem = NULL;
|
||||
}
|
||||
else if (cst_streq(tk,"parent"))
|
||||
pitem = item_parent(pitem);
|
||||
else if ((cst_streq(tk,"daughter")) ||
|
||||
(cst_streq(tk,"daughter1")))
|
||||
pitem = item_daughter(pitem);
|
||||
else if (cst_streq(tk,"daughtern"))
|
||||
pitem = item_last_daughter(pitem);
|
||||
else if (cst_streq(tk,"R"))
|
||||
{
|
||||
/* A relation move */
|
||||
j++;
|
||||
relation = tokens[j];
|
||||
pitem = item_as(pitem,relation);
|
||||
}
|
||||
else
|
||||
{
|
||||
cst_errmsg("ffeature: unknown directive \"%s\" ignored\n",tk);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == 0)
|
||||
{
|
||||
if (pitem && (utt = item_utt(pitem)))
|
||||
ff = feat_val(utt->ffunctions,tk);
|
||||
else
|
||||
ff = NULL;
|
||||
void_v = NULL;
|
||||
if (!ff)
|
||||
void_v = (void *)item_feat(pitem,tk);
|
||||
else if (pitem)
|
||||
{
|
||||
ffunc = val_ffunc(ff);
|
||||
void_v = (void *)(*ffunc)(pitem);
|
||||
}
|
||||
if (void_v == NULL)
|
||||
{
|
||||
#if 0
|
||||
if (pitem)
|
||||
printf("awb_debug didn't find %s in %s\n",tk,
|
||||
get_param_string(pitem->contents->features,"name","noname"));
|
||||
else
|
||||
{
|
||||
if (cst_streq("gpos",tk))
|
||||
printf("awb_debug2\n");
|
||||
printf("awb_debug didn't find %s %s\n",tk,featpath);
|
||||
}
|
||||
#endif
|
||||
void_v = (void *)&ffeature_default_val;
|
||||
}
|
||||
}
|
||||
else
|
||||
void_v = (void *)pitem;
|
||||
|
||||
return void_v;
|
||||
}
|
||||
|
||||
void ff_register(cst_features *ffunctions, const char *name, cst_ffunction f)
|
||||
{
|
||||
/* Register features functions */
|
||||
|
||||
if (feat_present(ffunctions, name))
|
||||
cst_errmsg("warning: ffunction %s redefined\n", name);
|
||||
feat_set(ffunctions, name, ffunc_val(f));
|
||||
}
|
||||
|
||||
void ff_unregister(cst_features *ffunctions, const char *name)
|
||||
{
|
||||
feat_remove(ffunctions, name);
|
||||
}
|
||||
+383
@@ -0,0 +1,383 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Items (and Item Contents) */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
#include "cst_alloc.h"
|
||||
#include "cst_item.h"
|
||||
#include "cst_relation.h"
|
||||
#include "cst_utterance.h"
|
||||
|
||||
/* Define functions for using items, rels and utts as vals */
|
||||
CST_VAL_REGISTER_TYPE_NODEL(relation,cst_relation)
|
||||
CST_VAL_REGISTER_TYPE_NODEL(item,cst_item)
|
||||
CST_VAL_REGISTER_TYPE(utterance,cst_utterance)
|
||||
CST_VAL_REGISTER_FUNCPTR(itemfunc,cst_itemfunc)
|
||||
|
||||
cst_item *new_item_relation(cst_relation *r,cst_item *i)
|
||||
{
|
||||
cst_item *ni;
|
||||
|
||||
ni = cst_utt_alloc(r->utterance, cst_item, 1);
|
||||
ni->contents = 0;
|
||||
ni->n = ni->p = ni->u = ni->d = 0;
|
||||
ni->relation = r;
|
||||
item_contents_set(ni,i);
|
||||
return ni;
|
||||
}
|
||||
|
||||
void item_contents_set(cst_item *current, cst_item *i)
|
||||
{
|
||||
cst_item_contents *c = 0;
|
||||
cst_item *nn_item;
|
||||
if (i == 0)
|
||||
c = new_item_contents(current);
|
||||
else
|
||||
c = i->contents;
|
||||
if (c != current->contents)
|
||||
{
|
||||
item_unref_contents(current);
|
||||
current->contents = c;
|
||||
/* If this contents is already in this relation */
|
||||
/* empty the other reference */
|
||||
if (feat_present(current->contents->relations,current->relation->name))
|
||||
{ /* oops this is already in this relation */
|
||||
nn_item = val_item(feat_val(current->contents->relations,
|
||||
current->relation->name));
|
||||
feat_set(nn_item->contents->relations,
|
||||
current->relation->name,
|
||||
item_val(nn_item));
|
||||
|
||||
}
|
||||
/* Add back reference */
|
||||
feat_set(current->contents->relations,
|
||||
current->relation->name,
|
||||
item_val(current));
|
||||
}
|
||||
}
|
||||
|
||||
void delete_item(cst_item *item)
|
||||
{
|
||||
cst_item *ds, *nds;
|
||||
|
||||
if (item->n != NULL)
|
||||
{
|
||||
item->n->p = item->p;
|
||||
item->n->u = item->u; /* in trees if this is first daughter */
|
||||
}
|
||||
if (item->p != NULL) item->p->n = item->n;
|
||||
if (item->u != NULL) item->u->d = item->n; /* when first daughter */
|
||||
|
||||
if (item->relation)
|
||||
{
|
||||
if (item->relation->head == item)
|
||||
item->relation->head = item->n;
|
||||
if (item->relation->tail == item)
|
||||
item->relation->tail = item->p;
|
||||
}
|
||||
|
||||
/* Delete all the daughters of item */
|
||||
for (ds = item->d; ds; ds=nds)
|
||||
{
|
||||
nds = ds->n;
|
||||
delete_item(ds);
|
||||
}
|
||||
|
||||
item_unref_contents(item);
|
||||
cst_utt_free(item->relation->utterance, item);
|
||||
}
|
||||
|
||||
void item_unref_contents(cst_item *item)
|
||||
{
|
||||
/* unreference this item from contents, and delete contents */
|
||||
/* if no one else is referencing it */
|
||||
|
||||
if (item && item->contents)
|
||||
{
|
||||
feat_remove(item->contents->relations,item->relation->name);
|
||||
if (feat_length(item->contents->relations) == 0)
|
||||
{
|
||||
delete_features(item->contents->relations);
|
||||
delete_features(item->contents->features);
|
||||
cst_utt_free(item->relation->utterance,item->contents);
|
||||
}
|
||||
item->contents = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cst_item_contents *new_item_contents(cst_item *i)
|
||||
{
|
||||
cst_item_contents *ic;
|
||||
|
||||
ic = cst_utt_alloc(i->relation->utterance,cst_item_contents,1);
|
||||
ic->features = new_features_local(i->relation->utterance->ctx);
|
||||
ic->relations = new_features_local(i->relation->utterance->ctx);
|
||||
|
||||
return ic;
|
||||
}
|
||||
|
||||
cst_item *item_as(const cst_item *i,const char *rname)
|
||||
{
|
||||
/* return i as relation rname or null */
|
||||
const cst_val *v;
|
||||
|
||||
if (i == NULL)
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
v = feat_val(i->contents->relations,rname);
|
||||
if (v != NULL)
|
||||
return val_item(v);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* List relation related functions */
|
||||
/********************************************************************/
|
||||
|
||||
cst_item *item_next(const cst_item *i)
|
||||
{
|
||||
if (i == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return i->n;
|
||||
}
|
||||
|
||||
cst_item *item_prev(const cst_item *i)
|
||||
{
|
||||
if (i == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return i->p;
|
||||
}
|
||||
|
||||
cst_item *item_append(cst_item *current, cst_item *ni)
|
||||
{
|
||||
cst_item *rni = 0;
|
||||
|
||||
if (ni && (ni->relation == current->relation))
|
||||
{
|
||||
/* got to delete it first as an item can't be in a relation twice */
|
||||
}
|
||||
else
|
||||
rni = new_item_relation(current->relation,ni);
|
||||
|
||||
rni->n = current->n;
|
||||
if (current->n != NULL)
|
||||
current->n->p = rni;
|
||||
rni->p = current;
|
||||
current->n = rni;
|
||||
|
||||
if (current->relation->tail == current)
|
||||
current->relation->tail = rni;
|
||||
|
||||
return rni;
|
||||
}
|
||||
|
||||
cst_item *item_prepend(cst_item *current, cst_item *ni)
|
||||
{
|
||||
cst_item *rni = 0;
|
||||
|
||||
if (ni && (ni->relation == current->relation))
|
||||
{
|
||||
/* got to delete it first as an item can't be in a relation twice */
|
||||
}
|
||||
else
|
||||
rni = new_item_relation(current->relation,ni);
|
||||
|
||||
rni->p = current->p;
|
||||
if (current->p != NULL)
|
||||
current->p->n = rni;
|
||||
rni->n = current;
|
||||
current->p = rni;
|
||||
|
||||
if (current->u) /* in a tree */
|
||||
{
|
||||
current->u->d = rni;
|
||||
rni->u = current->u;
|
||||
current->u = NULL;
|
||||
}
|
||||
|
||||
if (current->relation->head == current)
|
||||
current->relation->head = rni;
|
||||
|
||||
return rni;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* Tree relation related functions */
|
||||
/********************************************************************/
|
||||
cst_item *item_parent(const cst_item *i)
|
||||
{
|
||||
const cst_item *n;
|
||||
|
||||
for (n=i; item_prev(n); n=item_prev(n));
|
||||
if (n == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return n->u;
|
||||
}
|
||||
|
||||
cst_item *item_daughter(const cst_item *i)
|
||||
{
|
||||
if (i == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return i->d;
|
||||
}
|
||||
|
||||
cst_item *item_nth_daughter(const cst_item *i,int n)
|
||||
{
|
||||
int d;
|
||||
cst_item *p;
|
||||
|
||||
for (d=0,p=item_daughter(i); p && (d < n); p=item_next(p),d++);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
cst_item *item_last_daughter(const cst_item *i)
|
||||
{
|
||||
cst_item *p;
|
||||
|
||||
for (p=item_daughter(i); item_next(p); p=item_next(p));
|
||||
return p;
|
||||
}
|
||||
|
||||
cst_item *item_add_daughter(cst_item *i,cst_item *nd)
|
||||
{
|
||||
cst_item *p,*rnd;
|
||||
|
||||
p = item_last_daughter(i);
|
||||
|
||||
if (p)
|
||||
rnd=item_append(p,nd);
|
||||
else
|
||||
{ /* first new daughter */
|
||||
if (nd && (nd->relation == i->relation))
|
||||
{
|
||||
/* got to delete it first as nd can't be in a relation twice */
|
||||
cst_errmsg("item_add_daughter: already in relation\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
rnd = new_item_relation(i->relation,nd);
|
||||
|
||||
rnd->u = i;
|
||||
i->d = rnd;
|
||||
}
|
||||
|
||||
return rnd;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* Feature functions */
|
||||
/********************************************************************/
|
||||
|
||||
int item_feat_present(const cst_item *i,const char *name)
|
||||
{
|
||||
return feat_present(item_feats(i),name);
|
||||
}
|
||||
|
||||
int item_feat_remove(const cst_item *i,const char *name)
|
||||
{
|
||||
return feat_remove(item_feats(i),name);
|
||||
}
|
||||
|
||||
cst_features *item_feats(const cst_item *i)
|
||||
{
|
||||
return (i ? i->contents->features : NULL);
|
||||
}
|
||||
|
||||
const cst_val *item_feat(const cst_item *i,const char *name)
|
||||
{
|
||||
return feat_val(item_feats(i),name);
|
||||
}
|
||||
|
||||
int item_feat_int(const cst_item *i,const char *name)
|
||||
{
|
||||
return feat_int(item_feats(i),name);
|
||||
}
|
||||
|
||||
float item_feat_float(const cst_item *i,const char *name)
|
||||
{
|
||||
return feat_float(item_feats(i),name);
|
||||
}
|
||||
|
||||
const char *item_feat_string(const cst_item *i,const char *name)
|
||||
{
|
||||
return feat_string(item_feats(i),name);
|
||||
}
|
||||
|
||||
void item_set(const cst_item *i,const char *name,const cst_val *val)
|
||||
{
|
||||
feat_set(item_feats(i),name,val);
|
||||
}
|
||||
|
||||
void item_set_int(const cst_item *i,const char *name,int val)
|
||||
{
|
||||
feat_set_int(item_feats(i),name,val);
|
||||
}
|
||||
|
||||
void item_set_float(const cst_item *i,const char *name,float val)
|
||||
{
|
||||
feat_set_float(item_feats(i),name,val);
|
||||
}
|
||||
|
||||
void item_set_string(const cst_item *i,const char *name,const char *val)
|
||||
{
|
||||
feat_set_string(item_feats(i),name,val);
|
||||
}
|
||||
|
||||
cst_utterance *item_utt(const cst_item *i)
|
||||
{
|
||||
if (i && i->relation)
|
||||
return i->relation->utterance;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int item_equal(const cst_item *a, const cst_item *b)
|
||||
{
|
||||
if ((a == b) ||
|
||||
(a && b && (a->contents == b->contents)))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Relations */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
#include "cst_item.h"
|
||||
#include "cst_relation.h"
|
||||
#include "cst_utterance.h"
|
||||
|
||||
static const char * const cst_relation_noname = "NoName";
|
||||
|
||||
cst_relation *new_relation(const char *name, cst_utterance *u)
|
||||
{
|
||||
cst_relation *r = cst_utt_alloc(u,cst_relation,1);
|
||||
|
||||
r->name = cst_strdup(name);
|
||||
r->features = new_features_local(u->ctx);
|
||||
r->head = NULL;
|
||||
r->utterance = u;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void delete_relation(cst_relation *r)
|
||||
{
|
||||
cst_item *p, *np;
|
||||
|
||||
if (r != NULL)
|
||||
{
|
||||
/* This needs to traverse the *all* items */
|
||||
for(p=r->head; p; p=np)
|
||||
{
|
||||
np = item_next(p);
|
||||
delete_item(p); /* this *does* go down daughters too */
|
||||
}
|
||||
delete_features(r->features);
|
||||
cst_free(r->name);
|
||||
cst_utt_free(r->utterance,r);
|
||||
}
|
||||
}
|
||||
|
||||
cst_item *relation_head(cst_relation *r)
|
||||
{
|
||||
return ( r == NULL ? NULL : r->head);
|
||||
}
|
||||
|
||||
cst_item *relation_tail(cst_relation *r)
|
||||
{
|
||||
return (r == NULL ? NULL : r->tail);
|
||||
}
|
||||
|
||||
const char *relation_name(cst_relation *r)
|
||||
{
|
||||
return (r == NULL ? cst_relation_noname : r->name);
|
||||
}
|
||||
|
||||
cst_item *relation_append(cst_relation *r, cst_item *i)
|
||||
{
|
||||
cst_item *ni = new_item_relation(r,i);
|
||||
|
||||
if (r->head == NULL)
|
||||
r->head = ni;
|
||||
|
||||
ni->p = r->tail;
|
||||
if (r->tail)
|
||||
r->tail->n = ni;
|
||||
r->tail = ni;
|
||||
return ni;
|
||||
}
|
||||
|
||||
cst_item *relation_prepend(cst_relation *r, cst_item *i)
|
||||
{
|
||||
cst_item *ni = new_item_relation(r,i);
|
||||
|
||||
if (r->tail == NULL)
|
||||
r->tail = ni;
|
||||
|
||||
ni->n = r->head;
|
||||
if (r->head)
|
||||
r->head->p = ni;
|
||||
r->head = ni;
|
||||
return ni;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Utterances */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
#include "cst_alloc.h"
|
||||
#include "cst_utterance.h"
|
||||
|
||||
/* utterance functions are the modules that do the meat in synthesis */
|
||||
CST_VAL_REGISTER_FUNCPTR(uttfunc,cst_uttfunc)
|
||||
|
||||
cst_utterance *new_utterance()
|
||||
{
|
||||
cst_utterance *u;
|
||||
|
||||
u = cst_alloc(struct cst_utterance_struct,1);
|
||||
u->ctx = new_alloc_context(128*1024);
|
||||
|
||||
u->features = new_features_local(u->ctx);
|
||||
u->ffunctions = new_features_local(u->ctx);
|
||||
u->relations = new_features_local(u->ctx);
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
void delete_utterance(cst_utterance *u)
|
||||
{
|
||||
cst_featvalpair *fp;
|
||||
if (u)
|
||||
{
|
||||
delete_features(u->features);
|
||||
delete_features(u->ffunctions);
|
||||
/* Relation vals don't delete their contents */
|
||||
for (fp=u->relations->head; fp; fp=fp->next)
|
||||
delete_relation(val_relation(fp->val));
|
||||
delete_features(u->relations);
|
||||
delete_alloc_context(u->ctx);
|
||||
cst_free(u);
|
||||
}
|
||||
}
|
||||
|
||||
cst_relation *utt_relation_create(cst_utterance *u,const char *name)
|
||||
{
|
||||
cst_relation *r;
|
||||
|
||||
utt_relation_delete(u,name); /* remove if already there */
|
||||
r = new_relation(name,u);
|
||||
feat_set(u->relations,name,relation_val(r));
|
||||
return r;
|
||||
}
|
||||
|
||||
int utt_relation_delete(cst_utterance *u,const char *name)
|
||||
{
|
||||
/* Relation vals don't delete their contents */
|
||||
if (feat_present(u->relations, name))
|
||||
delete_relation(val_relation(feat_val(u->relations,name)));
|
||||
return feat_remove(u->relations,name);
|
||||
}
|
||||
|
||||
int utt_relation_present(cst_utterance *u,const char *name)
|
||||
{
|
||||
return feat_present(u->relations,name);
|
||||
}
|
||||
|
||||
cst_relation *utt_relation(cst_utterance *u,const char *name)
|
||||
{
|
||||
const cst_val *v = feat_val(u->relations,name);
|
||||
if (v != NULL)
|
||||
return val_relation(v);
|
||||
else
|
||||
{
|
||||
cst_errmsg("Relation: %s not present in utterance\n",
|
||||
name);
|
||||
cst_error();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,529 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Lexicon related functions */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_features.h"
|
||||
#include "cst_lexicon.h"
|
||||
#include "cst_tokenstream.h"
|
||||
|
||||
CST_VAL_REGISTER_TYPE_NODEL(lexicon,cst_lexicon)
|
||||
|
||||
#define WP_SIZE 64
|
||||
|
||||
static int no_syl_boundaries(const cst_item *i, const cst_val *p);
|
||||
static cst_val *lex_lookup_addenda(const char *wp,const cst_lexicon *l,
|
||||
int *found);
|
||||
|
||||
static int lex_match_entry(const char *a, const char *b);
|
||||
static int lex_lookup_bsearch(const cst_lexicon *l,const char *word);
|
||||
static int find_full_match(const cst_lexicon *l,
|
||||
int i,const char *word);
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
cst_lexicon *new_lexicon()
|
||||
{
|
||||
cst_lexicon *l = cst_alloc(cst_lexicon,1);
|
||||
l->syl_boundary = no_syl_boundaries;
|
||||
return l;
|
||||
}
|
||||
|
||||
void delete_lexicon(cst_lexicon *lex)
|
||||
{ /* But I doubt if this will ever be called, lexicons are mapped */
|
||||
/* This probably isn't complete */
|
||||
if (lex)
|
||||
{
|
||||
cst_free(lex->data);
|
||||
cst_free(lex);
|
||||
}
|
||||
}
|
||||
|
||||
cst_val *cst_lex_load_addenda(const cst_lexicon *lex, const char *lexfile)
|
||||
{ /* Load an addend from given file, check its phones wrt lex */
|
||||
cst_tokenstream *lf;
|
||||
const cst_string *line;
|
||||
cst_val *e = NULL;
|
||||
cst_val *na = NULL;
|
||||
int i;
|
||||
|
||||
lf = ts_open(lexfile,"\n","","","");
|
||||
if (lf == NULL)
|
||||
{
|
||||
cst_errmsg("lex_add_addenda: cannot open lexicon file\n");
|
||||
return NULL;;
|
||||
}
|
||||
|
||||
while (!ts_eof(lf))
|
||||
{
|
||||
line = ts_get(lf);
|
||||
if (line[0] == '#')
|
||||
continue; /* a comment */
|
||||
for (i=0; line[i]; i++)
|
||||
{
|
||||
if (line[i] != ' ')
|
||||
break;
|
||||
}
|
||||
if (line[i])
|
||||
{
|
||||
e = cst_lex_make_entry(lex,line);
|
||||
if (e)
|
||||
na = cons_val(e,na);
|
||||
}
|
||||
else
|
||||
continue; /* a blank line */
|
||||
}
|
||||
|
||||
ts_close(lf);
|
||||
return val_reverse(na);
|
||||
}
|
||||
|
||||
cst_val *cst_lex_make_entry(const cst_lexicon *lex, const cst_string *entry)
|
||||
{ /* if replace then replace entry in addenda of lex with entry */
|
||||
/* else append entry to addenda of lex */
|
||||
cst_tokenstream *e;
|
||||
cst_val *phones = NULL;
|
||||
cst_val *ventry;
|
||||
const cst_string *w, *p;
|
||||
cst_string *word;
|
||||
cst_string *pos;
|
||||
int i;
|
||||
|
||||
e = ts_open_string(entry,
|
||||
cst_ts_default_whitespacesymbols,
|
||||
"","","");
|
||||
|
||||
w = ts_get(e);
|
||||
if (w[0] == '"') /* it was a quoted entry */
|
||||
{ /* so reparse it */
|
||||
ts_close(e);
|
||||
e = ts_open_string(entry,
|
||||
cst_ts_default_whitespacesymbols,
|
||||
"","","");
|
||||
w = ts_get_quoted_token(e,'"','\\');
|
||||
}
|
||||
|
||||
word = cst_strdup(w);
|
||||
p = ts_get(e);
|
||||
if (!cst_streq(":",p)) /* there is a real pos */
|
||||
{
|
||||
pos = cst_strdup(p);
|
||||
p = ts_get(e);
|
||||
if (!cst_streq(":",p)) /* there is a real pos */
|
||||
{
|
||||
cst_fprintf(stdout,"add_addenda: lex %s: expected \":\" in %s\n",
|
||||
lex->name,
|
||||
word);
|
||||
cst_free(word); cst_free(pos); ts_close(e);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
pos = cst_strdup("nil");
|
||||
|
||||
while (!ts_eof(e))
|
||||
{
|
||||
p = ts_get(e);
|
||||
/* Check its a legal phone */
|
||||
for (i=0; lex->phone_table[i]; i++)
|
||||
if (cst_streq(p,lex->phone_table[i]))
|
||||
break;
|
||||
if (cst_streq("#",p)) /* comment to end of line */
|
||||
break;
|
||||
else if (lex->phone_table[i])
|
||||
/* Only add it if its a valid phone */
|
||||
phones = cons_val(string_val(p),phones);
|
||||
else
|
||||
{
|
||||
cst_fprintf(stdout,"add_addenda: lex: %s word %s phone %s not in lexicon phoneset\n",
|
||||
lex->name,
|
||||
word,
|
||||
p);
|
||||
}
|
||||
}
|
||||
|
||||
ventry = cons_val(string_val(word),cons_val(string_val(pos),
|
||||
val_reverse(phones)));
|
||||
cst_free(word); cst_free(pos); ts_close(e);
|
||||
#if 0
|
||||
printf("entry: ");
|
||||
val_print(stdout,ventry);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
return ventry;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void lexicon_register(cst_lexicon *lex)
|
||||
{
|
||||
/* Add given lexicon to list of known lexicons */
|
||||
cst_lexicon **old_lexs;
|
||||
int i;
|
||||
|
||||
old_lexs = flite_lexicons;
|
||||
flite_num_lexicons++;
|
||||
flite_lexicons = cst_alloc(cst_lexicon *,flite_num_lexicons);
|
||||
for (i=0; i<flite_num_lexicons-1; i++)
|
||||
flite_lexicons[i] = old_lexs[i];
|
||||
flite_lexicons[i] = lex;
|
||||
cst_free(old_lexs);
|
||||
}
|
||||
|
||||
cst_lexicon *lexicon_select(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < flite_num_lexicons; i++)
|
||||
if (cst_streq(name,flite_lexicons[i]->name))
|
||||
return flite_lexicons[i];
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int no_syl_boundaries(const cst_item *i, const cst_val *p)
|
||||
{
|
||||
/* This is a default function that will normally be replaced */
|
||||
/* for each lexicon */
|
||||
(void)i;
|
||||
(void)p;
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
int in_lex(const cst_lexicon *l, const char *word, const char *pos)
|
||||
{
|
||||
/* return TRUE is its in the lexicon */
|
||||
int r = FALSE, i;
|
||||
char *wp;
|
||||
|
||||
wp = cst_alloc(char,cst_strlen(word)+2);
|
||||
cst_sprintf(wp,"%c%s",(pos ? pos[0] : '0'),word);
|
||||
|
||||
for (i=0; l->addenda && l->addenda[i]; i++)
|
||||
{
|
||||
if (((wp[0] == '0') || (wp[0] == l->addenda[i][0][0])) &&
|
||||
(cst_streq(wp+1,l->addenda[i][0]+1)))
|
||||
{
|
||||
r = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!r && (lex_lookup_bsearch(l,wp) >= 0))
|
||||
r = TRUE;
|
||||
|
||||
cst_free(wp);
|
||||
return r;
|
||||
}
|
||||
|
||||
cst_val *lex_lookup(const cst_lexicon *l, const char *word, const char *pos)
|
||||
{
|
||||
int index;
|
||||
int p;
|
||||
const char *q;
|
||||
char *wp;
|
||||
cst_val *phones = 0;
|
||||
int found = FALSE;
|
||||
|
||||
wp = cst_alloc(char,cst_strlen(word)+2);
|
||||
cst_sprintf(wp,"%c%s",(pos ? pos[0] : '0'),word);
|
||||
|
||||
if (l->addenda)
|
||||
phones = lex_lookup_addenda(wp,l,&found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
index = lex_lookup_bsearch(l,wp);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
if (l->phone_hufftable)
|
||||
{
|
||||
for (p=index-2; l->data[p]; p--)
|
||||
for (q=l->phone_hufftable[l->data[p]]; *q; q++)
|
||||
phones = cons_val(string_val(l->phone_table[(unsigned char)*q]),
|
||||
phones);
|
||||
}
|
||||
else /* no compression -- should we still support this ? */
|
||||
{
|
||||
for (p=index-2; l->data[p]; p--)
|
||||
phones = cons_val(string_val(l->phone_table[l->data[p]]),
|
||||
phones);
|
||||
}
|
||||
phones = val_reverse(phones);
|
||||
}
|
||||
else if (l->lts_function)
|
||||
{
|
||||
phones = (l->lts_function)(l,word,"");
|
||||
}
|
||||
else if (l->lts_rule_set)
|
||||
{
|
||||
phones = lts_apply(word,
|
||||
"", /* more features if we had them */
|
||||
l->lts_rule_set);
|
||||
}
|
||||
}
|
||||
|
||||
cst_free(wp);
|
||||
|
||||
return phones;
|
||||
}
|
||||
|
||||
static cst_val *lex_lookup_addenda(const char *wp,const cst_lexicon *l,
|
||||
int *found)
|
||||
{
|
||||
/* For those other words */
|
||||
int i,j;
|
||||
cst_val *phones;
|
||||
|
||||
phones = NULL;
|
||||
|
||||
for (i=0; l->addenda[i]; i++)
|
||||
{
|
||||
if (((wp[0] == '0') || (wp[0] == l->addenda[i][0][0])) &&
|
||||
(cst_streq(wp+1,l->addenda[i][0]+1)))
|
||||
{
|
||||
for (j=1; l->addenda[i][j]; j++)
|
||||
phones = cons_val(string_val(l->addenda[i][j]),phones);
|
||||
*found = TRUE;
|
||||
return val_reverse(phones);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int lex_uncompress_word(char *ucword,int max_size,
|
||||
int p,const cst_lexicon *l)
|
||||
{
|
||||
int i,j=0,length;
|
||||
unsigned char *cword;
|
||||
|
||||
if (l->entry_hufftable == 0)
|
||||
/* can have "compressed" lexicons without compression */
|
||||
cst_sprintf(ucword,"%s",&l->data[p]);
|
||||
else
|
||||
{
|
||||
cword = &l->data[p];
|
||||
for (i=0,j=0; cword[i]; i++)
|
||||
{
|
||||
length = cst_strlen(l->entry_hufftable[cword[i]]);
|
||||
if (j+length+1<max_size)
|
||||
{
|
||||
memmove(ucword+j,l->entry_hufftable[cword[i]],length);
|
||||
j += length;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
ucword[j] = '\0';
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
static int lex_data_next_entry(const cst_lexicon *l,int p,int end)
|
||||
{
|
||||
for (p++; p < end; p++)
|
||||
if (l->data[p-1] == 255)
|
||||
return p;
|
||||
return end;
|
||||
}
|
||||
static int lex_data_prev_entry(const cst_lexicon *l,int p,int start)
|
||||
{
|
||||
for (p--; p > start; p--)
|
||||
if (l->data[p-1] == 255)
|
||||
return p;
|
||||
return start;
|
||||
}
|
||||
static int lex_data_closest_entry(const cst_lexicon *l,int p,int start,int end)
|
||||
{
|
||||
int d;
|
||||
|
||||
d=0;
|
||||
while ((p-d > start) &&
|
||||
(p+d < end))
|
||||
{
|
||||
if (l->data[(p+d)-1] == 255)
|
||||
return p+d;
|
||||
else if (l->data[(p-d)-1] == 255)
|
||||
return p-d;
|
||||
d++;
|
||||
}
|
||||
return p-d;
|
||||
}
|
||||
|
||||
static int lex_lookup_bsearch(const cst_lexicon *l, const char *word)
|
||||
{
|
||||
int start,mid,end,c;
|
||||
/* needs to be longer than longest word in lexicon */
|
||||
char word_pos[WP_SIZE];
|
||||
|
||||
start = 0;
|
||||
end = l->num_bytes;
|
||||
while (start < end) {
|
||||
mid = (start + end)/2;
|
||||
|
||||
/* find previous entry start */
|
||||
mid = lex_data_closest_entry(l,mid,start,end);
|
||||
lex_uncompress_word(word_pos,WP_SIZE,mid,l);
|
||||
|
||||
c = lex_match_entry(word_pos,word);
|
||||
|
||||
if (c == 0)
|
||||
return find_full_match(l,mid,word);
|
||||
else if (c > 0)
|
||||
end = mid;
|
||||
else
|
||||
start = lex_data_next_entry(l,mid + 1,end);
|
||||
|
||||
#if 0
|
||||
if (l->data[start-1] == 255)
|
||||
{
|
||||
lex_uncompress_word(word_pos,WP_SIZE,start,l);
|
||||
printf("start %s %d ",word_pos,start);
|
||||
}
|
||||
else
|
||||
printf("start NULL %d ",start);
|
||||
if (l->data[mid-1] == 255)
|
||||
{
|
||||
lex_uncompress_word(word_pos,WP_SIZE,mid,l);
|
||||
printf("mid %s %d ",word_pos,mid);
|
||||
}
|
||||
else
|
||||
printf("mid NULL %d ",mid);
|
||||
if (l->data[end-1] == 255)
|
||||
{
|
||||
lex_uncompress_word(word_pos,WP_SIZE,end,l);
|
||||
printf("end %s %d ",word_pos,end);
|
||||
}
|
||||
else
|
||||
printf("end NULL %d ",end);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int find_full_match(const cst_lexicon *l,
|
||||
int i,const char *word)
|
||||
|
||||
{
|
||||
/* found word, now look for actual match including pos */
|
||||
int w, match=i;
|
||||
/* needs to be longer than longest word in lexicon */
|
||||
char word_pos[WP_SIZE];
|
||||
|
||||
for (w=i; w > 0; )
|
||||
{
|
||||
lex_uncompress_word(word_pos,WP_SIZE,w,l);
|
||||
if (!cst_streq(word+1,word_pos+1))
|
||||
break;
|
||||
else if (cst_streq(word,word_pos))
|
||||
return w;
|
||||
match = w; /* if we can't find an exact match we'll take this one */
|
||||
/* go back to last entry */
|
||||
w = lex_data_prev_entry(l,w,0);
|
||||
}
|
||||
|
||||
for (w=i; w < l->num_bytes;)
|
||||
{
|
||||
lex_uncompress_word(word_pos,WP_SIZE,w,l);
|
||||
if (!cst_streq(word+1,word_pos+1))
|
||||
break;
|
||||
else if (cst_streq(word,word_pos))
|
||||
return w;
|
||||
/* go to next entry */
|
||||
w = lex_data_next_entry(l,w,l->num_bytes);
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
static int lex_match_entry(const char *a, const char *b)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = strcmp(a+1,b+1);
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Letter to sound rule support */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_features.h"
|
||||
#include "cst_lts.h"
|
||||
#include "cst_endian.h"
|
||||
|
||||
static cst_lts_phone apply_model(cst_lts_letter *vals,
|
||||
cst_lts_addr start,
|
||||
const cst_lts_model *model);
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
cst_lts_rules *new_lts_rules()
|
||||
{
|
||||
cst_lts_rules *lt = cst_alloc(cst_lts_rules,1);
|
||||
lt->name = 0;
|
||||
lt->letter_index = 0;
|
||||
lt->models = 0;
|
||||
lt->phone_table = 0;
|
||||
lt->context_window_size = 0;
|
||||
lt->context_extra_feats = 0;
|
||||
lt->letter_table = 0;
|
||||
return lt;
|
||||
}
|
||||
|
||||
cst_val *lts_apply_val(const cst_val *wlist,const char *feats,const cst_lts_rules *r)
|
||||
{
|
||||
/* for symbol to symbol mapping */
|
||||
const cst_val *v;
|
||||
cst_val *p;
|
||||
char *word;
|
||||
int i,j;
|
||||
|
||||
word = cst_alloc(char,val_length(wlist)+1);
|
||||
|
||||
for (v=wlist,i=0; v; v=val_cdr(v),i++)
|
||||
{
|
||||
for (j=0; r->letter_table[j]; j++)
|
||||
if (cst_streq(val_string(val_car(v)),r->letter_table[j]))
|
||||
{
|
||||
word[i] = j;
|
||||
break;
|
||||
}
|
||||
if (!r->letter_table[j])
|
||||
{
|
||||
#if 0
|
||||
printf("awb_debug unknown letter >%s<\n",val_string(val_car(v)));
|
||||
#endif
|
||||
i--; /* can't find this letter so skip it */
|
||||
}
|
||||
}
|
||||
|
||||
p = lts_apply(word,feats,r);
|
||||
cst_free(word);
|
||||
|
||||
return p;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
cst_val *lts_apply(const char *word,const char *feats,const cst_lts_rules *r)
|
||||
{
|
||||
int pos, index, i;
|
||||
cst_val *phones=0;
|
||||
cst_lts_letter *fval_buff;
|
||||
cst_lts_letter *full_buff;
|
||||
cst_lts_phone phone;
|
||||
char *left, *right, *p;
|
||||
char hash;
|
||||
char zeros[8];
|
||||
|
||||
/* For feature vals for each letter */
|
||||
fval_buff = cst_alloc(cst_lts_letter,
|
||||
(r->context_window_size*2)+
|
||||
r->context_extra_feats);
|
||||
/* Buffer with added contexts */
|
||||
full_buff = cst_alloc(cst_lts_letter,
|
||||
(r->context_window_size*2)+
|
||||
cst_strlen(word)+1); /* TBD assumes single POS feat */
|
||||
if (r->letter_table)
|
||||
{
|
||||
for (i=0; i<8; i++) zeros[i] = 2;
|
||||
cst_sprintf((char *)full_buff,
|
||||
"%.*s%c%s%c%.*s",
|
||||
r->context_window_size-1, zeros,
|
||||
1,
|
||||
word,
|
||||
1,
|
||||
r->context_window_size-1, zeros);
|
||||
hash = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Assumes l_letter is a char and context < 8 */
|
||||
cst_sprintf((char *)full_buff,
|
||||
"%.*s#%s#%.*s",
|
||||
r->context_window_size-1, "00000000",
|
||||
word,
|
||||
r->context_window_size-1, "00000000");
|
||||
hash = '#';
|
||||
}
|
||||
|
||||
/* Do the prediction backwards so we don't need to reverse the answer */
|
||||
for (pos = r->context_window_size + cst_strlen(word) - 1;
|
||||
full_buff[pos] != hash;
|
||||
pos--)
|
||||
{
|
||||
/* Fill the features buffer for the predictor */
|
||||
cst_sprintf((char *)fval_buff,
|
||||
"%.*s%.*s%s",
|
||||
r->context_window_size,
|
||||
full_buff+pos-r->context_window_size,
|
||||
r->context_window_size,
|
||||
full_buff+pos+1,
|
||||
feats);
|
||||
if ((!r->letter_table
|
||||
&& ((full_buff[pos] < 'a') || (full_buff[pos] > 'z'))))
|
||||
{
|
||||
#ifdef EXCESSIVELY_CHATTY
|
||||
cst_errmsg("lts:skipping unknown char \"%c\"\n",
|
||||
full_buff[pos]);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if (r->letter_table)
|
||||
index = full_buff[pos] - 3;
|
||||
else
|
||||
index = (full_buff[pos]-'a')%26;
|
||||
phone = apply_model(fval_buff,
|
||||
r->letter_index[index],
|
||||
r->models);
|
||||
/* delete epsilons and split dual-phones */
|
||||
if (cst_streq("epsilon",r->phone_table[phone]))
|
||||
continue;
|
||||
else if ((p=strchr(r->phone_table[phone],'-')) != NULL)
|
||||
{
|
||||
left = cst_substr(r->phone_table[phone],0,
|
||||
cst_strlen(r->phone_table[phone])-cst_strlen(p));
|
||||
right = cst_substr(r->phone_table[phone],
|
||||
(cst_strlen(r->phone_table[phone])-cst_strlen(p))+1,
|
||||
(cst_strlen(p)-1));
|
||||
phones = cons_val(string_val(left),
|
||||
cons_val(string_val(right),phones));
|
||||
cst_free(left);
|
||||
cst_free(right);
|
||||
}
|
||||
else
|
||||
phones = cons_val(string_val(r->phone_table[phone]),phones);
|
||||
}
|
||||
|
||||
cst_free(full_buff);
|
||||
cst_free(fval_buff);
|
||||
|
||||
return phones;
|
||||
}
|
||||
|
||||
static void cst_lts_get_state(cst_lts_rule *state,
|
||||
const cst_lts_model *model,
|
||||
unsigned short n,
|
||||
int rule_size)
|
||||
{ /* As some OS's require a more elaborate access than a simple lookup */
|
||||
memmove(state,&model[n*rule_size],rule_size);
|
||||
}
|
||||
|
||||
static cst_lts_phone apply_model(cst_lts_letter *vals,cst_lts_addr start,
|
||||
const cst_lts_model *model)
|
||||
{
|
||||
/* because some machines (ipaq/mips) can't deal with addrs not on */
|
||||
/* word boundaries we use a static and copy the rule values each time */
|
||||
/* so we know its properly aligned */
|
||||
/* Hmm this still might be wrong on some machines that align the */
|
||||
/* structure cst_lts_rules differently */
|
||||
cst_lts_rule state;
|
||||
unsigned short nstate;
|
||||
static const int sizeof_cst_lts_rule = 6;
|
||||
|
||||
cst_lts_get_state(&state,model,start,sizeof_cst_lts_rule);
|
||||
for ( ;
|
||||
state.feat != CST_LTS_EOR;
|
||||
)
|
||||
{
|
||||
/* printf("%s %c %c %d\n",vals,vals[state.feat],state.val,
|
||||
(vals[state.feat] == state.val) ? 1 : 0); */
|
||||
if (vals[state.feat] == state.val)
|
||||
nstate = state.qtrue;
|
||||
else
|
||||
nstate = state.qfalse;
|
||||
/* This should really happen at compilation time */
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
if (CST_BIG_ENDIAN)
|
||||
nstate = SWAPSHORT(nstate);
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
cst_lts_get_state(&state,model,nstate,sizeof_cst_lts_rule);
|
||||
}
|
||||
|
||||
return (cst_lts_phone)state.val;
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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 2000 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Regexes, this is just a front end to Henry Spencer's regex code */
|
||||
/* Includes a mapping of fsf format regex's to hs format (escaping) */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_alloc.h"
|
||||
#include "cst_regex.h"
|
||||
|
||||
#include "cst_regex_defs.h"
|
||||
|
||||
/* For access by const models */
|
||||
const cst_regex *const cst_regex_table[] = {
|
||||
&cst_rx_dotted_abbrev_rx
|
||||
};
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
static char *regularize(const char *unregex,int match);
|
||||
|
||||
void cst_regex_init()
|
||||
{
|
||||
/* no need to initialize regexes anymore, they are pre-compiled */
|
||||
|
||||
return;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
int cst_regex_match(const cst_regex *r, const char *str)
|
||||
{
|
||||
cst_regstate *s;
|
||||
|
||||
if (r == NULL) return 0;
|
||||
s = hs_regexec(r, str);
|
||||
if (s) {
|
||||
cst_free(s);
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
cst_regstate *cst_regex_match_return(const cst_regex *r, const char *str)
|
||||
{
|
||||
if (r == NULL)
|
||||
return 0;
|
||||
|
||||
return hs_regexec(r, str);
|
||||
}
|
||||
|
||||
cst_regex *new_cst_regex(const char *str)
|
||||
{
|
||||
cst_regex *r;
|
||||
char *reg_str = regularize(str,1);
|
||||
|
||||
r = hs_regcomp(reg_str);
|
||||
cst_free(reg_str);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void delete_cst_regex(cst_regex *r)
|
||||
{
|
||||
if (r)
|
||||
hs_regdelete(r);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* These define the different escape conventions for the FSF's */
|
||||
/* regexp code and Henry Spencer's */
|
||||
|
||||
static const char *fsf_magic="^$*+?[].\\";
|
||||
static const char *fsf_magic_backslashed="()|<>";
|
||||
static const char *spencer_magic="^$*+?[].()|\\\n";
|
||||
static const char *spencer_magic_backslashed="<>";
|
||||
|
||||
/* Adaptation of rjc's mapping of fsf format to henry spencer's format */
|
||||
/* of escape sequences, as taken from EST_Regex.cc in EST */
|
||||
static char *regularize(const char *unregex,int match)
|
||||
{
|
||||
char *reg = cst_alloc(char, cst_strlen(unregex)*2+3);
|
||||
char *r=reg;
|
||||
const char *e;
|
||||
int magic=0,last_was_bs=0;
|
||||
const char * in_brackets=NULL;
|
||||
const char *ex = (unregex?unregex:"");
|
||||
|
||||
if (match && *ex != '^')
|
||||
*(r++) = '^';
|
||||
|
||||
for(e=ex; *e ; e++)
|
||||
{
|
||||
if (*e == '\\' && !last_was_bs)
|
||||
{
|
||||
last_was_bs=1;
|
||||
continue;
|
||||
}
|
||||
|
||||
magic=strchr((last_was_bs?fsf_magic_backslashed:fsf_magic), *e)!=NULL;
|
||||
|
||||
if (in_brackets)
|
||||
{
|
||||
*(r++) = *e;
|
||||
if (*e == ']' && (e-in_brackets)>1)
|
||||
in_brackets=0;
|
||||
}
|
||||
else if (magic)
|
||||
{
|
||||
if (strchr(spencer_magic_backslashed, *e))
|
||||
*(r++) = '\\';
|
||||
|
||||
*(r++) = *e;
|
||||
if (*e == '[')
|
||||
in_brackets=e;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strchr(spencer_magic, *e))
|
||||
*(r++) = '\\';
|
||||
|
||||
*(r++) = *e;
|
||||
}
|
||||
last_was_bs=0;
|
||||
}
|
||||
|
||||
if (match && (e==ex || *(e-1) != '$'))
|
||||
{
|
||||
if (last_was_bs)
|
||||
*(r++) = '\\';
|
||||
*(r++) = '$';
|
||||
}
|
||||
|
||||
*r='\0';
|
||||
|
||||
return reg;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
@@ -0,0 +1,161 @@
|
||||
/* Autogenerated from make_cst_regexes */
|
||||
static const unsigned char cst_rx_white_rxprog[] = {
|
||||
156, 6, 0, 20, 1, 0, 3, 11, 0, 11, 4, 0, 0, 32, 110, 116,
|
||||
114, 0, 2, 0, 3, 0, 0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_white_rx = {
|
||||
0, 1, NULL, 0, 24,
|
||||
(char *)cst_rx_white_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_white = &cst_rx_white_rx;
|
||||
|
||||
static const unsigned char cst_rx_alpha_rxprog[] = {
|
||||
156, 6, 0, 68, 1, 0, 3, 11, 0, 59, 4, 0, 0, 65, 66, 67,
|
||||
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
|
||||
84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105,
|
||||
106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
|
||||
122, 0, 2, 0, 3, 0, 0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_alpha_rx = {
|
||||
0, 1, NULL, 0, 72,
|
||||
(char *)cst_rx_alpha_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_alpha = &cst_rx_alpha_rx;
|
||||
|
||||
static const unsigned char cst_rx_uppercase_rxprog[] = {
|
||||
156, 6, 0, 42, 1, 0, 3, 11, 0, 33, 4, 0, 0, 65, 66, 67,
|
||||
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
|
||||
84, 85, 86, 87, 88, 89, 90, 0, 2, 0, 3, 0, 0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_uppercase_rx = {
|
||||
0, 1, NULL, 0, 46,
|
||||
(char *)cst_rx_uppercase_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_uppercase = &cst_rx_uppercase_rx;
|
||||
|
||||
static const unsigned char cst_rx_lowercase_rxprog[] = {
|
||||
156, 6, 0, 42, 1, 0, 3, 11, 0, 33, 4, 0, 0, 97, 98, 99,
|
||||
100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
|
||||
116, 117, 118, 119, 120, 121, 122, 0, 2, 0, 3, 0, 0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_lowercase_rx = {
|
||||
0, 1, NULL, 0, 46,
|
||||
(char *)cst_rx_lowercase_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_lowercase = &cst_rx_lowercase_rx;
|
||||
|
||||
static const unsigned char cst_rx_alphanum_rxprog[] = {
|
||||
156, 6, 0, 78, 1, 0, 3, 11, 0, 69, 4, 0, 0, 48, 49, 50,
|
||||
51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73,
|
||||
74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
|
||||
90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
||||
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 0, 2, 0, 3, 0,
|
||||
0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_alphanum_rx = {
|
||||
0, 1, NULL, 0, 82,
|
||||
(char *)cst_rx_alphanum_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_alphanum = &cst_rx_alphanum_rx;
|
||||
|
||||
static const unsigned char cst_rx_identifier_rxprog[] = {
|
||||
156, 6, 0, 136, 1, 0, 3, 4, 0, 57, 65, 66, 67, 68, 69, 70,
|
||||
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
|
||||
87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
|
||||
109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 95, 0,
|
||||
11, 0, 70, 4, 0, 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
|
||||
81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102,
|
||||
103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
|
||||
119, 120, 121, 122, 95, 0, 2, 0, 3, 0, 0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_identifier_rx = {
|
||||
0, 1, NULL, 0, 140,
|
||||
(char *)cst_rx_identifier_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_identifier = &cst_rx_identifier_rx;
|
||||
|
||||
static const unsigned char cst_rx_int_rxprog[] = {
|
||||
156, 6, 0, 40, 1, 0, 3, 6, 0, 8, 8, 0, 8, 45, 0, 6,
|
||||
0, 3, 9, 0, 3, 11, 0, 17, 4, 0, 0, 48, 49, 50, 51, 52,
|
||||
53, 54, 55, 56, 57, 0, 2, 0, 3, 0, 0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_int_rx = {
|
||||
0, 1, NULL, 0, 44,
|
||||
(char *)cst_rx_int_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_int = &cst_rx_int_rx;
|
||||
|
||||
static const unsigned char cst_rx_double_rxprog[] = {
|
||||
156, 6, 0, 199, 1, 0, 3, 6, 0, 8, 8, 0, 8, 45, 0, 6,
|
||||
0, 3, 9, 0, 3, 21, 0, 3, 6, 0, 51, 22, 0, 3, 6, 0,
|
||||
42, 11, 0, 17, 4, 0, 0, 48, 49, 50, 51, 52, 53, 54, 55, 56,
|
||||
57, 0, 8, 0, 5, 46, 0, 10, 0, 17, 4, 0, 0, 48, 49, 50,
|
||||
51, 52, 53, 54, 55, 56, 57, 0, 32, 0, 66, 6, 0, 29, 23, 0,
|
||||
3, 6, 0, 20, 11, 0, 17, 4, 0, 0, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 57, 0, 33, 0, 37, 6, 0, 34, 24, 0, 3, 6, 0,
|
||||
25, 8, 0, 5, 46, 0, 11, 0, 17, 4, 0, 0, 48, 49, 50, 51,
|
||||
52, 53, 54, 55, 56, 57, 0, 34, 0, 3, 31, 0, 3, 6, 0, 50,
|
||||
25, 0, 3, 6, 0, 41, 4, 0, 6, 101, 69, 0, 6, 0, 9, 4,
|
||||
0, 9, 45, 43, 0, 6, 0, 3, 9, 0, 3, 11, 0, 17, 4, 0,
|
||||
0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 35, 0, 6, 6,
|
||||
0, 3, 9, 0, 3, 2, 0, 3, 0, 0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_double_rx = {
|
||||
0, 1, NULL, 0, 203,
|
||||
(char *)cst_rx_double_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_double = &cst_rx_double_rx;
|
||||
|
||||
static const unsigned char cst_rx_commaint_rxprog[] = {
|
||||
156, 6, 0, 224, 1, 0, 3, 4, 0, 14, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 57, 0, 6, 0, 17, 4, 0, 17, 48, 49, 50, 51, 52,
|
||||
53, 54, 55, 56, 57, 0, 6, 0, 3, 9, 0, 3, 6, 0, 17, 4,
|
||||
0, 17, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 6, 0, 3,
|
||||
9, 0, 3, 8, 0, 5, 44, 0, 6, 0, 62, 21, 0, 3, 6, 0,
|
||||
50, 4, 0, 14, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 4,
|
||||
0, 14, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 4, 0, 14,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 8, 0, 5, 44, 0,
|
||||
31, 0, 3, 7, 0, 59, 6, 0, 3, 9, 0, 3, 4, 0, 14, 48,
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 4, 0, 14, 48, 49, 50,
|
||||
51, 52, 53, 54, 55, 56, 57, 0, 4, 0, 14, 48, 49, 50, 51, 52,
|
||||
53, 54, 55, 56, 57, 0, 6, 0, 34, 22, 0, 3, 6, 0, 25, 8,
|
||||
0, 5, 46, 0, 11, 0, 17, 4, 0, 0, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 57, 0, 32, 0, 6, 6, 0, 3, 9, 0, 3, 2, 0,
|
||||
3, 0, 0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_commaint_rx = {
|
||||
0, 1, NULL, 0, 228,
|
||||
(char *)cst_rx_commaint_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_commaint = &cst_rx_commaint_rx;
|
||||
|
||||
static const unsigned char cst_rx_digits_rxprog[] = {
|
||||
156, 6, 0, 40, 1, 0, 3, 4, 0, 14, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 57, 0, 10, 0, 17, 4, 0, 0, 48, 49, 50, 51, 52,
|
||||
53, 54, 55, 56, 57, 0, 2, 0, 3, 0, 0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_digits_rx = {
|
||||
0, 1, NULL, 0, 44,
|
||||
(char *)cst_rx_digits_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_digits = &cst_rx_digits_rx;
|
||||
|
||||
static const unsigned char cst_rx_dotted_abbrev_rxprog[] = {
|
||||
156, 6, 0, 147, 1, 0, 3, 6, 0, 76, 21, 0, 3, 6, 0, 64,
|
||||
4, 0, 56, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
|
||||
78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99,
|
||||
100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
|
||||
116, 117, 118, 119, 120, 121, 122, 0, 8, 0, 5, 46, 0, 31, 0, 3,
|
||||
7, 0, 73, 6, 0, 3, 9, 0, 3, 4, 0, 56, 65, 66, 67, 68,
|
||||
69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
|
||||
85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
|
||||
107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
|
||||
0, 2, 0, 3, 0, 0, 0,
|
||||
};
|
||||
static const cst_regex cst_rx_dotted_abbrev_rx = {
|
||||
0, 1, NULL, 0, 151,
|
||||
(char *)cst_rx_dotted_abbrev_rxprog
|
||||
};
|
||||
const cst_regex * const cst_rx_dotted_abbrev = &cst_rx_dotted_abbrev_rx;
|
||||
|
||||
+1318
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,200 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 2000 */
|
||||
/* 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 2000 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* CART tree support */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_regex.h"
|
||||
#include "cst_cart.h"
|
||||
|
||||
CST_VAL_REGISTER_TYPE_NODEL(cart,cst_cart)
|
||||
|
||||
/* Make this 1 if you want to debug som cart calls */
|
||||
#define CART_DEBUG 0
|
||||
|
||||
#define cst_cart_node_n(P,TREE) ((TREE)->rule_table[P])
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
void delete_cart(cst_cart *cart)
|
||||
{
|
||||
cst_errmsg("delete_cart function missing\n");
|
||||
return;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
#define cst_cart_node_val(n,tree) (cst_cart_node_n(n,tree).val)
|
||||
#define cst_cart_node_op(n,tree) (cst_cart_node_n(n,tree).op)
|
||||
#define cst_cart_node_feat(n,tree) (tree->feat_table[cst_cart_node_n(n,tree).feat])
|
||||
#define cst_cart_node_yes(n,tree) (n+1)
|
||||
#define cst_cart_node_no(n,tree) (cst_cart_node_n(n,tree).no_node)
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
#if CART_DEBUG
|
||||
static void cart_print_node(int n, const cst_cart *tree)
|
||||
{
|
||||
printf("%s ",cst_cart_node_feat(n,tree));
|
||||
if (cst_cart_node_op(n,tree) == CST_CART_OP_IS)
|
||||
printf("IS ");
|
||||
else if (cst_cart_node_op(n,tree) == CST_CART_OP_LESS)
|
||||
printf("< ");
|
||||
else if (cst_cart_node_op(n,tree) == CST_CART_OP_GREATER)
|
||||
printf("> ");
|
||||
else if (cst_cart_node_op(n,tree) == CST_CART_OP_IN)
|
||||
printf("IN ");
|
||||
else if (cst_cart_node_op(n,tree) == CST_CART_OP_MATCHES)
|
||||
printf("MATCHES ");
|
||||
else
|
||||
printf("*%d* ",cst_cart_node_op(n,tree));
|
||||
val_print(stdout,cst_cart_node_val(n,tree));
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
const cst_val *cart_interpret(cst_item *item, const cst_cart *tree)
|
||||
{
|
||||
/* Tree interpretation */
|
||||
const cst_val *v=0;
|
||||
const cst_val *tree_val;
|
||||
const char *tree_feat = "";
|
||||
cst_features *fcache;
|
||||
int r=0;
|
||||
int node=0;
|
||||
|
||||
fcache = new_features_local(item_utt(item)->ctx);
|
||||
|
||||
while (cst_cart_node_op(node,tree) != CST_CART_OP_LEAF)
|
||||
{
|
||||
#if CART_DEBUG
|
||||
cart_print_node(node,tree);
|
||||
#endif
|
||||
tree_feat = cst_cart_node_feat(node,tree);
|
||||
|
||||
v = get_param_val(fcache,tree_feat,0);
|
||||
if (v == 0)
|
||||
{
|
||||
v = ffeature(item,tree_feat);
|
||||
feat_set(fcache,tree_feat,v);
|
||||
}
|
||||
|
||||
#if CART_DEBUG
|
||||
val_print(stdout,v); printf("\n");
|
||||
#endif
|
||||
tree_val = cst_cart_node_val(node,tree);
|
||||
if (cst_cart_node_op(node,tree) == CST_CART_OP_IS)
|
||||
r = val_equal(v,tree_val);
|
||||
else if (cst_cart_node_op(node,tree) == CST_CART_OP_LESS)
|
||||
r = val_less(v,tree_val);
|
||||
else if (cst_cart_node_op(node,tree) == CST_CART_OP_GREATER)
|
||||
r = val_greater(v,tree_val);
|
||||
else if (cst_cart_node_op(node,tree) == CST_CART_OP_IN)
|
||||
r = val_member(v,tree_val);
|
||||
else if (cst_cart_node_op(node,tree) == CST_CART_OP_MATCHES)
|
||||
r = cst_regex_match(cst_regex_table[val_int(tree_val)],
|
||||
val_string(v));
|
||||
else
|
||||
{
|
||||
cst_errmsg("cart_interpret_question: unknown op type %d\n",
|
||||
cst_cart_node_op(node,tree));
|
||||
cst_error();
|
||||
}
|
||||
|
||||
if (r)
|
||||
{ /* Oh yes it is */
|
||||
#if CART_DEBUG
|
||||
printf(" YES\n");
|
||||
#endif
|
||||
node = cst_cart_node_yes(node,tree);
|
||||
}
|
||||
else
|
||||
{ /* Oh no it isn't */
|
||||
#if CART_DEBUG
|
||||
printf(" NO\n");
|
||||
#endif
|
||||
node = cst_cart_node_no(node,tree);
|
||||
}
|
||||
}
|
||||
|
||||
delete_features(fcache);
|
||||
|
||||
return cst_cart_node_val(node,tree);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,803 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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"
|
||||
|
||||
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);
|
||||
#ifdef FLITE_PLUS_HTS_ENGINE
|
||||
const cst_val *accented(const cst_item *p);
|
||||
#else
|
||||
static const cst_val *accented(const cst_item *p);
|
||||
#endif /* FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
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 this;
|
||||
start = (float)ffeature_int(p,"R:mcep_link.parent.daughter1.frame_number");
|
||||
end = (float)ffeature_int(p,"R:mcep_link.parent.daughtern.frame_number");
|
||||
this = item_feat_int(p,"frame_number");
|
||||
if ((end-start) == 0.0)
|
||||
return float_val(0.0);
|
||||
else
|
||||
return float_val((this-start)/(end-start));
|
||||
}
|
||||
|
||||
const cst_val *cg_state_index(const cst_item *p)
|
||||
{
|
||||
float start;
|
||||
int this;
|
||||
start = (float)ffeature_int(p,"R:mcep_link.parent.daughter1.frame_number");
|
||||
this = item_feat_int(p,"frame_number");
|
||||
return float_val(this-start);
|
||||
}
|
||||
|
||||
const cst_val *cg_state_rindex(const cst_item *p)
|
||||
{
|
||||
float end;
|
||||
int this;
|
||||
end = (float)ffeature_int(p,"R:mcep_link.parent.daughtern.frame_number");
|
||||
this = item_feat_int(p,"frame_number");
|
||||
return float_val(end-this);
|
||||
}
|
||||
|
||||
const cst_val *cg_phone_place(const cst_item *p)
|
||||
{
|
||||
float start, end;
|
||||
int this;
|
||||
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");
|
||||
this = item_feat_int(p,"frame_number");
|
||||
if ((end-start) == 0.0)
|
||||
return float_val(0.0);
|
||||
else
|
||||
return float_val((this-start)/(end-start));
|
||||
}
|
||||
|
||||
const cst_val *cg_phone_index(const cst_item *p)
|
||||
{
|
||||
float start;
|
||||
int this;
|
||||
start = (float)ffeature_int(p,"R:mcep_link.parent.R:segstate.parent.daughter1.R:mcep_link.daughter1.frame_number");
|
||||
this = item_feat_int(p,"frame_number");
|
||||
return float_val(this-start);
|
||||
}
|
||||
|
||||
const cst_val *cg_phone_rindex(const cst_item *p)
|
||||
{
|
||||
float end;
|
||||
int this;
|
||||
end = (float)ffeature_int(p,"R:mcep_link.parent.R:segstate.parent.daughtern.R:mcep_link.daughtern.frame_number");
|
||||
this = item_feat_int(p,"frame_number");
|
||||
return float_val(end-this);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FLITE_PLUS_HTS_ENGINE
|
||||
const cst_val *accented(const cst_item *syl)
|
||||
#else
|
||||
static const cst_val *accented(const cst_item *syl)
|
||||
#endif
|
||||
{
|
||||
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 *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 = (cst_val *) &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");
|
||||
|
||||
/* This should actually include the first syllable, but Festival's
|
||||
doesn't. */
|
||||
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",item_feat_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");
|
||||
|
||||
for (c=0, p=item_next(ss);
|
||||
p && (c < CST_CONST_INT_MAX);
|
||||
p=item_next(p))
|
||||
{
|
||||
if (cst_streq("1",item_feat_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_INT_0; /* hmm, no sylstructure */
|
||||
else if (item_next(ss) != NULL)
|
||||
return VAL_INT_0; /* word internal */
|
||||
else if (path_to_item(ss,"R:SylStructure.parent.R:Word.n") == NULL)
|
||||
return VAL_INT_4; /* utterance final */
|
||||
else if (path_to_item(ss,"R:SylStructure.parent.R:Phrase.n") == NULL)
|
||||
return VAL_INT_3; /* phrase final */
|
||||
else
|
||||
return VAL_INT_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");
|
||||
|
||||
for (c=0, p=ss;
|
||||
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");
|
||||
|
||||
for (c=0, p=ss;
|
||||
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_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, "segment_duration",segment_duration);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 2000 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Voice definition */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_val.h"
|
||||
#include "cst_utterance.h"
|
||||
#include "cst_item.h"
|
||||
#include "cst_phoneset.h"
|
||||
|
||||
CST_VAL_REGISTER_TYPE_NODEL(phoneset,cst_phoneset)
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
cst_phoneset *new_phoneset()
|
||||
{
|
||||
/* These aren't going to be supported dynamically */
|
||||
cst_phoneset *v = cst_alloc(struct cst_phoneset_struct,1);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void delete_phoneset(cst_phoneset *v)
|
||||
{
|
||||
if (v)
|
||||
{
|
||||
cst_free(v);
|
||||
}
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
int phone_id(const cst_phoneset *ps,const char* phonename)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i< ps->num_phones; i++)
|
||||
if (cst_streq(ps->phonenames[i],phonename))
|
||||
return i;
|
||||
/* Wonder if I should print an error here or not */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int phone_feat_id(const cst_phoneset *ps,const char* featname)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; ps->featnames[i]; i++)
|
||||
if (cst_streq(ps->featnames[i],featname))
|
||||
return i;
|
||||
|
||||
/* Wonder if I should print an error here or not */
|
||||
return 0;
|
||||
}
|
||||
|
||||
const cst_val *phone_feature(const cst_phoneset *ps,
|
||||
const char* phonename,
|
||||
const char *featname)
|
||||
{
|
||||
return ps->featvals[ps->fvtable[phone_id(ps,phonename)]
|
||||
[phone_feat_id(ps,featname)]];
|
||||
}
|
||||
|
||||
const char *phone_feature_string(const cst_phoneset *ps,
|
||||
const char* phonename,
|
||||
const char *featname)
|
||||
{
|
||||
return val_string(phone_feature(ps,phonename,featname));
|
||||
}
|
||||
|
||||
|
||||
const cst_phoneset *item_phoneset(const cst_item *p)
|
||||
{
|
||||
return val_phoneset(feat_val(item_utt(p)->features,"phoneset"));
|
||||
}
|
||||
@@ -0,0 +1,696 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 2000 */
|
||||
/* 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: September 2000 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* General synthesis control */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_cart.h"
|
||||
#include "cst_tokenstream.h"
|
||||
#include "cst_utt_utils.h"
|
||||
#include "cst_lexicon.h"
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
#include "cst_units.h"
|
||||
#endif /* !FLITE_PLUS_HTS_ENIGINE */
|
||||
#include "cst_synth.h"
|
||||
#include "cst_phoneset.h"
|
||||
|
||||
CST_VAL_REGISTER_FUNCPTR(breakfunc,cst_breakfunc)
|
||||
|
||||
#ifndef SYNTH_MODULES_DEBUG
|
||||
#define SYNTH_MODULES_DEBUG 0
|
||||
#endif
|
||||
|
||||
#if SYNTH_MODULES_DEBUG > 0
|
||||
#define DPRINTF(l,x) if (SYNTH_MODULES_DEBUG > l) cst_dbgmsg x
|
||||
#else
|
||||
#define DPRINTF(l,x)
|
||||
#endif
|
||||
|
||||
static cst_utterance *tokentosegs(cst_utterance *u);
|
||||
|
||||
static const cst_synth_module synth_method_text[] = {
|
||||
{ "tokenizer_func", default_tokenization },
|
||||
{ "textanalysis_func", default_textanalysis },
|
||||
{ "pos_tagger_func", default_pos_tagger },
|
||||
{ "phrasing_func", default_phrasing },
|
||||
{ "lexical_insertion_func", default_lexical_insertion },
|
||||
{ "pause_insertion_func", default_pause_insertion },
|
||||
{ "intonation_func", cart_intonation },
|
||||
{ "postlex_func", NULL },
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
{ "duration_model_func", cart_duration },
|
||||
{ "f0_model_func", NULL },
|
||||
{ "wave_synth_func", NULL },
|
||||
{ "post_synth_hook_func", NULL },
|
||||
#endif /* !FLITE_PLUS_HTS_ENIGINE */
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
static const cst_synth_module synth_method_text2segs[] = {
|
||||
{ "tokenizer_func", default_tokenization },
|
||||
{ "textanalysis_func", default_textanalysis },
|
||||
{ "pos_tagger_func", default_pos_tagger },
|
||||
{ "phrasing_func", default_phrasing },
|
||||
{ "lexical_insertion_func", default_lexical_insertion },
|
||||
{ "pause_insertion_func", default_pause_insertion },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const cst_synth_module synth_method_tokens[] = {
|
||||
{ "textanalysis_func", default_textanalysis },
|
||||
{ "pos_tagger_func", default_pos_tagger },
|
||||
{ "phrasing_func", default_phrasing },
|
||||
{ "lexical_insertion_func", default_lexical_insertion },
|
||||
{ "pause_insertion_func", default_pause_insertion },
|
||||
{ "intonation_func", cart_intonation },
|
||||
{ "postlex_func", NULL },
|
||||
{ "duration_model_func", cart_duration },
|
||||
{ "f0_model_func", NULL },
|
||||
{ "wave_synth_func", NULL },
|
||||
{ "post_synth_hook_func", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const cst_synth_module synth_method_phones[] = {
|
||||
{ "tokenizer_func", default_tokenization },
|
||||
{ "textanalysis_func", tokentosegs },
|
||||
{ "pos_tagger_func", default_pos_tagger },
|
||||
{ "intonation_func", NULL },
|
||||
{ "duration_model_func", cart_duration },
|
||||
{ "f0_model_func", flat_prosody },
|
||||
{ "wave_synth_func", NULL },
|
||||
{ "post_synth_hook_func", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
cst_utterance *apply_synth_module(cst_utterance *u,
|
||||
const cst_synth_module *mod)
|
||||
{
|
||||
const cst_val *v;
|
||||
|
||||
v = feat_val(u->features, mod->hookname);
|
||||
if (v)
|
||||
return (*val_uttfunc(v))(u);
|
||||
if (mod->defhook)
|
||||
return (*mod->defhook)(u);
|
||||
return u;
|
||||
}
|
||||
|
||||
cst_utterance *apply_synth_method(cst_utterance *u,
|
||||
const cst_synth_module meth[])
|
||||
{
|
||||
while (meth->hookname)
|
||||
{
|
||||
if ((u = apply_synth_module(u, meth)) == NULL)
|
||||
return NULL;
|
||||
++meth;
|
||||
}
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
cst_utterance *utt_init(cst_utterance *u, cst_voice *vox)
|
||||
{
|
||||
feat_copy_into(vox->features,u->features);
|
||||
feat_copy_into(vox->ffunctions,u->ffunctions);
|
||||
if (vox->utt_init)
|
||||
vox->utt_init(u, vox);
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
cst_utterance *utt_synth(cst_utterance *u)
|
||||
{
|
||||
return apply_synth_method(u, synth_method_text);
|
||||
}
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
cst_utterance *utt_synth_tokens(cst_utterance *u)
|
||||
{
|
||||
return apply_synth_method(u, synth_method_tokens);
|
||||
}
|
||||
|
||||
cst_utterance *utt_synth_text2segs(cst_utterance *u)
|
||||
{
|
||||
return apply_synth_method(u, synth_method_text2segs);
|
||||
}
|
||||
|
||||
cst_utterance *utt_synth_phones(cst_utterance *u)
|
||||
{
|
||||
return apply_synth_method(u, synth_method_phones);
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
cst_utterance *default_tokenization(cst_utterance *u)
|
||||
{
|
||||
const char *text,*token;
|
||||
cst_tokenstream *fd;
|
||||
cst_item *t;
|
||||
cst_relation *r;
|
||||
|
||||
text = utt_input_text(u);
|
||||
r = utt_relation_create(u,"Token");
|
||||
fd = ts_open_string(text,
|
||||
get_param_string(u->features,"text_whitespace",NULL),
|
||||
get_param_string(u->features,"text_singlecharsymbols",NULL),
|
||||
get_param_string(u->features,"text_prepunctuation",NULL),
|
||||
get_param_string(u->features,"text_postpunctuation",NULL));
|
||||
|
||||
while(!ts_eof(fd))
|
||||
{
|
||||
token = ts_get(fd);
|
||||
if (cst_strlen(token) > 0)
|
||||
{
|
||||
t = relation_append(r,NULL);
|
||||
item_set_string(t,"name",token);
|
||||
item_set_string(t,"whitespace",fd->whitespace);
|
||||
item_set_string(t,"prepunctuation",fd->prepunctuation);
|
||||
item_set_string(t,"punc",fd->postpunctuation);
|
||||
item_set_int(t,"file_pos",fd->file_pos);
|
||||
item_set_int(t,"line_number",fd->line_number);
|
||||
}
|
||||
}
|
||||
|
||||
ts_close(fd);
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
cst_val *default_tokentowords(cst_item *i)
|
||||
{
|
||||
return cons_val(string_val(item_feat_string(i,"name")), NULL);
|
||||
}
|
||||
|
||||
cst_utterance *default_textanalysis(cst_utterance *u)
|
||||
{
|
||||
cst_item *t,*word;
|
||||
cst_relation *word_rel;
|
||||
cst_val *words;
|
||||
const cst_val *w;
|
||||
const cst_val *ttwv;
|
||||
|
||||
word_rel = utt_relation_create(u,"Word");
|
||||
ttwv = feat_val(u->features, "tokentowords_func");
|
||||
|
||||
for (t=relation_head(utt_relation(u,"Token")); t; t=item_next(t))
|
||||
{
|
||||
if (ttwv)
|
||||
words = (cst_val *)(*val_itemfunc(ttwv))(t);
|
||||
else
|
||||
words = default_tokentowords(t);
|
||||
|
||||
for (w=words; w; w=val_cdr(w))
|
||||
{
|
||||
word = item_add_daughter(t,NULL);
|
||||
if (cst_val_consp(val_car(w)))
|
||||
{ /* Has extra features */
|
||||
item_set_string(word,"name",val_string(val_car(val_car(w))));
|
||||
feat_copy_into(val_features(val_cdr(val_car(w))),
|
||||
item_feats(word));
|
||||
}
|
||||
else
|
||||
item_set_string(word,"name",val_string(val_car(w)));
|
||||
relation_append(word_rel,word);
|
||||
}
|
||||
delete_val(words);
|
||||
}
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
cst_utterance *default_phrasing(cst_utterance *u)
|
||||
{
|
||||
cst_relation *r;
|
||||
cst_item *w, *p, *lp=NULL;
|
||||
const cst_val *v;
|
||||
cst_cart *phrasing_cart;
|
||||
|
||||
r = utt_relation_create(u,"Phrase");
|
||||
phrasing_cart = val_cart(feat_val(u->features,"phrasing_cart"));
|
||||
|
||||
for (p=NULL,w=relation_head(utt_relation(u,"Word")); w; w=item_next(w))
|
||||
{
|
||||
if (p == NULL)
|
||||
{
|
||||
p = relation_append(r,NULL);
|
||||
lp = p;
|
||||
#ifdef FLITE_PLUS_HTS_ENGINE
|
||||
item_set_string(p,"name","BB");
|
||||
#else
|
||||
item_set_string(p,"name","B");
|
||||
#endif /* FLITE_PLUS_HTS_ENGINE */
|
||||
}
|
||||
item_add_daughter(p,w);
|
||||
v = cart_interpret(w,phrasing_cart);
|
||||
if (cst_streq(val_string(v),"BB"))
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
if (lp && item_prev(lp)) /* follow festival */
|
||||
item_set_string(lp,"name","BB");
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
cst_utterance *default_pause_insertion(cst_utterance *u)
|
||||
{
|
||||
/* Add initial silences and silence at each phrase break */
|
||||
const char *silence;
|
||||
const cst_item *w;
|
||||
cst_item *p, *s;
|
||||
|
||||
silence = val_string(feat_val(u->features,"silence"));
|
||||
|
||||
/* Insert initial silence */
|
||||
s = relation_head(utt_relation(u,"Segment"));
|
||||
if (s == NULL)
|
||||
s = relation_append(utt_relation(u,"Segment"),NULL);
|
||||
else
|
||||
s = item_prepend(s,NULL);
|
||||
item_set_string(s,"name",silence);
|
||||
|
||||
for (p=relation_head(utt_relation(u,"Phrase")); p; p=item_next(p))
|
||||
{
|
||||
for (w = item_last_daughter(p); w; w=item_prev(w))
|
||||
{
|
||||
s = path_to_item(w,"R:SylStructure.daughtern.daughtern.R:Segment");
|
||||
if (s)
|
||||
{
|
||||
s = item_append(s,NULL);
|
||||
item_set_string(s,"name",silence);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
cst_utterance *cart_intonation(cst_utterance *u)
|
||||
{
|
||||
cst_cart *accents, *tones;
|
||||
cst_item *s;
|
||||
const cst_val *v;
|
||||
|
||||
if (feat_present(u->features,"no_intonation_accent_model"))
|
||||
return u; /* not all languages have intonation models */
|
||||
|
||||
accents = val_cart(feat_val(u->features,"int_cart_accents"));
|
||||
tones = val_cart(feat_val(u->features,"int_cart_tones"));
|
||||
|
||||
for (s=relation_head(utt_relation(u,"Syllable")); s; s=item_next(s))
|
||||
{
|
||||
v = cart_interpret(s,accents);
|
||||
if (!cst_streq("NONE",val_string(v)))
|
||||
item_set_string(s,"accent",val_string(v));
|
||||
v = cart_interpret(s,tones);
|
||||
if (!cst_streq("NONE",val_string(v)))
|
||||
item_set_string(s,"endtone",val_string(v));
|
||||
DPRINTF(0,("word %s gpos %s stress %s ssyl_in %s ssyl_out %s accent %s endtone %s\n",
|
||||
ffeature_string(s,"R:SylStructure.parent.name"),
|
||||
ffeature_string(s,"R:SylStructure.parent.gpos"),
|
||||
ffeature_string(s,"stress"),
|
||||
ffeature_string(s,"ssyl_in"),
|
||||
ffeature_string(s,"ssyl_out"),
|
||||
ffeature_string(s,"accent"),
|
||||
ffeature_string(s,"endtone")));
|
||||
}
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
CST_VAL_REGISTER_TYPE_NODEL(dur_stats,dur_stats)
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
const dur_stat *phone_dur_stat(const dur_stats *ds,const char *ph)
|
||||
{
|
||||
int i;
|
||||
for (i=0; ds[i]; i++)
|
||||
if (cst_streq(ph,ds[i]->phone))
|
||||
return ds[i];
|
||||
|
||||
return ds[0];
|
||||
}
|
||||
|
||||
cst_utterance *cart_duration(cst_utterance *u)
|
||||
{
|
||||
cst_cart *dur_tree;
|
||||
cst_item *s;
|
||||
float zdur, dur_stretch, local_dur_stretch, dur;
|
||||
float end;
|
||||
dur_stats *ds;
|
||||
const dur_stat *dur_stat;
|
||||
|
||||
end = 0;
|
||||
|
||||
if (feat_present(u->features,"no_segment_duration_model"))
|
||||
return u; /* not all methods need segment durations */
|
||||
|
||||
dur_tree = val_cart(feat_val(u->features,"dur_cart"));
|
||||
dur_stretch = get_param_float(u->features,"duration_stretch", 1.0);
|
||||
ds = val_dur_stats(feat_val(u->features,"dur_stats"));
|
||||
|
||||
for (s=relation_head(utt_relation(u,"Segment")); s; s=item_next(s))
|
||||
{
|
||||
zdur = val_float(cart_interpret(s,dur_tree));
|
||||
dur_stat = phone_dur_stat(ds,item_name(s));
|
||||
|
||||
local_dur_stretch = ffeature_float(s, "R:SylStructure.parent.parent."
|
||||
"R:Token.parent.local_duration_stretch");
|
||||
if (local_dur_stretch)
|
||||
local_dur_stretch *= dur_stretch;
|
||||
else
|
||||
local_dur_stretch = dur_stretch;
|
||||
|
||||
dur = local_dur_stretch * ((zdur*dur_stat->stddev)+dur_stat->mean);
|
||||
DPRINTF(0,("phone %s accent %s stress %s pdur %f stretch %f mean %f std %f dur %f\n",
|
||||
item_name(s),
|
||||
ffeature_string(s,"R:SylStructure.parent.accented"),
|
||||
ffeature_string(s,"R:SylStructure.parent.stress"),
|
||||
zdur, local_dur_stretch, dur_stat->mean,
|
||||
dur_stat->stddev, dur));
|
||||
end += dur;
|
||||
item_set_float(s,"end",end);
|
||||
}
|
||||
return u;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENIGINE */
|
||||
|
||||
cst_utterance *default_pos_tagger(cst_utterance *u)
|
||||
{
|
||||
cst_item *word;
|
||||
const cst_val *p;
|
||||
const cst_cart *tagger;
|
||||
|
||||
p = get_param_val(u->features,"pos_tagger_cart",NULL);
|
||||
if (p == NULL)
|
||||
return u;
|
||||
tagger = val_cart(p);
|
||||
|
||||
for (word=relation_head(utt_relation(u,"Word"));
|
||||
word; word=item_next(word))
|
||||
{
|
||||
p = cart_interpret(word,tagger);
|
||||
item_set_string(word,"pos",val_string(p));
|
||||
}
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
cst_utterance *default_lexical_insertion(cst_utterance *u)
|
||||
{
|
||||
cst_item *word;
|
||||
cst_relation *sylstructure,*seg,*syl;
|
||||
cst_lexicon *lex;
|
||||
const cst_val *lex_addenda = NULL;
|
||||
const cst_val *p, *wp = NULL;
|
||||
char *phone_name;
|
||||
char *stress = "0";
|
||||
const char *pos;
|
||||
cst_val *phones;
|
||||
cst_item *ssword, *sssyl, *segitem, *sylitem, *seg_in_syl;
|
||||
|
||||
lex = val_lexicon(feat_val(u->features,"lexicon"));
|
||||
if (lex->lex_addenda)
|
||||
lex_addenda = lex->lex_addenda;
|
||||
|
||||
syl = utt_relation_create(u,"Syllable");
|
||||
sylstructure = utt_relation_create(u,"SylStructure");
|
||||
seg = utt_relation_create(u,"Segment");
|
||||
|
||||
for (word=relation_head(utt_relation(u,"Word"));
|
||||
word; word=item_next(word))
|
||||
{
|
||||
ssword = relation_append(sylstructure,word);
|
||||
pos = ffeature_string(word,"pos");
|
||||
phones = NULL;
|
||||
wp = NULL;
|
||||
|
||||
/* printf("awb_debug word %s pos %s gpos %s\n",
|
||||
item_feat_string(word,"name"),
|
||||
pos,
|
||||
ffeature_string(word,"gpos")); */
|
||||
|
||||
/* FIXME: need to make sure that textanalysis won't split
|
||||
tokens with explicit pronunciation (or that it will
|
||||
propagate such to words, then we can remove the path here) */
|
||||
if (item_feat_present(item_parent(item_as(word, "Token")), "phones"))
|
||||
phones = (cst_val *) item_feat(item_parent(item_as(word, "Token")), "phones");
|
||||
else
|
||||
{
|
||||
wp = val_assoc_string(item_feat_string(word, "name"),lex_addenda);
|
||||
if (wp)
|
||||
phones = (cst_val *)val_cdr(val_cdr(wp));
|
||||
else
|
||||
phones = lex_lookup(lex,item_feat_string(word,"name"),pos);
|
||||
}
|
||||
|
||||
for (sssyl=NULL,sylitem=NULL,p=phones; p; p=val_cdr(p))
|
||||
{
|
||||
if (sylitem == NULL)
|
||||
{
|
||||
sylitem = relation_append(syl,NULL);
|
||||
sssyl = item_add_daughter(ssword,sylitem);
|
||||
stress = "0";
|
||||
}
|
||||
segitem = relation_append(seg,NULL);
|
||||
phone_name = cst_strdup(val_string(val_car(p)));
|
||||
if (phone_name[cst_strlen(phone_name)-1] == '1')
|
||||
{
|
||||
stress = "1";
|
||||
phone_name[cst_strlen(phone_name)-1] = '\0';
|
||||
}
|
||||
else if (phone_name[cst_strlen(phone_name)-1] == '0')
|
||||
{
|
||||
stress = "0";
|
||||
phone_name[cst_strlen(phone_name)-1] = '\0';
|
||||
}
|
||||
item_set_string(segitem,"name",phone_name);
|
||||
seg_in_syl = item_add_daughter(sssyl,segitem);
|
||||
#if 0
|
||||
printf("awb_debug ph %s\n",phone_name);
|
||||
#endif
|
||||
if ((lex->syl_boundary)(seg_in_syl,val_cdr(p)))
|
||||
{
|
||||
#if 0
|
||||
printf("awb_debug SYL\n");
|
||||
#endif
|
||||
sylitem = NULL;
|
||||
if (sssyl)
|
||||
item_set_string(sssyl,"stress",stress);
|
||||
}
|
||||
cst_free(phone_name);
|
||||
}
|
||||
if (!item_feat_present(item_parent(item_as(word, "Token")), "phones")
|
||||
&& ! wp)
|
||||
delete_val(phones);
|
||||
}
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
/* Dummy F0 modelling for phones, copied directly from us_f0_model.c */
|
||||
cst_utterance *flat_prosody(cst_utterance *u)
|
||||
{
|
||||
/* F0 target model */
|
||||
cst_item *s,*t;
|
||||
cst_relation *targ_rel;
|
||||
float mean, stddev;
|
||||
|
||||
targ_rel = utt_relation_create(u,"Target");
|
||||
mean = get_param_float(u->features,"target_f0_mean", 100.0);
|
||||
mean *= get_param_float(u->features,"f0_shift", 1.0);
|
||||
stddev = get_param_float(u->features,"target_f0_stddev", 12.0);
|
||||
|
||||
s=relation_head(utt_relation(u,"Segment"));
|
||||
t = relation_append(targ_rel,NULL);
|
||||
item_set_float(t,"pos",0.0);
|
||||
item_set_float(t,"f0",mean+stddev);
|
||||
|
||||
s=relation_tail(utt_relation(u,"Segment"));
|
||||
t = relation_append(targ_rel,NULL);
|
||||
|
||||
item_set_float(t,"pos",item_feat_float(s,"end"));
|
||||
item_set_float(t,"f0",mean-stddev);
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
static cst_utterance *tokentosegs(cst_utterance *u)
|
||||
{
|
||||
cst_item *t;
|
||||
cst_relation *seg, *syl, *sylstructure, *word;
|
||||
cst_item *sylitem, *sylstructureitem, *worditem, *sssyl;
|
||||
cst_phoneset *ps;
|
||||
|
||||
ps = val_phoneset(utt_feat_val(u, "phoneset"));
|
||||
/* Just copy tokens into the Segment relation */
|
||||
seg = utt_relation_create(u, "Segment");
|
||||
syl = utt_relation_create(u, "Syllable");
|
||||
word = utt_relation_create(u, "Word");
|
||||
sylstructure = utt_relation_create(u, "SylStructure");
|
||||
sssyl = sylitem = worditem = sylstructureitem = 0;
|
||||
for (t = relation_head(utt_relation(u, "Token")); t; t = item_next(t))
|
||||
{
|
||||
cst_item *segitem = relation_append(seg, NULL);
|
||||
char const *pname = item_feat_string(t, "name");
|
||||
char *name = cst_strdup(pname);
|
||||
|
||||
if (worditem == 0)
|
||||
{
|
||||
worditem = relation_append(word,NULL);
|
||||
item_set_string(worditem, "name", "phonestring");
|
||||
sylstructureitem = relation_append(sylstructure,worditem);
|
||||
}
|
||||
if (sylitem == 0)
|
||||
{
|
||||
sylitem = relation_append(syl,NULL);
|
||||
sssyl = item_add_daughter(sylstructureitem,sylitem);
|
||||
}
|
||||
|
||||
if (name[cst_strlen(name)-1] == '1')
|
||||
{
|
||||
item_set_string(sssyl,"stress","1");
|
||||
name[cst_strlen(name)-1] = '\0';
|
||||
}
|
||||
else if (name[cst_strlen(name)-1] == '0')
|
||||
{
|
||||
item_set_string(sssyl,"stress","0");
|
||||
name[cst_strlen(name)-1] = '\0';
|
||||
}
|
||||
|
||||
if (cst_streq(name,"-"))
|
||||
{
|
||||
sylitem = 0; /* syllable break */
|
||||
}
|
||||
else if (phone_id(ps, name) == -1)
|
||||
{
|
||||
cst_errmsg("Phone `%s' not in phoneset\n", pname);
|
||||
cst_error();
|
||||
}
|
||||
else
|
||||
{
|
||||
item_add_daughter(sssyl,segitem);
|
||||
item_set_string(segitem, "name", name);
|
||||
}
|
||||
|
||||
cst_free(name);
|
||||
}
|
||||
|
||||
return u;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENIGINE */
|
||||
|
||||
int default_utt_break(cst_tokenstream *ts,
|
||||
const char *token,
|
||||
cst_relation *tokens)
|
||||
{
|
||||
/* This is the default utt break functions, languages may override this */
|
||||
/* This will be ok for some latin based languages */
|
||||
const char *postpunct = item_feat_string(relation_tail(tokens), "punc");
|
||||
const char *ltoken = item_name(relation_tail(tokens));
|
||||
|
||||
if (cst_strchr(ts->whitespace,'\n') != cst_strrchr(ts->whitespace,'\n'))
|
||||
/* contains two new lines */
|
||||
return TRUE;
|
||||
else if (strchr(postpunct,':') ||
|
||||
strchr(postpunct,'?') ||
|
||||
strchr(postpunct,'!'))
|
||||
return TRUE;
|
||||
else if (strchr(postpunct,'.') &&
|
||||
(cst_strlen(ts->whitespace) > 1) &&
|
||||
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ",token[0]))
|
||||
return TRUE;
|
||||
else if (strchr(postpunct,'.') &&
|
||||
/* next word starts with a capital */
|
||||
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ",token[0]) &&
|
||||
/* last word isn't an abbreviation */
|
||||
!(strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ",ltoken[cst_strlen(ltoken)-1])||
|
||||
((cst_strlen(ltoken) < 4) &&
|
||||
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ",ltoken[0]))))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 2000 */
|
||||
/* 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: September 2000 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Various basic utt utilities */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_synth.h"
|
||||
#include "cst_utt_utils.h"
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
cst_wave *utt_wave(cst_utterance *u)
|
||||
{
|
||||
if (u)
|
||||
return val_wave(feat_val(u->features,"wave"));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int utt_set_wave(cst_utterance *u, cst_wave *w)
|
||||
{
|
||||
feat_set(u->features,"wave",wave_val(w));
|
||||
return 0;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
const char *utt_input_text(cst_utterance *u)
|
||||
{
|
||||
return val_string(feat_val(u->features,"input_text"));
|
||||
}
|
||||
|
||||
int utt_set_input_text(cst_utterance *u,const char *text)
|
||||
{
|
||||
feat_set_string(u->features,"input_text",text);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 2000 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Voice definition */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
#include "cst_alloc.h"
|
||||
#include "cst_voice.h"
|
||||
|
||||
CST_VAL_REGISTER_TYPE(voice,cst_voice)
|
||||
|
||||
cst_voice *new_voice()
|
||||
{
|
||||
cst_voice *v = cst_alloc(struct cst_voice_struct,1);
|
||||
|
||||
v->features = new_features();
|
||||
v->ffunctions = new_features();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void delete_voice(cst_voice *v)
|
||||
{
|
||||
if (v)
|
||||
{
|
||||
delete_features(v->features);
|
||||
delete_features(v->ffunctions);
|
||||
/* do not delete any dbs in the voice */
|
||||
/* they are probably const and not deletable -- at least */
|
||||
/* that is true at present */
|
||||
cst_free(v);
|
||||
}
|
||||
}
|
||||
+415
@@ -0,0 +1,415 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 2000-2008 */
|
||||
/* 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: September 2000 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Basic user level functions */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_tokenstream.h"
|
||||
#include "flite.h"
|
||||
|
||||
/* This is a global, which isn't ideal, this may change */
|
||||
/* It is set when flite_set_voice_list() is called which happens in */
|
||||
/* flite_main() */
|
||||
cst_val *flite_voice_list = 0;
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
int flite_init()
|
||||
{
|
||||
cst_regex_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
cst_voice *flite_voice_select(const char *name)
|
||||
{
|
||||
const cst_val *v;
|
||||
cst_voice *voice;
|
||||
|
||||
if (flite_voice_list == NULL)
|
||||
return NULL; /* oops, not good */
|
||||
if (name == NULL)
|
||||
return val_voice(val_car(flite_voice_list));
|
||||
|
||||
for (v=flite_voice_list; v; v=val_cdr(v))
|
||||
{
|
||||
voice = val_voice(val_car(v));
|
||||
if (cst_streq(name,voice->name))
|
||||
return voice;
|
||||
}
|
||||
|
||||
return flite_voice_select(NULL);
|
||||
|
||||
}
|
||||
|
||||
int flite_voice_add_lex_addenda(cst_voice *v, const cst_string *lexfile)
|
||||
{
|
||||
/* Add addenda in lexfile to current voice */
|
||||
cst_lexicon *lex;
|
||||
const cst_val *lex_addenda = NULL;
|
||||
cst_val *new_addenda;
|
||||
|
||||
lex = val_lexicon(feat_val(v->features,"lexicon"));
|
||||
if (feat_present(v->features, "lex_addenda"))
|
||||
lex_addenda = feat_val(v->features, "lex_addenda");
|
||||
|
||||
new_addenda = cst_lex_load_addenda(lex,lexfile);
|
||||
#if 0
|
||||
printf("\naddenda: ");
|
||||
val_print(stdout,new_addenda);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
new_addenda = val_append(new_addenda,(cst_val *)lex_addenda);
|
||||
if (lex->lex_addenda)
|
||||
delete_val(lex->lex_addenda);
|
||||
lex->lex_addenda = new_addenda;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
cst_utterance *flite_do_synth(cst_utterance *u,
|
||||
cst_voice *voice,
|
||||
cst_uttfunc synth)
|
||||
{
|
||||
utt_init(u, voice);
|
||||
if ((*synth)(u) == NULL)
|
||||
{
|
||||
delete_utterance(u);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return u;
|
||||
}
|
||||
|
||||
cst_utterance *flite_synth_text(const char *text, cst_voice *voice)
|
||||
{
|
||||
cst_utterance *u;
|
||||
|
||||
u = new_utterance();
|
||||
utt_set_input_text(u,text);
|
||||
return flite_do_synth(u, voice, utt_synth);
|
||||
}
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
cst_utterance *flite_synth_phones(const char *text, cst_voice *voice)
|
||||
{
|
||||
cst_utterance *u;
|
||||
|
||||
u = new_utterance();
|
||||
utt_set_input_text(u,text);
|
||||
return flite_do_synth(u, voice, utt_synth_phones);
|
||||
}
|
||||
|
||||
cst_wave *flite_text_to_wave(const char *text, cst_voice *voice)
|
||||
{
|
||||
cst_utterance *u;
|
||||
cst_wave *w;
|
||||
|
||||
if ((u = flite_synth_text(text,voice)) == NULL)
|
||||
return NULL;
|
||||
|
||||
w = copy_wave(utt_wave(u));
|
||||
delete_utterance(u);
|
||||
return w;
|
||||
}
|
||||
|
||||
float flite_file_to_speech(const char *filename,
|
||||
cst_voice *voice,
|
||||
const char *outtype)
|
||||
{
|
||||
cst_utterance *utt;
|
||||
cst_tokenstream *ts;
|
||||
const char *token;
|
||||
cst_item *t;
|
||||
cst_relation *tokrel;
|
||||
float durs = 0;
|
||||
int num_tokens;
|
||||
cst_wave *w;
|
||||
cst_breakfunc breakfunc = default_utt_break;
|
||||
cst_uttfunc utt_user_callback = 0;
|
||||
int fp;
|
||||
|
||||
if ((ts = ts_open(filename,
|
||||
get_param_string(voice->features,"text_whitespace",NULL),
|
||||
get_param_string(voice->features,"text_singlecharsymbols",NULL),
|
||||
get_param_string(voice->features,"text_prepunctuation",NULL),
|
||||
get_param_string(voice->features,"text_postpunctuation",NULL)))
|
||||
== NULL)
|
||||
{
|
||||
cst_errmsg("failed to open file \"%s\" for reading\n",
|
||||
filename);
|
||||
return 1;
|
||||
}
|
||||
fp = get_param_int(voice->features,"file_start_position",0);
|
||||
if (fp > 0)
|
||||
ts_set_stream_pos(ts,fp);
|
||||
|
||||
if (feat_present(voice->features,"utt_break"))
|
||||
breakfunc = val_breakfunc(feat_val(voice->features,"utt_break"));
|
||||
|
||||
if (feat_present(voice->features,"utt_user_callback"))
|
||||
utt_user_callback = val_uttfunc(feat_val(voice->features,"utt_user_callback"));
|
||||
|
||||
/* If its a file to write to, create and save an empty wave file */
|
||||
/* as we are going to incrementally append to it */
|
||||
if (!cst_streq(outtype,"play") &&
|
||||
!cst_streq(outtype,"none") &&
|
||||
!cst_streq(outtype,"stream"))
|
||||
{
|
||||
w = new_wave();
|
||||
cst_wave_resize(w,0,1);
|
||||
cst_wave_set_sample_rate(w,16000);
|
||||
cst_wave_save_riff(w,outtype); /* an empty wave */
|
||||
delete_wave(w);
|
||||
}
|
||||
|
||||
num_tokens = 0;
|
||||
utt = new_utterance();
|
||||
tokrel = utt_relation_create(utt, "Token");
|
||||
while (!ts_eof(ts) || num_tokens > 0)
|
||||
{
|
||||
token = ts_get(ts);
|
||||
if ((cst_strlen(token) == 0) ||
|
||||
(num_tokens > 500) || /* need an upper bound */
|
||||
(relation_head(tokrel) &&
|
||||
breakfunc(ts,token,tokrel)))
|
||||
{
|
||||
/* An end of utt, so synthesize it */
|
||||
if (utt_user_callback)
|
||||
utt = (utt_user_callback)(utt);
|
||||
|
||||
if (utt)
|
||||
{
|
||||
utt = flite_do_synth(utt,voice,utt_synth_tokens);
|
||||
durs += flite_process_output(utt,outtype,TRUE);
|
||||
delete_utterance(utt); utt = NULL;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
if (ts_eof(ts)) break;
|
||||
|
||||
utt = new_utterance();
|
||||
tokrel = utt_relation_create(utt, "Token");
|
||||
num_tokens = 0;
|
||||
}
|
||||
num_tokens++;
|
||||
|
||||
t = relation_append(tokrel, NULL);
|
||||
item_set_string(t,"name",token);
|
||||
item_set_string(t,"whitespace",ts->whitespace);
|
||||
item_set_string(t,"prepunctuation",ts->prepunctuation);
|
||||
item_set_string(t,"punc",ts->postpunctuation);
|
||||
/* Mark it at the beginning of the token */
|
||||
item_set_int(t,"file_pos",
|
||||
ts->file_pos-(1+ /* as we are already on the next char */
|
||||
cst_strlen(token)+
|
||||
cst_strlen(ts->prepunctuation)+
|
||||
cst_strlen(ts->postpunctuation)));
|
||||
item_set_int(t,"line_number",ts->line_number);
|
||||
}
|
||||
|
||||
delete_utterance(utt);
|
||||
ts_close(ts);
|
||||
return durs;
|
||||
}
|
||||
|
||||
float flite_text_to_speech(const char *text,
|
||||
cst_voice *voice,
|
||||
const char *outtype)
|
||||
{
|
||||
cst_utterance *u;
|
||||
float dur;
|
||||
|
||||
u = flite_synth_text(text,voice);
|
||||
dur = flite_process_output(u,outtype,FALSE);
|
||||
delete_utterance(u);
|
||||
|
||||
return dur;
|
||||
}
|
||||
|
||||
float flite_phones_to_speech(const char *text,
|
||||
cst_voice *voice,
|
||||
const char *outtype)
|
||||
{
|
||||
cst_utterance *u;
|
||||
float dur;
|
||||
|
||||
u = flite_synth_phones(text,voice);
|
||||
dur = flite_process_output(u,outtype,FALSE);
|
||||
delete_utterance(u);
|
||||
|
||||
return dur;
|
||||
}
|
||||
|
||||
float flite_process_output(cst_utterance *u, const char *outtype,
|
||||
int append)
|
||||
{
|
||||
/* Play or save (append) output to output file */
|
||||
cst_wave *w;
|
||||
float dur;
|
||||
|
||||
if (!u) return 0.0;
|
||||
|
||||
w = utt_wave(u);
|
||||
|
||||
dur = (float)w->num_samples/(float)w->sample_rate;
|
||||
|
||||
if (cst_streq(outtype,"play"))
|
||||
play_wave(w);
|
||||
else if (cst_streq(outtype,"stream"))
|
||||
{
|
||||
/* It's already been played so do nothing */
|
||||
|
||||
}
|
||||
else if (!cst_streq(outtype,"none"))
|
||||
{
|
||||
if (append)
|
||||
cst_wave_append_riff(w,outtype);
|
||||
else
|
||||
cst_wave_save_riff(w,outtype);
|
||||
}
|
||||
|
||||
return dur;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
int flite_get_param_int(const cst_features *f, const char *name,int def)
|
||||
{
|
||||
return get_param_int(f,name,def);
|
||||
}
|
||||
float flite_get_param_float(const cst_features *f, const char *name, float def)
|
||||
{
|
||||
return get_param_float(f,name,def);
|
||||
}
|
||||
const char *flite_get_param_string(const cst_features *f, const char *name, const char *def)
|
||||
{
|
||||
return get_param_string(f,name,def);
|
||||
}
|
||||
const cst_val *flite_get_param_val(const cst_features *f, const char *name, cst_val *def)
|
||||
{
|
||||
return get_param_val(f,name,def);
|
||||
}
|
||||
|
||||
void flite_feat_set_int(cst_features *f, const char *name, int v)
|
||||
{
|
||||
feat_set_int(f,name,v);
|
||||
}
|
||||
void flite_feat_set_float(cst_features *f, const char *name, float v)
|
||||
{
|
||||
feat_set_float(f,name,v);
|
||||
}
|
||||
void flite_feat_set_string(cst_features *f, const char *name, const char *v)
|
||||
{
|
||||
feat_set_string(f,name,v);
|
||||
}
|
||||
void flite_feat_set(cst_features *f, const char *name,const cst_val *v)
|
||||
{
|
||||
feat_set(f,name,v);
|
||||
}
|
||||
|
||||
int flite_feat_remove(cst_features *f, const char *name)
|
||||
{
|
||||
return feat_remove(f,name);
|
||||
}
|
||||
|
||||
const char *flite_ffeature_string(const cst_item *item,const char *featpath)
|
||||
{
|
||||
return ffeature_string(item,featpath);
|
||||
}
|
||||
|
||||
int flite_ffeature_int(const cst_item *item,const char *featpath)
|
||||
{
|
||||
return ffeature_int(item,featpath);
|
||||
}
|
||||
float flite_ffeature_float(const cst_item *item,const char *featpath)
|
||||
{
|
||||
return ffeature_float(item,featpath);
|
||||
}
|
||||
const cst_val *flite_ffeature(const cst_item *item,const char *featpath)
|
||||
{
|
||||
return ffeature(item,featpath);
|
||||
}
|
||||
cst_item* flite_path_to_item(const cst_item *item,const char *featpath)
|
||||
{
|
||||
return path_to_item(item,featpath);
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: July 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Basic wraparounds for malloc and free */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
#include "cst_file.h"
|
||||
#include "cst_alloc.h"
|
||||
#include "cst_error.h"
|
||||
|
||||
#ifdef UNDER_CE
|
||||
#include <windows.h>
|
||||
#endif /* UNDER_CE */
|
||||
|
||||
/* define this if you want to trace memory usage */
|
||||
/* #define CST_DEBUG_MALLOC */
|
||||
/* #define CST_DEBUG_MALLOC_TRACE */
|
||||
#ifdef CST_DEBUG_MALLOC
|
||||
int cst_allocated = 0;
|
||||
int cst_freed = 0;
|
||||
int cst_alloc_max = 0;
|
||||
int cst_alloc_imax = 0;
|
||||
int cst_alloc_num_calls = 0;
|
||||
int cst_alloc_out = 0;
|
||||
#ifdef CST_DEBUG_MALLOC_TRACE
|
||||
/* This is a crude memory tracer to find leaks */
|
||||
int cst_alloc_ckpt = -1;
|
||||
/* You have to know how big this should be to use it, its for debuging only */
|
||||
#define NUM_CHUNKS 10000000
|
||||
void *cst_alloc_cunks[NUM_CHUNKS];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void *cst_safe_alloc(int size)
|
||||
{
|
||||
/* returns pointer to memory all set 0 */
|
||||
void *p = NULL;
|
||||
if (size < 0)
|
||||
{
|
||||
cst_errmsg("alloc: asked for negative size %d\n", size);
|
||||
cst_error();
|
||||
}
|
||||
else if (size == 0) /* some mallocs return NULL for this */
|
||||
size++;
|
||||
|
||||
#ifdef CST_DEBUG_MALLOC
|
||||
if (size > cst_alloc_imax)
|
||||
{
|
||||
cst_alloc_imax = size;
|
||||
}
|
||||
cst_allocated += size;
|
||||
cst_alloc_out += size;
|
||||
size += 2 * sizeof(int);
|
||||
#endif
|
||||
|
||||
#ifdef UNDER_CE
|
||||
p = (void *)LocalAlloc(LPTR, size);
|
||||
#else
|
||||
p = (void *)calloc(size,1);
|
||||
#endif
|
||||
|
||||
#ifdef CST_DEBUG_MALLOC
|
||||
#ifdef CST_DEBUG_MALLOC_TRACE
|
||||
if (cst_alloc_num_calls == cst_alloc_ckpt)
|
||||
cst_dbgmsg("cst_malloc: %d\n", cst_alloc_ckpt);
|
||||
cst_alloc_cunks[cst_alloc_num_calls] = p;
|
||||
#endif
|
||||
cst_alloc_num_calls++;
|
||||
*(int *)p = 1314;
|
||||
p = (int *)p + 1;
|
||||
*(int *)p = size - (2 * sizeof(int));
|
||||
if ((cst_allocated - cst_freed) > cst_alloc_max)
|
||||
cst_alloc_max = cst_allocated - cst_freed;
|
||||
p = (int *)p + 1;
|
||||
#endif
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
cst_errmsg("alloc: can't alloc %d bytes\n", size);
|
||||
cst_error();
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *cst_safe_calloc(int size)
|
||||
{
|
||||
return cst_safe_alloc(size);
|
||||
}
|
||||
|
||||
void *cst_safe_realloc(void *p,int size)
|
||||
{
|
||||
void *np=0;
|
||||
|
||||
#ifdef CST_DEBUG_MALLOC
|
||||
cst_free(p);
|
||||
return cst_safe_alloc(size);
|
||||
#endif
|
||||
|
||||
if (size == 0)
|
||||
size++; /* as some mallocs do strange things with 0 */
|
||||
|
||||
if (p == NULL)
|
||||
np = cst_safe_alloc(size);
|
||||
else
|
||||
#ifdef UNDER_CE
|
||||
np = LocalReAlloc((HLOCAL)p, size, LMEM_MOVEABLE|LMEM_ZEROINIT);
|
||||
#else
|
||||
np = realloc(p,size);
|
||||
#endif
|
||||
|
||||
if (np == NULL)
|
||||
{
|
||||
cst_errmsg("CST_REALLOC failed for %d bytes\n",size);
|
||||
cst_error();
|
||||
}
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
void cst_free(void *p)
|
||||
{
|
||||
if (p != NULL)
|
||||
{
|
||||
#ifdef CST_DEBUG_MALLOC
|
||||
if (*((int *)p - 2) != 1314)
|
||||
{
|
||||
cst_dbgmsg("CST_MALLOC_DEBUG freeing non-malloc memory\n");
|
||||
return;
|
||||
}
|
||||
if (*((int *)p - 1) <= 0)
|
||||
{
|
||||
cst_dbgmsg("CST_MALLOC_DEBUG re-freeing memory\n");
|
||||
return;
|
||||
}
|
||||
cst_freed += *((int *)p - 1);
|
||||
cst_alloc_out -= *((int *)p - 1);
|
||||
*((int *)p - 1) = 0; /* mark it as freed */
|
||||
p = (int *)p - 2;
|
||||
#endif
|
||||
#ifndef CST_DEBUG_MALLOC_TRACE
|
||||
#ifdef UNDER_CE
|
||||
if (LocalFree(p) != NULL)
|
||||
{
|
||||
cst_errmsg("LocalFree(%p) failed with code %x\n",
|
||||
p, GetLastError());
|
||||
cst_error();
|
||||
}
|
||||
#else
|
||||
free(p);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CST_DEBUG_MALLOC_TRACE
|
||||
|
||||
void cst_find_unfreed()
|
||||
{
|
||||
int i, t;
|
||||
|
||||
|
||||
for (i = 0, t = 0;
|
||||
i < NUM_CHUNKS
|
||||
&& i < cst_alloc_num_calls
|
||||
&& cst_alloc_cunks[i];
|
||||
i++)
|
||||
{
|
||||
if (((int *)cst_alloc_cunks[i])[1] != 0)
|
||||
{
|
||||
cst_dbgmsg("unfreed at %d\n", i);
|
||||
t++;
|
||||
}
|
||||
}
|
||||
cst_dbgmsg("total unfreed %d\n", t);
|
||||
}
|
||||
|
||||
void cst_alloc_debug_summary()
|
||||
{
|
||||
cst_find_unfreed();
|
||||
printf("allocated %d freed %d max %d imax %d calls %d out %d\n",
|
||||
cst_allocated, cst_freed, cst_alloc_max,
|
||||
cst_alloc_imax, cst_alloc_num_calls, cst_alloc_out);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UNDER_CE
|
||||
cst_alloc_context new_alloc_context(int size)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
h = HeapCreate(0, size, 0);
|
||||
return (cst_alloc_context) h;
|
||||
}
|
||||
|
||||
void delete_alloc_context(cst_alloc_context ctx)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
h = (HANDLE)ctx;
|
||||
HeapDestroy(h);
|
||||
}
|
||||
|
||||
void *cst_local_alloc(cst_alloc_context ctx, int size)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
h = (HANDLE)ctx;
|
||||
if (h)
|
||||
return HeapAlloc(h, HEAP_ZERO_MEMORY, size);
|
||||
else
|
||||
return LocalAlloc(LPTR, size);
|
||||
}
|
||||
|
||||
void cst_local_free(cst_alloc_context ctx, void *p)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
h = (HANDLE)ctx;
|
||||
if (h)
|
||||
HeapFree(h, 0, p);
|
||||
else
|
||||
LocalFree(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Error mechanism */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "cst_file.h"
|
||||
#include "cst_error.h"
|
||||
|
||||
#ifdef UNDER_CE
|
||||
|
||||
#include <winbase.h>
|
||||
#include <stdlib.h>
|
||||
#include "cst_alloc.h"
|
||||
|
||||
int cst_errmsg(const char *fmt, ...)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
wchar_t wmsg[256];
|
||||
wchar_t *wfmt;
|
||||
size_t len;
|
||||
va_list args;
|
||||
|
||||
len = mbstowcs(NULL,fmt,0) + 1;
|
||||
wfmt = cst_alloc(wchar_t,len);
|
||||
mbstowcs(wfmt,fmt,len);
|
||||
|
||||
va_start(args,fmt);
|
||||
_vsnwprintf(wmsg,256,wfmt,args);
|
||||
va_end(args);
|
||||
|
||||
wmsg[255]=L'\0';
|
||||
cst_free(wfmt);
|
||||
MessageBoxW(0,wmsg,L"Error",0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
jmp_buf *cst_errjmp = 0;
|
||||
|
||||
#elif defined(__palmos__)
|
||||
#ifdef __ARM_ARCH_4T__
|
||||
/* We only support throwing errors in ARM land */
|
||||
jmp_buf *cst_errjmp = 0;
|
||||
#endif
|
||||
|
||||
char cst_error_msg[600];
|
||||
int cst_errmsg(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int count;
|
||||
|
||||
va_start(args,fmt);
|
||||
count = cst_vsprintf(cst_error_msg,fmt,args);
|
||||
va_end(args);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
jmp_buf *cst_errjmp = 0;
|
||||
|
||||
int cst_errmsg(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int rv;
|
||||
|
||||
va_start(args, fmt);
|
||||
rv = vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,319 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Feature support */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_error.h"
|
||||
#include "cst_features.h"
|
||||
|
||||
CST_VAL_REGISTER_TYPE(features,cst_features)
|
||||
|
||||
static cst_featvalpair *feat_find_featpair(const cst_features *f,
|
||||
const char *name)
|
||||
{
|
||||
cst_featvalpair *n;
|
||||
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
for (n=f->head; n; n=n->next)
|
||||
if (cst_streq(name,n->name))
|
||||
return n;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cst_features *new_features(void)
|
||||
{
|
||||
cst_features *f;
|
||||
|
||||
f = cst_alloc(cst_features,1);
|
||||
f->head = NULL;
|
||||
f->ctx = NULL;
|
||||
return f;
|
||||
}
|
||||
|
||||
cst_features *new_features_local(cst_alloc_context ctx)
|
||||
{
|
||||
cst_features *f;
|
||||
|
||||
f = (cst_features *)cst_local_alloc(ctx, sizeof(*f));
|
||||
f->head = NULL;
|
||||
f->ctx = ctx;
|
||||
return f;
|
||||
}
|
||||
|
||||
void delete_features(cst_features *f)
|
||||
{
|
||||
cst_featvalpair *n, *np;
|
||||
|
||||
if (f)
|
||||
{
|
||||
for (n=f->head; n; n=np)
|
||||
{
|
||||
np = n->next;
|
||||
delete_val(n->val);
|
||||
cst_local_free(f->ctx,n);
|
||||
}
|
||||
cst_local_free(f->ctx,f);
|
||||
}
|
||||
}
|
||||
|
||||
int feat_present(const cst_features *f, const char *name)
|
||||
{
|
||||
return (feat_find_featpair(f,name) != NULL);
|
||||
}
|
||||
|
||||
int feat_length(const cst_features *f)
|
||||
{
|
||||
int i=0;
|
||||
cst_featvalpair *p;
|
||||
if (f)
|
||||
for (i=0,p=f->head; p; p=p->next)
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int feat_remove(cst_features *f, const char *name)
|
||||
{
|
||||
cst_featvalpair *n,*p,*np;
|
||||
|
||||
if (f == NULL)
|
||||
return FALSE; /* didn't remove it */
|
||||
else
|
||||
{
|
||||
for (p=NULL,n=f->head; n; p=n,n=np)
|
||||
{
|
||||
np = n->next;
|
||||
if (cst_streq(name,n->name))
|
||||
{
|
||||
if (p == 0)
|
||||
f->head = np;
|
||||
else
|
||||
p->next = np;
|
||||
delete_val(n->val);
|
||||
cst_local_free(f->ctx,n);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int feat_int(const cst_features *f, const char *name)
|
||||
{
|
||||
return val_int(feat_val(f,name));
|
||||
}
|
||||
|
||||
float feat_float(const cst_features *f, const char *name)
|
||||
{
|
||||
return val_float(feat_val(f,name));
|
||||
}
|
||||
|
||||
const char *feat_string(const cst_features *f, const char *name)
|
||||
{
|
||||
return val_string(feat_val(f,name));
|
||||
}
|
||||
|
||||
const cst_val *feat_val(const cst_features *f, const char *name)
|
||||
{
|
||||
cst_featvalpair *n;
|
||||
n = feat_find_featpair(f,name);
|
||||
|
||||
if (n == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return n->val;
|
||||
}
|
||||
|
||||
int get_param_int(const cst_features *f, const char *name,int def)
|
||||
{
|
||||
const cst_val *v;
|
||||
|
||||
v = feat_val(f,name);
|
||||
if (v != NULL)
|
||||
return val_int(v);
|
||||
else
|
||||
return def;
|
||||
}
|
||||
|
||||
float get_param_float(const cst_features *f, const char *name, float def)
|
||||
{
|
||||
const cst_val *v;
|
||||
|
||||
v = feat_val(f,name);
|
||||
if (v != NULL)
|
||||
return val_float(v);
|
||||
else
|
||||
return def;
|
||||
}
|
||||
const char *get_param_string(const cst_features *f, const char *name, const char *def)
|
||||
{
|
||||
const cst_val *v;
|
||||
|
||||
v = feat_val(f,name);
|
||||
if (v != NULL)
|
||||
return val_string(v);
|
||||
else
|
||||
return def;
|
||||
}
|
||||
|
||||
const cst_val *get_param_val(const cst_features *f, const char *name, cst_val *def)
|
||||
{
|
||||
const cst_val *v;
|
||||
|
||||
v = feat_val(f,name);
|
||||
if (v != NULL)
|
||||
return v;
|
||||
else
|
||||
return def;
|
||||
}
|
||||
|
||||
void feat_set_int(cst_features *f, const char *name, int v)
|
||||
{
|
||||
feat_set(f,name,int_val(v));
|
||||
}
|
||||
|
||||
void feat_set_float(cst_features *f, const char *name, float v)
|
||||
{
|
||||
feat_set(f,name,float_val(v));
|
||||
}
|
||||
|
||||
void feat_set_string(cst_features *f, const char *name, const char *v)
|
||||
{
|
||||
feat_set(f,name,string_val(v));
|
||||
}
|
||||
|
||||
void feat_set(cst_features *f, const char* name, const cst_val *val)
|
||||
{
|
||||
cst_featvalpair *n;
|
||||
n = feat_find_featpair(f,name);
|
||||
|
||||
if (val == NULL)
|
||||
{
|
||||
cst_errmsg("cst_val: trying to set a NULL val for feature \"%s\"\n",
|
||||
name);
|
||||
}
|
||||
else if (n == NULL)
|
||||
{ /* first reference to this feature so create new fpair */
|
||||
cst_featvalpair *p;
|
||||
p = (cst_featvalpair *)cst_local_alloc(f->ctx, sizeof(*p));
|
||||
p->next = f->head;
|
||||
p->name = name;
|
||||
p->val = val_inc_refcount(val);
|
||||
f->head = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete_val(n->val);
|
||||
n->val = val_inc_refcount(val);
|
||||
}
|
||||
}
|
||||
|
||||
int feat_copy_into(const cst_features *from,cst_features *to)
|
||||
{
|
||||
/* Copy all features in from into to */
|
||||
cst_featvalpair *p;
|
||||
int i;
|
||||
|
||||
for (i=0,p=from->head; p; p=p->next,i++)
|
||||
feat_set(to,p->name,p->val);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
int feat_print(cst_file fd,const cst_features *f)
|
||||
{
|
||||
cst_featvalpair *p;
|
||||
|
||||
for (p=f->head; p; p=p->next)
|
||||
{
|
||||
cst_fprintf(fd, "%s ",p->name);
|
||||
val_print(fd,p->val);
|
||||
cst_fprintf(fd,"\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
@@ -0,0 +1,160 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* String manipulation functions */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "cst_alloc.h"
|
||||
#include "cst_string.h"
|
||||
|
||||
#ifdef UNDER_CE /* WinCE does not fully implement ANSI C */
|
||||
|
||||
cst_string *cst_strrchr(const cst_string *str, int c)
|
||||
{
|
||||
cst_string *p = (const cst_string *)str + cst_strlen(str);
|
||||
while (p >= str) {
|
||||
if (*p == c)
|
||||
return p;
|
||||
--p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
double cst_atof(const char *str)
|
||||
{
|
||||
/* double f = 0.0; */
|
||||
|
||||
/* sscanf(str, "%f", &f); */
|
||||
return atof(str);
|
||||
}
|
||||
|
||||
#else /* Sane operating system */
|
||||
|
||||
cst_string *cst_strrchr(const cst_string *str, int c)
|
||||
{
|
||||
return (cst_string *)strrchr((const char *)str, c);
|
||||
}
|
||||
|
||||
double cst_atof(const char *str)
|
||||
{
|
||||
return atof(str);
|
||||
}
|
||||
#endif /* WinCE */
|
||||
|
||||
cst_string *cst_strdup(const cst_string *str)
|
||||
{
|
||||
cst_string *nstr = NULL;
|
||||
|
||||
if (str)
|
||||
{
|
||||
nstr = cst_alloc(cst_string,cst_strlen((const char *)str)+1);
|
||||
memmove(nstr,str,cst_strlen((const char *)str)+1);
|
||||
}
|
||||
return nstr;
|
||||
}
|
||||
|
||||
cst_string *cst_strchr(const cst_string *s, int c)
|
||||
{
|
||||
return (cst_string *)strchr((const char *)s,c);
|
||||
}
|
||||
|
||||
char *cst_substr(const char *str,int start, int length)
|
||||
{
|
||||
char *nstr = NULL;
|
||||
|
||||
if (str)
|
||||
{
|
||||
nstr = cst_alloc(char,length+1);
|
||||
strncpy(nstr,str+start,length);
|
||||
nstr[length] = '\0';
|
||||
}
|
||||
return nstr;
|
||||
}
|
||||
|
||||
char *cst_string_before(const char *s,const char *c)
|
||||
{
|
||||
char *p;
|
||||
char *q;
|
||||
|
||||
p = (char *)cst_strstr(s,c);
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
q = (char *)cst_strdup((cst_string *)s);
|
||||
q[cst_strlen(s)-cst_strlen(p)] = '\0';
|
||||
return q;
|
||||
}
|
||||
|
||||
cst_string *cst_downcase(const cst_string *str)
|
||||
{
|
||||
cst_string *dc;
|
||||
int i;
|
||||
|
||||
dc = cst_strdup(str);
|
||||
for (i=0; str[i] != '\0'; i++)
|
||||
{
|
||||
if (isupper((int)str[i]))
|
||||
dc[i] = tolower((int)str[i]);
|
||||
}
|
||||
return dc;
|
||||
}
|
||||
|
||||
cst_string *cst_upcase(const cst_string *str)
|
||||
{
|
||||
cst_string *uc;
|
||||
int i;
|
||||
|
||||
uc = cst_strdup(str);
|
||||
for (i=0; str[i] != '\0'; i++)
|
||||
{
|
||||
if (islower((int)str[i]))
|
||||
uc[i] = toupper((int)str[i]);
|
||||
}
|
||||
return uc;
|
||||
}
|
||||
|
||||
int cst_member_string(const char *str, const char * const *slist)
|
||||
{
|
||||
const char * const *p;
|
||||
|
||||
for (p = slist; *p; ++p)
|
||||
if (cst_streq(*p, str))
|
||||
break;
|
||||
|
||||
return *p != NULL;
|
||||
}
|
||||
@@ -0,0 +1,508 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: July 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Tokenizer for strings and files */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_tokenstream.h"
|
||||
|
||||
const cst_string * const cst_ts_default_whitespacesymbols = " \t\n\r";
|
||||
const cst_string * const cst_ts_default_singlecharsymbols = "(){}[]";
|
||||
const cst_string * const cst_ts_default_prepunctuationsymbols = "\"'`({[";
|
||||
const cst_string * const cst_ts_default_postpunctuationsymbols = "\"'`.,:;!?(){}[]";
|
||||
|
||||
#define TS_BUFFER_SIZE 256
|
||||
#define TS_EOF -1
|
||||
|
||||
static cst_string ts_getc(cst_tokenstream *ts);
|
||||
|
||||
static void set_charclass_table(cst_tokenstream *ts)
|
||||
{
|
||||
int i;
|
||||
memset(ts->charclass,0,256); /* zero everything */
|
||||
|
||||
for (i=0; ts->p_whitespacesymbols[i]; i++)
|
||||
ts->charclass[(unsigned char)ts->p_whitespacesymbols[i]] |= TS_CHARCLASS_WHITESPACE;
|
||||
for (i=0; ts->p_singlecharsymbols[i]; i++)
|
||||
ts->charclass[(unsigned char)ts->p_singlecharsymbols[i]] |= TS_CHARCLASS_SINGLECHAR;
|
||||
for (i=0; ts->p_prepunctuationsymbols[i]; i++)
|
||||
ts->charclass[(unsigned char)ts->p_prepunctuationsymbols[i]] |= TS_CHARCLASS_PREPUNCT;
|
||||
for (i=0; ts->p_postpunctuationsymbols[i]; i++)
|
||||
ts->charclass[(unsigned char)ts->p_postpunctuationsymbols[i]]|=TS_CHARCLASS_POSTPUNCT;
|
||||
return;
|
||||
}
|
||||
|
||||
void set_charclasses(cst_tokenstream *ts,
|
||||
const cst_string *whitespace,
|
||||
const cst_string *singlecharsymbols,
|
||||
const cst_string *prepunctuation,
|
||||
const cst_string *postpunctuation)
|
||||
{
|
||||
ts->p_whitespacesymbols =
|
||||
(whitespace ? whitespace : cst_ts_default_whitespacesymbols);
|
||||
ts->p_singlecharsymbols =
|
||||
(singlecharsymbols ? singlecharsymbols : cst_ts_default_singlecharsymbols);
|
||||
ts->p_prepunctuationsymbols =
|
||||
(prepunctuation ? prepunctuation : cst_ts_default_prepunctuationsymbols);
|
||||
ts->p_postpunctuationsymbols =
|
||||
(postpunctuation ? postpunctuation : cst_ts_default_postpunctuationsymbols);
|
||||
|
||||
set_charclass_table(ts);
|
||||
return;
|
||||
}
|
||||
|
||||
static void extend_buffer(cst_string **buffer,int *buffer_max)
|
||||
{
|
||||
int new_max;
|
||||
cst_string *new_buffer;
|
||||
|
||||
new_max = (*buffer_max)+(*buffer_max)/5;
|
||||
new_buffer = cst_alloc(cst_string,new_max);
|
||||
memmove(new_buffer,*buffer,*buffer_max);
|
||||
cst_free(*buffer);
|
||||
*buffer = new_buffer;
|
||||
*buffer_max = new_max;
|
||||
}
|
||||
|
||||
static cst_tokenstream *new_tokenstream(const cst_string *whitespace,
|
||||
const cst_string *singlechars,
|
||||
const cst_string *prepunct,
|
||||
const cst_string *postpunct)
|
||||
{ /* Constructor function */
|
||||
cst_tokenstream *ts = cst_alloc(cst_tokenstream,1);
|
||||
ts->fd = NULL;
|
||||
ts->file_pos = 0;
|
||||
ts->line_number = 0;
|
||||
ts->string_buffer = NULL;
|
||||
ts->token_pos = 0;
|
||||
ts->whitespace = cst_alloc(cst_string,TS_BUFFER_SIZE);
|
||||
ts->ws_max = TS_BUFFER_SIZE;
|
||||
if (prepunct && prepunct[0])
|
||||
{
|
||||
ts->prepunctuation = cst_alloc(cst_string,TS_BUFFER_SIZE);
|
||||
ts->prep_max = TS_BUFFER_SIZE;
|
||||
}
|
||||
ts->token = cst_alloc(cst_string,TS_BUFFER_SIZE);
|
||||
ts->token_max = TS_BUFFER_SIZE;
|
||||
if (postpunct && postpunct[0])
|
||||
{
|
||||
ts->postpunctuation = cst_alloc(cst_string,TS_BUFFER_SIZE);
|
||||
ts->postp_max = TS_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
set_charclasses(ts,whitespace,singlechars,prepunct,postpunct);
|
||||
ts->current_char = 0;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
void delete_tokenstream(cst_tokenstream *ts)
|
||||
{
|
||||
cst_free(ts->whitespace);
|
||||
cst_free(ts->token);
|
||||
if (ts->prepunctuation) cst_free(ts->prepunctuation);
|
||||
if (ts->postpunctuation) cst_free(ts->postpunctuation);
|
||||
cst_free(ts);
|
||||
}
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
cst_tokenstream *ts_open(const char *filename,
|
||||
const cst_string *whitespace,
|
||||
const cst_string *singlechars,
|
||||
const cst_string *prepunct,
|
||||
const cst_string *postpunct)
|
||||
{
|
||||
cst_tokenstream *ts = new_tokenstream(whitespace,
|
||||
singlechars,
|
||||
prepunct,
|
||||
postpunct);
|
||||
|
||||
#ifndef UNDER_CE
|
||||
if (cst_streq("-",filename))
|
||||
ts->fd = stdin;
|
||||
else
|
||||
#endif
|
||||
ts->fd = cst_fopen(filename,CST_OPEN_READ|CST_OPEN_BINARY);
|
||||
ts_getc(ts);
|
||||
|
||||
if (ts->fd == NULL)
|
||||
{
|
||||
delete_tokenstream(ts);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return ts;
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE*/
|
||||
|
||||
cst_tokenstream *ts_open_string(const cst_string *string,
|
||||
const cst_string *whitespace,
|
||||
const cst_string *singlechars,
|
||||
const cst_string *prepunct,
|
||||
const cst_string *postpunct)
|
||||
{
|
||||
cst_tokenstream *ts = new_tokenstream(whitespace,
|
||||
singlechars,
|
||||
prepunct,
|
||||
postpunct);
|
||||
|
||||
ts->string_buffer = cst_strdup(string);
|
||||
ts_getc(ts);
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
void ts_close(cst_tokenstream *ts)
|
||||
{
|
||||
if (ts->fd != NULL)
|
||||
{
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
#ifndef UNDER_CE
|
||||
if (ts->fd != stdin)
|
||||
#endif
|
||||
cst_fclose(ts->fd);
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
ts->fd = NULL; /* just in case close gets called twice */
|
||||
}
|
||||
if (ts->string_buffer != NULL)
|
||||
{
|
||||
cst_free(ts->string_buffer);
|
||||
ts->string_buffer = NULL;
|
||||
}
|
||||
delete_tokenstream(ts);
|
||||
}
|
||||
|
||||
static void get_token_sub_part(cst_tokenstream *ts,
|
||||
int charclass,
|
||||
cst_string **buffer,
|
||||
int *buffer_max)
|
||||
{
|
||||
int p;
|
||||
|
||||
for (p=0; ((ts->current_char != TS_EOF) &&
|
||||
(ts_charclass(ts->current_char,charclass,ts)) &&
|
||||
(!ts_charclass(ts->current_char,
|
||||
TS_CHARCLASS_SINGLECHAR,ts))); p++)
|
||||
{
|
||||
if (p >= *buffer_max) extend_buffer(buffer,buffer_max);
|
||||
(*buffer)[p] = ts->current_char;
|
||||
ts_getc(ts);
|
||||
}
|
||||
(*buffer)[p] = '\0';
|
||||
}
|
||||
|
||||
/* Can't afford dynamically generate this char class so have separater func */
|
||||
static void get_token_sub_part_2(cst_tokenstream *ts,
|
||||
int endclass1,
|
||||
cst_string **buffer,
|
||||
int *buffer_max)
|
||||
{
|
||||
int p;
|
||||
|
||||
for (p=0; ((ts->current_char != TS_EOF) &&
|
||||
(!ts_charclass(ts->current_char,endclass1,ts)) &&
|
||||
(!ts_charclass(ts->current_char,
|
||||
TS_CHARCLASS_SINGLECHAR,ts)));
|
||||
p++)
|
||||
{
|
||||
if (p >= *buffer_max) extend_buffer(buffer,buffer_max);
|
||||
(*buffer)[p] = ts->current_char;
|
||||
ts_getc(ts);
|
||||
}
|
||||
(*buffer)[p] = '\0';
|
||||
}
|
||||
|
||||
static void get_token_postpunctuation(cst_tokenstream *ts)
|
||||
{
|
||||
int p,t;
|
||||
|
||||
t = cst_strlen(ts->token);
|
||||
for (p=t;
|
||||
(p > 0) &&
|
||||
((ts->token[p] == '\0') ||
|
||||
(ts_charclass(ts->token[p],TS_CHARCLASS_POSTPUNCT,ts)));
|
||||
p--);
|
||||
|
||||
if (t != p)
|
||||
{
|
||||
if (t-p >= ts->postp_max)
|
||||
extend_buffer(&ts->postpunctuation,&ts->postp_max);
|
||||
/* Copy postpunctuation from token */
|
||||
memmove(ts->postpunctuation,&ts->token[p+1],(t-p));
|
||||
/* truncate token at postpunctuation */
|
||||
ts->token[p+1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
int ts_eof(cst_tokenstream *ts)
|
||||
{
|
||||
if (ts->current_char == TS_EOF)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int ts_set_stream_pos(cst_tokenstream *ts, int pos)
|
||||
{
|
||||
/* Note this doesn't preserve line_pos */
|
||||
int new_pos, l;
|
||||
|
||||
if (ts->fd)
|
||||
#ifdef FLITE_PLUS_HTS_ENGINE
|
||||
new_pos = pos < 0 ? 0 : pos;
|
||||
#else
|
||||
new_pos = (int)cst_fseek(ts->fd, (long)pos, CST_SEEK_ABSOLUTE);
|
||||
#endif
|
||||
else if (ts->string_buffer)
|
||||
{
|
||||
l = cst_strlen(ts->string_buffer);
|
||||
if (pos > l)
|
||||
new_pos = l;
|
||||
else if (pos < 0)
|
||||
new_pos = 0;
|
||||
else
|
||||
new_pos = pos;
|
||||
}
|
||||
else
|
||||
new_pos = pos; /* not sure it can get here */
|
||||
|
||||
ts->file_pos = new_pos;
|
||||
ts->current_char = ' '; /* To be safe */
|
||||
|
||||
return ts->file_pos;
|
||||
}
|
||||
|
||||
int ts_get_stream_pos(cst_tokenstream *ts)
|
||||
{
|
||||
return ts->file_pos;
|
||||
}
|
||||
|
||||
static cst_string ts_getc(cst_tokenstream *ts)
|
||||
{
|
||||
if (ts->fd)
|
||||
{
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
ts->current_char = cst_fgetc(ts->fd);
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
}
|
||||
else if (ts->string_buffer)
|
||||
{
|
||||
if (ts->string_buffer[ts->file_pos] == '\0')
|
||||
ts->current_char = TS_EOF;
|
||||
else
|
||||
ts->current_char = ts->string_buffer[ts->file_pos];
|
||||
}
|
||||
|
||||
if (ts->current_char != TS_EOF)
|
||||
ts->file_pos++;
|
||||
if (ts->current_char == '\n')
|
||||
ts->line_number++;
|
||||
return ts->current_char;
|
||||
}
|
||||
|
||||
const cst_string *ts_get_quoted_token(cst_tokenstream *ts,
|
||||
char quote,
|
||||
char escape)
|
||||
{
|
||||
/* for reading the next quoted token that starts with quote and
|
||||
ends with quote, quote may appear only if preceded by escape */
|
||||
int p;
|
||||
|
||||
/* Hmm can't change quotes within a ts */
|
||||
ts->charclass[(unsigned int)quote] |= TS_CHARCLASS_QUOTE;
|
||||
ts->charclass[(unsigned int)escape] |= TS_CHARCLASS_QUOTE;
|
||||
|
||||
/* skipping whitespace */
|
||||
get_token_sub_part(ts,TS_CHARCLASS_WHITESPACE,
|
||||
&ts->whitespace,
|
||||
&ts->ws_max);
|
||||
ts->token_pos = ts->file_pos - 1;
|
||||
|
||||
if (ts->current_char == quote)
|
||||
{ /* go until quote */
|
||||
ts_getc(ts);
|
||||
|
||||
for (p=0; ((ts->current_char != TS_EOF) &&
|
||||
(ts->current_char != quote));
|
||||
p++)
|
||||
{
|
||||
if (p >= ts->token_max)
|
||||
extend_buffer(&ts->token,&ts->token_max);
|
||||
ts->token[p] = ts->current_char;
|
||||
ts_getc(ts);
|
||||
if (ts->current_char == escape)
|
||||
{
|
||||
ts_get(ts);
|
||||
if (p >= ts->token_max)
|
||||
extend_buffer(&ts->token,&ts->token_max);
|
||||
ts->token[p] = ts->current_char;
|
||||
ts_get(ts);
|
||||
}
|
||||
}
|
||||
ts->token[p] = '\0';
|
||||
ts_getc(ts);
|
||||
}
|
||||
else /* its not quotes, like to be careful dont you */
|
||||
{ /* treat is as standard token */
|
||||
/* Get prepunctuation */
|
||||
get_token_sub_part(ts,TS_CHARCLASS_PREPUNCT,
|
||||
&ts->prepunctuation,
|
||||
&ts->prep_max);
|
||||
/* Get the symbol itself */
|
||||
if (!ts_charclass(ts->current_char,TS_CHARCLASS_SINGLECHAR,ts))
|
||||
{
|
||||
if (2 >= ts->token_max) extend_buffer(&ts->token,&ts->token_max);
|
||||
ts->token[0] = ts->current_char;
|
||||
ts->token[1] = '\0';
|
||||
ts_getc(ts);
|
||||
}
|
||||
else
|
||||
get_token_sub_part_2(ts,
|
||||
TS_CHARCLASS_WHITESPACE, /* end class1 */
|
||||
&ts->token,
|
||||
&ts->token_max);
|
||||
/* This'll have token *plus* post punctuation in ts->token */
|
||||
/* Get postpunctuation */
|
||||
get_token_postpunctuation(ts);
|
||||
}
|
||||
|
||||
return ts->token;
|
||||
}
|
||||
|
||||
const cst_string *ts_get(cst_tokenstream *ts)
|
||||
{
|
||||
/* Get next token */
|
||||
|
||||
/* Skip whitespace */
|
||||
get_token_sub_part(ts,
|
||||
TS_CHARCLASS_WHITESPACE,
|
||||
&ts->whitespace,
|
||||
&ts->ws_max);
|
||||
|
||||
/* quoted strings currently ignored */
|
||||
ts->token_pos = ts->file_pos - 1;
|
||||
|
||||
/* Get prepunctuation */
|
||||
if (ts->current_char != TS_EOF &&
|
||||
ts_charclass(ts->current_char,TS_CHARCLASS_PREPUNCT,ts))
|
||||
get_token_sub_part(ts,
|
||||
TS_CHARCLASS_PREPUNCT,
|
||||
&ts->prepunctuation,
|
||||
&ts->prep_max);
|
||||
else if (ts->prepunctuation)
|
||||
ts->prepunctuation[0] = '\0';
|
||||
/* Get the symbol itself */
|
||||
if (ts->current_char != TS_EOF &&
|
||||
ts_charclass(ts->current_char,TS_CHARCLASS_SINGLECHAR,ts))
|
||||
{
|
||||
if (2 >= ts->token_max) extend_buffer(&ts->token,&ts->token_max);
|
||||
ts->token[0] = ts->current_char;
|
||||
ts->token[1] = '\0';
|
||||
ts_getc(ts);
|
||||
}
|
||||
else
|
||||
get_token_sub_part_2(ts,
|
||||
TS_CHARCLASS_WHITESPACE, /* end class1 */
|
||||
&ts->token,
|
||||
&ts->token_max);
|
||||
/* This'll have token *plus* post punctuation in ts->token */
|
||||
/* Get postpunctuation */
|
||||
if (ts->p_postpunctuationsymbols[0])
|
||||
get_token_postpunctuation(ts);
|
||||
|
||||
return ts->token;
|
||||
}
|
||||
|
||||
int ts_read(void *buff, int size, int num, cst_tokenstream *ts)
|
||||
{
|
||||
/* people should complain about the speed here */
|
||||
/* people will complain about EOF as end of file */
|
||||
int i,j,p;
|
||||
cst_string *cbuff;
|
||||
|
||||
cbuff = (cst_string *)buff;
|
||||
|
||||
for (p=i=0; i < num; i++)
|
||||
for (j=0; j < size; j++,p++)
|
||||
cbuff[p] = ts_getc(ts);
|
||||
|
||||
return i;
|
||||
}
|
||||
+594
@@ -0,0 +1,594 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Language Technologies Institute */
|
||||
/* Carnegie Mellon University */
|
||||
/* Copyright (c) 1999 */
|
||||
/* 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: December 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Typed values */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_math.h"
|
||||
#include "cst_file.h"
|
||||
#include "cst_val.h"
|
||||
#include "cst_string.h"
|
||||
|
||||
static cst_val *new_val()
|
||||
{
|
||||
return cst_alloc(struct cst_val_struct,1);
|
||||
}
|
||||
|
||||
cst_val *int_val(int i)
|
||||
{
|
||||
cst_val *v = new_val();
|
||||
CST_VAL_TYPE(v) = CST_VAL_TYPE_INT;
|
||||
CST_VAL_INT(v) = i;
|
||||
return v;
|
||||
}
|
||||
|
||||
cst_val *float_val(float f)
|
||||
{
|
||||
cst_val *v = new_val();
|
||||
CST_VAL_TYPE(v) = CST_VAL_TYPE_FLOAT;
|
||||
CST_VAL_FLOAT(v) = f;
|
||||
return v;
|
||||
}
|
||||
|
||||
cst_val *string_val(const char *s)
|
||||
{
|
||||
cst_val *v = new_val();
|
||||
CST_VAL_TYPE(v) = CST_VAL_TYPE_STRING;
|
||||
/* would be nice to note if this is a deletable string or not */
|
||||
CST_VAL_STRING_LVAL(v) = cst_strdup(s);
|
||||
return v;
|
||||
}
|
||||
|
||||
cst_val *cons_val(const cst_val *a, const cst_val *b)
|
||||
{
|
||||
cst_val *v = new_val();
|
||||
CST_VAL_CAR(v)=((!a || cst_val_consp(a)) ?
|
||||
(cst_val *)(void *)a:val_inc_refcount(a));
|
||||
CST_VAL_CDR(v)=((!b || cst_val_consp(b)) ?
|
||||
(cst_val *)(void *)b:val_inc_refcount(b));
|
||||
return v;
|
||||
}
|
||||
|
||||
cst_val *val_new_typed(int type,void *vv)
|
||||
{
|
||||
cst_val *v = new_val();
|
||||
CST_VAL_TYPE(v) = type;
|
||||
CST_VAL_VOID(v) = vv;
|
||||
return v;
|
||||
}
|
||||
|
||||
void delete_val_list(cst_val *v)
|
||||
{
|
||||
if (v)
|
||||
{
|
||||
if (cst_val_consp(v))
|
||||
{
|
||||
delete_val_list(CST_VAL_CDR(v));
|
||||
cst_free(v);
|
||||
}
|
||||
else
|
||||
delete_val(v);
|
||||
}
|
||||
}
|
||||
|
||||
void delete_val(cst_val *v)
|
||||
{
|
||||
if (v)
|
||||
{
|
||||
if (cst_val_consp(v))
|
||||
{
|
||||
delete_val(CST_VAL_CAR(v));
|
||||
delete_val(CST_VAL_CDR(v));
|
||||
cst_free(v);
|
||||
}
|
||||
else if (val_dec_refcount(v) == 0)
|
||||
{
|
||||
if (CST_VAL_TYPE(v) == CST_VAL_TYPE_STRING)
|
||||
cst_free(CST_VAL_VOID(v));
|
||||
else if (CST_VAL_TYPE(v) >= CST_VAL_TYPE_FIRST_FREE)
|
||||
{
|
||||
if (cst_val_defs[CST_VAL_TYPE(v)/2].delete_function)
|
||||
(cst_val_defs[CST_VAL_TYPE(v)/2].delete_function)
|
||||
(CST_VAL_VOID(v));
|
||||
}
|
||||
cst_free(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Accessor functions */
|
||||
int val_int(const cst_val *v)
|
||||
{
|
||||
if (v && (CST_VAL_TYPE(v) == CST_VAL_TYPE_INT))
|
||||
return CST_VAL_INT(v);
|
||||
else if (v && (CST_VAL_TYPE(v) == CST_VAL_TYPE_FLOAT))
|
||||
return (int)CST_VAL_FLOAT(v);
|
||||
else if (v && (CST_VAL_TYPE(v) == CST_VAL_TYPE_STRING))
|
||||
return atoi(CST_VAL_STRING(v));
|
||||
else
|
||||
{
|
||||
cst_errmsg("VAL: tried to access int in %d typed val\n",
|
||||
(v ? CST_VAL_TYPE(v) : -1));
|
||||
cst_error();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
float val_float(const cst_val *v)
|
||||
{
|
||||
if (v && (CST_VAL_TYPE(v) == CST_VAL_TYPE_INT))
|
||||
return (float)CST_VAL_INT(v);
|
||||
else if (v && (CST_VAL_TYPE(v) == CST_VAL_TYPE_FLOAT))
|
||||
return CST_VAL_FLOAT(v);
|
||||
else if (v && (CST_VAL_TYPE(v) == CST_VAL_TYPE_STRING))
|
||||
return cst_atof(CST_VAL_STRING(v));
|
||||
else
|
||||
{
|
||||
cst_errmsg("VAL: tried to access float in %d typed val\n",
|
||||
(v ? CST_VAL_TYPE(v) : -1));
|
||||
cst_error();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *val_string(const cst_val *v)
|
||||
{
|
||||
if (v && (CST_VAL_TYPE(v) == CST_VAL_TYPE_STRING))
|
||||
return CST_VAL_STRING(v);
|
||||
else
|
||||
{
|
||||
cst_errmsg("VAL: tried to access string in %d typed val\n",
|
||||
(v ? CST_VAL_TYPE(v) : -1));
|
||||
cst_error();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const cst_val *val_car(const cst_val *v)
|
||||
{
|
||||
if (v && cst_val_consp(v))
|
||||
return CST_VAL_CAR(v);
|
||||
else
|
||||
{
|
||||
cst_errmsg("VAL: tried to access car in %d typed val\n",
|
||||
(v ? CST_VAL_TYPE(v) : -1));
|
||||
cst_error();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const cst_val *val_cdr(const cst_val *v)
|
||||
{
|
||||
if (v && cst_val_consp(v))
|
||||
return CST_VAL_CDR(v);
|
||||
else
|
||||
{
|
||||
cst_errmsg("VAL: tried to access cdr in %d typed val\n",
|
||||
(v ? CST_VAL_TYPE(v) : -1));
|
||||
cst_error();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *val_generic(const cst_val *v, int type, const char *stype)
|
||||
{ /* a generic access function that checks the expected type */
|
||||
if (v && CST_VAL_TYPE(v) == type)
|
||||
return CST_VAL_VOID(v);
|
||||
else
|
||||
{
|
||||
cst_errmsg("VAL: tried to access %s in %d type val\n",
|
||||
stype,
|
||||
(v ? CST_VAL_TYPE(v) : -1));
|
||||
cst_error();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *val_void(const cst_val *v)
|
||||
{
|
||||
/* The scary, do anything function, this shouldn't be called by mortals */
|
||||
if ((v == NULL) ||
|
||||
(CST_VAL_TYPE(v) == CST_VAL_TYPE_CONS) ||
|
||||
(CST_VAL_TYPE(v) == CST_VAL_TYPE_INT) ||
|
||||
(CST_VAL_TYPE(v) == CST_VAL_TYPE_FLOAT))
|
||||
{
|
||||
cst_errmsg("VAL: tried to access void in %d typed val\n",
|
||||
(v ? CST_VAL_TYPE(v) : -1));
|
||||
cst_error();
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return CST_VAL_VOID(v);
|
||||
}
|
||||
|
||||
int cst_val_consp(const cst_val *v)
|
||||
{
|
||||
/* To keep a val cell down to 8 bytes we identify non-cons cells */
|
||||
/* with non-zero values in the least significant bit of the first */
|
||||
/* address in the cell (this is a standard technique used on Lisp */
|
||||
/* machines */
|
||||
#if 0
|
||||
void *t;
|
||||
int t1;
|
||||
|
||||
/* Hmm this still isn't right (it can be) but this isn't it */
|
||||
t = CST_VAL_CAR(v);
|
||||
t1 = *(int *)&t;
|
||||
|
||||
if ((t1&0x1) == 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
#endif
|
||||
const cst_val_atom *t;
|
||||
|
||||
t = (const cst_val_atom *)v;
|
||||
if (t->type % 2 == 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const cst_val *set_cdr(cst_val *v1, const cst_val *v2)
|
||||
{
|
||||
/* destructive set cdr, be careful you have a pointer to current cdr */
|
||||
|
||||
if (!cst_val_consp(v1))
|
||||
{
|
||||
cst_errmsg("VAL: tried to set cdr of non-consp cell\n");
|
||||
cst_error();
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
val_dec_refcount(CST_VAL_CDR(v1));
|
||||
val_inc_refcount(v1);
|
||||
CST_VAL_CDR(v1) = (cst_val *)v2;
|
||||
}
|
||||
return v1;
|
||||
}
|
||||
|
||||
const cst_val *set_car(cst_val *v1, const cst_val *v2)
|
||||
{
|
||||
/* destructive set car, be careful you have a pointer to current cdr */
|
||||
|
||||
if (!cst_val_consp(v1))
|
||||
{
|
||||
cst_errmsg("VAL: tried to set car of non-consp cell\n");
|
||||
cst_error();
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
val_dec_refcount(CST_VAL_CAR(v1));
|
||||
val_inc_refcount(v1);
|
||||
CST_VAL_CAR(v1) = (cst_val *)v2;
|
||||
}
|
||||
return v1;
|
||||
}
|
||||
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
void val_print(cst_file fd,const cst_val *v)
|
||||
{
|
||||
const cst_val *p;
|
||||
|
||||
if (v == NULL)
|
||||
cst_fprintf(fd,"[null]");
|
||||
else if (CST_VAL_TYPE(v) == CST_VAL_TYPE_INT)
|
||||
cst_fprintf(fd,"%d",val_int(v));
|
||||
else if (CST_VAL_TYPE(v) == CST_VAL_TYPE_FLOAT)
|
||||
cst_fprintf(fd,"%f",val_float(v));
|
||||
else if (CST_VAL_TYPE(v) == CST_VAL_TYPE_STRING)
|
||||
cst_fprintf(fd,"%s",val_string(v));
|
||||
else if (cst_val_consp(v))
|
||||
{
|
||||
cst_fprintf(fd,"(");
|
||||
for (p=v; p; )
|
||||
{
|
||||
val_print(fd,val_car(p));
|
||||
p=val_cdr(p);
|
||||
if (p)
|
||||
cst_fprintf(fd," ");
|
||||
}
|
||||
cst_fprintf(fd,")");
|
||||
}
|
||||
else
|
||||
cst_fprintf(fd,"[Val %s 0x%p]",
|
||||
cst_val_defs[CST_VAL_TYPE(v)/2].name,CST_VAL_VOID(v));
|
||||
}
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
|
||||
cst_val *val_reverse(cst_val *l)
|
||||
{
|
||||
cst_val *n,*np,*nl;
|
||||
for (nl=0,n=l; n; nl=n,n=np)
|
||||
{
|
||||
np=CST_VAL_CDR(n);
|
||||
CST_VAL_CDR(n) = nl;
|
||||
}
|
||||
return nl;
|
||||
}
|
||||
|
||||
cst_val *val_append(cst_val *l1, cst_val *l2)
|
||||
{
|
||||
/* Destructively add l2 to the end of l1 return l1 */
|
||||
cst_val *t;
|
||||
|
||||
if (l1 == 0)
|
||||
return l2;
|
||||
else
|
||||
{
|
||||
for (t=l1; val_cdr(t); t=CST_VAL_CDR(t));
|
||||
CST_VAL_CDR(t) = l2;
|
||||
return l1;
|
||||
}
|
||||
}
|
||||
|
||||
int val_length(const cst_val *l)
|
||||
{
|
||||
const cst_val *n;
|
||||
int i;
|
||||
|
||||
for (i=0,n=l; n; n=val_cdr(n))
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int val_equal(const cst_val *v1, const cst_val *v2)
|
||||
{
|
||||
if (v1 == v2)
|
||||
return TRUE; /* its eq so its equal */
|
||||
else if (v1 == 0)
|
||||
return FALSE;
|
||||
else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE(v2))
|
||||
{
|
||||
if (cst_val_consp(v1))
|
||||
return ((val_equal(val_car(v1),val_car(v2))) &&
|
||||
(val_equal(val_cdr(v1),val_cdr(v2))));
|
||||
else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE_INT)
|
||||
return (val_int(v1) == val_int(v2));
|
||||
else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE_FLOAT)
|
||||
return (val_float(v1) == val_float(v2));
|
||||
else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE_STRING)
|
||||
return (cst_streq(CST_VAL_STRING(v1),CST_VAL_STRING(v2)));
|
||||
else
|
||||
return CST_VAL_VOID(v1) == CST_VAL_VOID(v2);
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int val_less(const cst_val *v1, const cst_val *v2)
|
||||
{
|
||||
return val_float(v1) < val_float(v2);
|
||||
}
|
||||
|
||||
int val_greater(const cst_val *v1,const cst_val *v2)
|
||||
{
|
||||
return val_float(v1) > val_float(v2);
|
||||
}
|
||||
|
||||
int val_member(const cst_val *v1,const cst_val *l)
|
||||
{
|
||||
const cst_val *i;
|
||||
|
||||
for (i=l; i; i=val_cdr(i))
|
||||
{
|
||||
if (val_equal(val_car(i),v1))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int val_member_string(const char *v1,const cst_val *l)
|
||||
{
|
||||
const cst_val *i;
|
||||
|
||||
for (i=l; i; i=val_cdr(i))
|
||||
{
|
||||
if (cst_streq(v1,val_string(val_car(i))))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cst_val *val_inc_refcount(const cst_val *b)
|
||||
{
|
||||
cst_val *wb;
|
||||
|
||||
/* Well I was lying, they're not really const, but this is the place */
|
||||
/* where breaking const is reasonable */
|
||||
wb = (cst_val *)(void *)b;
|
||||
|
||||
if (CST_VAL_REFCOUNT(wb) == -1)
|
||||
/* or is a cons cell in the text segment, how do I do that ? */
|
||||
return wb;
|
||||
else if (!cst_val_consp(wb)) /* we don't ref count cons cells */
|
||||
CST_VAL_REFCOUNT(wb) += 1;
|
||||
return wb;
|
||||
}
|
||||
|
||||
int val_dec_refcount(const cst_val *b)
|
||||
{
|
||||
cst_val *wb;
|
||||
|
||||
wb = (cst_val *)(void *)b;
|
||||
|
||||
if (CST_VAL_REFCOUNT(wb) == -1)
|
||||
/* or is a cons cell in the text segment, how do I do that ? */
|
||||
return -1;
|
||||
else if (cst_val_consp(wb)) /* we don't ref count cons cells */
|
||||
return 0;
|
||||
else if (CST_VAL_REFCOUNT(wb) == 0)
|
||||
{
|
||||
/* Otherwise, trying to free a val outside an
|
||||
item/relation/etc has rather the opposite effect from what
|
||||
you might have intended... */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CST_VAL_REFCOUNT(wb) -= 1;
|
||||
return CST_VAL_REFCOUNT(wb);
|
||||
}
|
||||
}
|
||||
|
||||
cst_val *cst_utf8_explode(const cst_string *utf8string)
|
||||
{
|
||||
/* return a list of utf-8 characters as strings */
|
||||
const unsigned char *xxx = (const unsigned char *)utf8string;
|
||||
cst_val *chars = NULL;
|
||||
char utf8char[5];
|
||||
|
||||
for (int i=0; xxx[i]; i++)
|
||||
{
|
||||
if (xxx[i] < 0x80) /* one byte */
|
||||
{
|
||||
sprintf(utf8char, "%c", xxx[i]);
|
||||
}
|
||||
else if (xxx[i] < 0xe0) /* two bytes */
|
||||
{
|
||||
sprintf(utf8char, "%c%c", xxx[i], xxx[i+1]);
|
||||
i++;
|
||||
}
|
||||
else if (xxx[i] < 0xff) /* three bytes */
|
||||
{
|
||||
sprintf(utf8char, "%c%c%c", xxx[i], xxx[i+1], xxx[i+2]);
|
||||
i++; i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(utf8char, "%c%c%c%c", xxx[i], xxx[i+1], xxx[i+2], xxx[i+3]);
|
||||
i++; i++; i++;
|
||||
}
|
||||
|
||||
chars = cons_val(string_val(utf8char), chars);
|
||||
}
|
||||
|
||||
return val_reverse(chars);
|
||||
}
|
||||
|
||||
int val_stringp(const cst_val *v)
|
||||
{
|
||||
if (cst_val_consp(v))
|
||||
return FALSE;
|
||||
else if (CST_VAL_TYPE(v) == CST_VAL_TYPE_STRING)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const cst_val *val_assoc_string(const char *v1,const cst_val *al)
|
||||
{
|
||||
const cst_val *i;
|
||||
|
||||
for (i=al; i; i=val_cdr(i))
|
||||
{
|
||||
if (cst_streq(v1,val_string(val_car(val_car(i)))))
|
||||
return val_car(i);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cst_string *cst_implode(const cst_val *sl)
|
||||
{
|
||||
const cst_val *v;
|
||||
int l=0;
|
||||
char *s;
|
||||
|
||||
for (v=sl; v; v=val_cdr(v))
|
||||
{
|
||||
if (val_stringp(val_car(v)))
|
||||
l += cst_strlen(val_string(val_car(v)));
|
||||
}
|
||||
|
||||
s = cst_alloc(cst_string,l+1);
|
||||
|
||||
for (v=sl; v; v=val_cdr(v))
|
||||
{
|
||||
if (val_stringp(val_car(v)))
|
||||
cst_sprintf(s,"%s%s",s,val_string(val_car(v)));
|
||||
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Without a real garbage collector we need some basic constant val */
|
||||
/* to avoid having to create them on the fly */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
#include "cst_val.h"
|
||||
#include "cst_features.h"
|
||||
#include "cst_string.h"
|
||||
|
||||
DEF_CONST_VAL_STRING(val_string_0,"0");
|
||||
DEF_CONST_VAL_STRING(val_string_1,"1");
|
||||
DEF_CONST_VAL_STRING(val_string_2,"2");
|
||||
DEF_CONST_VAL_STRING(val_string_3,"3");
|
||||
DEF_CONST_VAL_STRING(val_string_4,"4");
|
||||
DEF_CONST_VAL_STRING(val_string_5,"5");
|
||||
DEF_CONST_VAL_STRING(val_string_6,"6");
|
||||
DEF_CONST_VAL_STRING(val_string_7,"7");
|
||||
DEF_CONST_VAL_STRING(val_string_8,"8");
|
||||
DEF_CONST_VAL_STRING(val_string_9,"9");
|
||||
DEF_CONST_VAL_STRING(val_string_10,"10");
|
||||
DEF_CONST_VAL_STRING(val_string_11,"11");
|
||||
DEF_CONST_VAL_STRING(val_string_12,"12");
|
||||
DEF_CONST_VAL_STRING(val_string_13,"13");
|
||||
DEF_CONST_VAL_STRING(val_string_14,"14");
|
||||
DEF_CONST_VAL_STRING(val_string_15,"15");
|
||||
DEF_CONST_VAL_STRING(val_string_16,"16");
|
||||
DEF_CONST_VAL_STRING(val_string_17,"17");
|
||||
DEF_CONST_VAL_STRING(val_string_18,"18");
|
||||
DEF_CONST_VAL_STRING(val_string_19,"19");
|
||||
|
||||
DEF_CONST_VAL_INT(val_int_0,0);
|
||||
DEF_CONST_VAL_INT(val_int_1,1);
|
||||
DEF_CONST_VAL_INT(val_int_2,2);
|
||||
DEF_CONST_VAL_INT(val_int_3,3);
|
||||
DEF_CONST_VAL_INT(val_int_4,4);
|
||||
DEF_CONST_VAL_INT(val_int_5,5);
|
||||
DEF_CONST_VAL_INT(val_int_6,6);
|
||||
DEF_CONST_VAL_INT(val_int_7,7);
|
||||
DEF_CONST_VAL_INT(val_int_8,8);
|
||||
DEF_CONST_VAL_INT(val_int_9,9);
|
||||
DEF_CONST_VAL_INT(val_int_10,10);
|
||||
DEF_CONST_VAL_INT(val_int_11,11);
|
||||
DEF_CONST_VAL_INT(val_int_12,12);
|
||||
DEF_CONST_VAL_INT(val_int_13,13);
|
||||
DEF_CONST_VAL_INT(val_int_14,14);
|
||||
DEF_CONST_VAL_INT(val_int_15,15);
|
||||
DEF_CONST_VAL_INT(val_int_16,16);
|
||||
DEF_CONST_VAL_INT(val_int_17,17);
|
||||
DEF_CONST_VAL_INT(val_int_18,18);
|
||||
DEF_CONST_VAL_INT(val_int_19,19);
|
||||
|
||||
static const int val_int_const_max = 20;
|
||||
static const cst_val * const val_int_const [] = {
|
||||
VAL_INT_0,
|
||||
VAL_INT_1,
|
||||
VAL_INT_2,
|
||||
VAL_INT_3,
|
||||
VAL_INT_4,
|
||||
VAL_INT_5,
|
||||
VAL_INT_6,
|
||||
VAL_INT_7,
|
||||
VAL_INT_8,
|
||||
VAL_INT_9,
|
||||
VAL_INT_10,
|
||||
VAL_INT_11,
|
||||
VAL_INT_12,
|
||||
VAL_INT_13,
|
||||
VAL_INT_14,
|
||||
VAL_INT_15,
|
||||
VAL_INT_16,
|
||||
VAL_INT_17,
|
||||
VAL_INT_18,
|
||||
VAL_INT_19 };
|
||||
|
||||
static const cst_val * const val_string_const [] = {
|
||||
VAL_STRING_0,
|
||||
VAL_STRING_1,
|
||||
VAL_STRING_2,
|
||||
VAL_STRING_3,
|
||||
VAL_STRING_4,
|
||||
VAL_STRING_5,
|
||||
VAL_STRING_6,
|
||||
VAL_STRING_7,
|
||||
VAL_STRING_8,
|
||||
VAL_STRING_9,
|
||||
VAL_STRING_10,
|
||||
VAL_STRING_11,
|
||||
VAL_STRING_12,
|
||||
VAL_STRING_13,
|
||||
VAL_STRING_14,
|
||||
VAL_STRING_15,
|
||||
VAL_STRING_16,
|
||||
VAL_STRING_17,
|
||||
VAL_STRING_18,
|
||||
VAL_STRING_19 };
|
||||
|
||||
const cst_val *val_int_n(int n)
|
||||
{
|
||||
if (n < val_int_const_max)
|
||||
return val_int_const[n];
|
||||
else
|
||||
return val_int_const[val_int_const_max-1];
|
||||
}
|
||||
|
||||
/* carts are pretty confused about strings/ints, and some features */
|
||||
/* are actually used as floats and as int/strings */
|
||||
const cst_val *val_string_n(int n)
|
||||
{
|
||||
if (n < 0)
|
||||
return val_string_const[0];
|
||||
else if (n < val_int_const_max) /* yes I mean *int*, its the table size */
|
||||
return val_string_const[n];
|
||||
else
|
||||
return val_string_const[val_int_const_max-1];
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This technique isn't thread safe, so I replaced it with val_consts */
|
||||
static cst_features *val_string_consts = NULL;
|
||||
|
||||
const cst_val *val_string_x(const char *n)
|
||||
{
|
||||
const cst_val *v;
|
||||
|
||||
/* *BUG* This will have to be fixed soon */
|
||||
if (val_string_consts == NULL)
|
||||
val_string_consts = new_features();
|
||||
|
||||
v = feat_val(val_string_consts,n);
|
||||
if (v)
|
||||
return v;
|
||||
else
|
||||
{
|
||||
feat_set_string(val_string_consts,n,n);
|
||||
return feat_val(val_string_consts,n);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,165 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* 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 1999 */
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* User defined type registration */
|
||||
/* */
|
||||
/* I'd like to make this file be automatically generated */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* 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_val.h"
|
||||
#include "cst_string.h"
|
||||
|
||||
CST_VAL_REG_TD_TYPE(utterance,cst_utterance,7)
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
CST_VAL_REG_TD_TYPE(wave,cst_wave,9)
|
||||
CST_VAL_REG_TD_TYPE(track,cst_track,11)
|
||||
CST_VAL_REG_TD_TYPE(lpcres,cst_lpcres,13)
|
||||
CST_VAL_REG_TD_FUNCPTR(uttfunc,cst_uttfunc,15)
|
||||
#else
|
||||
CST_VAL_REG_TD_TYPE(wave,NULL,9)
|
||||
CST_VAL_REG_TD_TYPE(track,NULL,11)
|
||||
CST_VAL_REG_TD_TYPE(lpcres,NULL,13)
|
||||
CST_VAL_REG_TD_FUNCPTR(uttfunc,NULL,15)
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
CST_VAL_REG_TD_FUNCPTR(ffunc,cst_ffunction,17)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(relation,cst_relation,19)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(item,cst_item,21)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(cart,cst_cart,23)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(phoneset,cst_phoneset,25)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(lexicon,cst_lexicon,27)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(dur_stats,dur_stats,29)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(diphone_db,cst_diphone_db,31)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(clunit_db,cst_clunit_db,33)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(vit_cand,cst_vit_cand,35)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(sts_list,cst_sts_list,37)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(userdata,cst_userdata,41)
|
||||
CST_VAL_REGISTER_TYPE_NODEL(userdata,cst_userdata)
|
||||
CST_VAL_REG_TD_FUNCPTR(itemfunc,cst_itemfunc,43)
|
||||
CST_VAL_REG_TD_TYPE(features,cst_features,45)
|
||||
CST_VAL_REG_TD_FUNCPTR(breakfunc,cst_breakfunc,47)
|
||||
CST_VAL_REG_TD_TYPE_NODEL(cg_db,cst_cg_db,49)
|
||||
CST_VAL_REG_TD_TYPE(voice,cst_voice,51)
|
||||
CST_VAL_REG_TD_TYPE(audio_streaming_info,cst_audio_streaming_info,53)
|
||||
|
||||
const cst_val_def cst_val_defs[] = {
|
||||
/* These ones are never called */
|
||||
{ "int" , NULL }, /* 1 INT */
|
||||
{ "float", NULL }, /* 3 FLOAT */
|
||||
{ "string", NULL }, /* 5 STRING */
|
||||
/* These are indexed (type/2) at print and delete time */
|
||||
{ "utterance", val_delete_utterance }, /* 7 utterance */
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
{ "wave", val_delete_wave }, /* 9 wave */
|
||||
{ "track", val_delete_track }, /* 11 track */
|
||||
{ "lpcres", val_delete_lpcres }, /* 13 lpcres */
|
||||
{ "uttfunc", val_delete_uttfunc }, /* 15 uttfunc */
|
||||
#else
|
||||
{ "wave", NULL }, /* 9 wave */
|
||||
{ "track", NULL }, /* 11 track */
|
||||
{ "lpcres", NULL }, /* 13 lpcres */
|
||||
{ "uttfunc", NULL }, /* 15 uttfunc */
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
{ "ffunc", val_delete_ffunc }, /* 17 ffunc */
|
||||
{ "relation", val_delete_relation }, /* 19 relation */
|
||||
{ "item", val_delete_item }, /* 21 item */
|
||||
{ "cart", val_delete_cart }, /* 23 cart */
|
||||
{ "phoneset", val_delete_phoneset }, /* 25 phoneset */
|
||||
{ "lexicon", val_delete_lexicon }, /* 27 lexicon */
|
||||
{ "dur_stats", val_delete_dur_stats }, /* 29 dur_stats */
|
||||
{ "diphone_db", val_delete_diphone_db }, /* 31 diphone_db */
|
||||
{ "clunit_db", val_delete_clunit_db }, /* 33 clunit_db */
|
||||
{ "vit_cand", val_delete_vit_cand }, /* 35 vit_cand */
|
||||
{ "sts_list", val_delete_sts_list }, /* 37 sts_list */
|
||||
{ NULL, NULL }, /* 39 (reserved) */
|
||||
{ "userdata", val_delete_userdata }, /* 41 userdata */
|
||||
{ "itemfunc", val_delete_itemfunc }, /* 43 itemfunc */
|
||||
{ "features", val_delete_features }, /* 45 itemfunc */
|
||||
{ "breakfunc", val_delete_breakfunc }, /* 47 breakfunc */
|
||||
{ "cg_db", val_delete_cg_db }, /* 49 cg_db */
|
||||
#ifndef FLITE_PLUS_HTS_ENGINE
|
||||
{ "voice", val_delete_voice }, /* 51 cst_voice */
|
||||
{ "audio_streaming_info", val_delete_audio_streaming_info }, /* 53 asi */
|
||||
#else
|
||||
{ "voice", NULL }, /* 51 cst_voice */
|
||||
{ "audio_streaming_info", NULL }, /* 53 asi */
|
||||
#endif /* !FLITE_PLUS_HTS_ENGINE */
|
||||
{ NULL, NULL } /* NULLs at end of list */
|
||||
};
|
||||
Reference in New Issue
Block a user