static int WordSylSeg(cst_utterance *u) { cst_item *word; cst_relation *sylstructure,*seg,*syl; cst_val *phones; const cst_val *p; cst_item *ssword,*segitem; 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)) { printf("word: %s\n",item_feat_string(word,"name")); ssword = relation_append(sylstructure,word); phones = lex_lookup((cst_lexicon *)&cmu_lex,item_feat_string(word,"name"),0); for (p=phones; p; p=val_cdr(p)) { segitem = relation_append(seg,NULL); item_set(segitem,"name",val_car(p)); printf("seg: %s\n",item_feat_string(segitem,"name")); item_add_daughter(ssword,segitem); } delete_val_list(phones); } return TRUE; }
static float cg_state_duration(cst_item *s, cst_cg_db *cg_db) { float zdur, dur; const char *n; int i, x; zdur = val_float(cart_interpret(s,cg_db->dur_cart)); n = item_feat_string(s,"name"); for (x=i=0; cg_db->dur_stats[i]; i++) { if (cst_streq(cg_db->dur_stats[i]->phone,n)) { x=i; break; } } if (!cg_db->dur_stats[i]) /* unknown type name */ x = 0; dur = (zdur*cg_db->dur_stats[x]->stddev)+cg_db->dur_stats[x]->mean; /* dur = 1.2 * (float)exp((float)dur); */ return dur; }
int relation_save(cst_relation *r, const char *filename) { cst_file fd; cst_item *item; if (cst_streq(filename, "-")) fd = stdout; else if ((fd = cst_fopen(filename, CST_OPEN_WRITE)) == 0) { cst_errmsg("relation_save: can't open file \"%s\" for writing\n", filename); return CST_ERROR_FORMAT; } for (item = relation_head(r); item; item = item_next(item)) { if (item_feat_present(item, "end")) cst_fprintf(fd, "%f ", item_feat_float(item, "end")); else cst_fprintf(fd, "%f ", 0.00); if (item_feat_present(item, "name")) cst_fprintf(fd, "%s ", item_feat_string(item, "name")); else cst_fprintf(fd, "%s ", "_"); cst_fprintf(fd, "\n"); } if (fd != stdout) cst_fclose(fd); return CST_OK_FORMAT; }
static float cg_state_duration(cst_item *s, cst_cg_db *cg_db) { float zdur, dur; const char *n; int i, x; #ifdef STATICANALYZEDEPENDENCIES #define __clang_analyzer__ 1 #endif #if !defined(__clang_analyzer__) || defined(STATICANALYZEDEPENDENCIES) #undef __clang_analyzer__ zdur = val_float(cart_interpret(s,cg_db->dur_cart)); n = item_feat_string(s,"name"); for (x=i=0; cg_db->dur_stats[i]; i++) { if (cst_streq(cg_db->dur_stats[i]->phone,n)) { x=i; break; } } if (!cg_db->dur_stats[i]) /* unknown type name */ x = 0; dur = (zdur*cg_db->dur_stats[x]->stddev)+cg_db->dur_stats[x]->mean; /* dur = 1.2 * (float)exp((float)dur); */ return dur; }
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; }
int main(int argc, char **argv) { cst_utterance *u; cst_relation *r; cst_item *item=0; int i; u = new_utterance(); r = utt_relation_create(u,"Segment"); for (i=0; i<10; i++) { char buff[20]; sprintf(buff,"seg_%03d",i); if (i==0) item = relation_append(r,NULL); else item = item_append(item,NULL); item_set_string(item,"name",buff); item_set_float(item,"duration",i*0.20); } for (i=0,item=relation_head(utt_relation(u,"Segment")); item; item=item_next(item),i++) { printf("Segment %d %s %f\n", i, item_feat_string(item,"name"), item_feat_float(item,"duration")); } delete_utterance(u); return 0; }
static int ifd_syl_boundary(const cst_item *i,const cst_val *v) { /* Returns TRUE if this should be a syllable boundary */ /* This is of course phone set dependent */ int p, n, nn; if (v == NULL) return TRUE; else if (ifd_is_silence(val_string(val_car(v)))) return TRUE; else if (!ifd_has_vowel_in_list(v)) /* no more vowels so rest *all* coda */ return FALSE; else if (!ifd_has_vowel_in_syl(i)) /* need a vowel */ return FALSE; else if (ifd_is_vowel(val_string(val_car(v)))) return TRUE; else if (val_cdr(v) == NULL) return FALSE; else { /* so there is following vowel, and multiple phones left */ p = ifd_sonority(item_feat_string(i,"name")); n = ifd_sonority(val_string(val_car(v))); nn = ifd_sonority(val_string(val_car(val_cdr(v)))); if ((p <= n) && (n <= nn)) return TRUE; else return FALSE; } }
static cst_utterance *cg_make_hmmstates(cst_utterance *utt) { /* Build HMM state structure below the segment structure */ cst_cg_db *cg_db; cst_relation *hmmstate, *segstate; cst_item *seg, *s, *ss; const char *segname; int sp,p; cg_db = val_cg_db(utt_feat_val(utt,"cg_db")); hmmstate = utt_relation_create(utt,"HMMstate"); segstate = utt_relation_create(utt,"segstate"); for (seg = utt_rel_head(utt,"Segment"); seg; seg=item_next(seg)) { ss = relation_append(segstate,seg); segname = item_feat_string(seg,"name"); for (p=0; cg_db->phone_states[p]; p++) if (cst_streq(segname,cg_db->phone_states[p][0])) break; if (cg_db->phone_states[p] == NULL) p = 0; /* unknown phoneme */ for (sp=1; cg_db->phone_states[p][sp]; sp++) { s = relation_append(hmmstate,NULL); item_add_daughter(ss,s); item_set_string(s,"name",cg_db->phone_states[p][sp]); item_set_int(s,"statepos",sp); } } return utt; }
static cst_val *cmu_LANGNAME_tokentowords(cst_item *token, const char *name) { /* Return list of words that expand token/name */ cst_val *r; /* printf("token_name %s name %s\n",item_name(token),name); */ if (item_feat_present(token,"phones")) return cons_val(string_val(name),NULL); #if 0 if (item_feat_present(token,"nsw")) nsw = item_feat_string(token,"nsw"); utt = item_utt(token); lex = val_lexicon(feat_val(utt->features,"lexicon")); #endif if (cst_strlen(name) > 0) r = cons_val(string_val(name),0); else r = NULL; return r; }
cst_utterance *russian_postlex_function(cst_utterance *u) { const cst_item *word,*seg; const char *answer,*name,*pair; for(word=relation_head(utt_relation(u,"Transcription"));word;word=item_next(word)) { if(item_feat_present(word,"no_pl")||item_feat_present(word,"no_vr")) continue; for(seg=item_daughter(word);seg;seg=item_next(seg)) { name=item_feat_string(seg,"name"); if(cst_member_string(name,unstressed_vowels)) { answer=val_string(cart_interpret(item_as(seg,"Segment"),&ru_vowel_reduction_cart)); if(!cst_streq(answer,"N")) item_set_string(seg,"name",answer); } else { if(cst_streq(name,"ii")&& cst_streq(ffeature_string(seg,"R:Segment.p.ph_csoft"),"-")&& !(cst_streq(item_feat_string(word,"name"),"и")&& cst_streq(ffeature_string(word,"gpos"),"content"))) { item_set_string(seg,"name","yy"); } } } } for(word=relation_tail(utt_relation(u,"Transcription"));word;word=item_prev(word)) { if(item_feat_present(word,"no_pl")) continue; for(seg=item_last_daughter(word);seg;seg=item_prev(seg)) { name=item_feat_string(seg,"name"); pair=russian_vpair(name); if(pair!=NULL) { answer=val_string(cart_interpret(item_as(seg,"Segment"),&ru_vpair_cart)); if(cst_streq(answer,"Y")) item_set_string(seg,"name",pair); } } } return u; }
static void fix_ah(cst_utterance *u) { /* This should really be done in the index itself */ const cst_item *s; for (s=relation_head(utt_relation(u,"Segment")); s; s=item_next(s)) if (cst_streq(item_feat_string(s,"name"),"ah")) item_set_string(s,"name","aa"); }
static int ifd_has_vowel_in_syl(const cst_item *i) { const cst_item *n; for (n=i; n; n=item_prev(n)) if (ifd_is_vowel(item_feat_string(n,"name"))) return TRUE; return FALSE; }
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 int vowel_seg_between(const cst_item *f,const cst_item *l) { const cst_item *s; for(s=f;s;s=item_next(s)) { if(is_vowel(item_feat_string(s,"name"))) return TRUE; if(item_equal(s,l)) break; } return FALSE; }
static const cst_val *seg_onsetcoda(const cst_item *seg) { const cst_item *s; const cst_phoneset *ps = item_phoneset(seg); 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 cst_utterance *print_info(cst_utterance *u) { cst_item *item; const char *relname; relname = utt_feat_string(u,"print_info_relation"); for (item=relation_head(utt_relation(u,relname)); item; item=item_next(item)) { printf("%s ",item_feat_string(item,"name")); } printf("\n"); return u; }
static int my_call_back(cst_item *i) { const char *name; name = item_feat_string(i, "name"); if (cst_streq(name, "__silence__")) printf("\n"); else { /* printf("%s %f\n",name,item_feat_float(i,"end")); */ printf("%s ", name); fflush(stdout); } return CST_OK_FORMAT; }
static cst_val* word_to_phones(const cst_item *word) { cst_val*phones=NULL; const char *name=item_feat_string(word, "name"); ustring32_t letters=ustring32_alloc(0); if(letters==NULL) return NULL; ustring32_assign8(letters,(const uint8_t*)name); if(ustring32_empty(letters)) { ustring32_free(letters); return NULL; } unsigned int flags=classify_characters(ustring32_str(letters),ustring32_length(letters)); int variant=item_feat_int(item_parent(item_as(word,"Token")),"variant"); if((flags&cs_lc)&&cst_streq(ffeature_string(word,"gpos"),"content")) { if(variant==variant_pseudo_english) phones=ustring32_lts_apply(letters,&en_consonants_lts); else phones=ustring32_lts_apply(letters,&ru_consonants_lts); item_set_int(word,"no_vr",1); } else if((variant==variant_pseudo_english)&&(flags&cs_en)) { cst_val *en_phones=lex_lookup(en_lex,name,(cst_streq(name,"a")?"n":NULL)); if(en_phones) { phones=ru_lts_apply(en_phones,&ru_en_lts); delete_val(en_phones); } item_set_int(word,"no_pl",1); } else { const ru_dict_entry *e=bsearch(name,ru_dict,ru_dict_size,sizeof(ru_dict_entry),compare_entries); if(e!=NULL) { if(e->stress > 0) ustring32_set(letters,e->stress-1,1105); else item_set_int(word,"stressed_syl_num",e->stress); } phones=ustring32_lts_apply(letters,&ru_lts); } ustring32_free(letters); return phones; }
static const cst_val *gpos(const cst_item *word) { /* Guess at part of speech (function/content) */ const char *w; int s,t; w = item_feat_string(word,"name"); for (s=0; us_gpos[s]; s++) { for (t=1; us_gpos[s][t]; t++) if (cst_streq(w,val_string(us_gpos[s][t]))) return us_gpos[s][0]; } return (cst_val *)&val_string_content; }
static void apostrophe_s(cst_utterance *u) { cst_item *s; cst_item *schwa; const cst_phoneset *ps = u->vox->phoneset; const char *pname, *word; for (s=item_next(UTT_REL_HEAD(u,SEGMENT)); s; s=item_next(s)) { word = val_string(ffeature(s, "R:"SYLSTRUCTURE".P.P.name")); if (cst_streq("'s", word)) { pname = item_feat_string(item_prev(s),"name"); if ((strchr("fa",*phone_feature_string(ps,pname,"ctype")) != NULL) && (strchr("dbg", *phone_feature_string(ps,pname,"cplace")) == NULL)) /* needs a schwa */ { schwa = item_prepend(s,NULL); item_set_string(schwa,"name","ax"); item_prepend(item_as(s,SYLSTRUCTURE),schwa); } else if (cst_streq("-",phone_feature_string(ps,pname,"cvox"))) item_set_string(s,"name","s"); } else if (cst_streq("'ve", word) || cst_streq("'ll", word) || cst_streq("'d", word)) { if (cst_streq("-",ffeature_string(s,"p."PH_VC))) { schwa = item_prepend(s,NULL); item_set_string(schwa,"name","ax"); item_prepend(item_as(s,SYLSTRUCTURE),schwa); } } } }
static cst_utterance *print_info(cst_utterance *u) { cst_item *item; const char *relname; relname = utt_feat_string(u,"print_info_relation"); for (item=relation_head(utt_relation(u,relname)); item; item=item_next(item)) { printf("%s ",item_feat_string(item,"name")); #if 0 if (cst_streq("+",ffeature_string(item,"ph_vc"))) printf("%s",ffeature_string(item,"R:SylStructure.parent.stress")); printf(" "); #endif } printf("\n"); return u; }
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 *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 */ }
string getPhonemes( const char* sText ) { string sRet; cst_features* args = new_features(); cst_voice* v; cst_utterance* u; cst_item* s; const char* name; //const cst_val* d; flite_init(); v = register_cmu_us_no_wave( NULL ); u = flite_synth_text( sText, v ); for ( s = relation_head( utt_relation( u, "Segment" ) ); s; s = item_next( s ) ) { sRet += item_feat_string( s, "name" ); float test = item_feat_float( s, "end" ); //d = segment_duration( s ); /* If its a vowel and is stressed output stress value */ if ( ( cst_streq( "+", ffeature_string( s, "ph_vc" ) ) ) && ( cst_streq( "1", ffeature_string( s, "R:SylStructure.parent.stress" ) ) ) ) { sRet += "1"; } sRet += " "; } delete_utterance( u ); delete_features( args ); return sRet; }
cst_utterance *flowm_print_relation_callback(cst_utterance *u) { /* Say the details of a named relation for display */ char rst[FL_MAX_MSG_CHARS]; const char *name; const char *relname; cst_item *item; char *space; space = ""; relname = get_param_string(u->features,"print_info_relation", NULL); cst_sprintf(rst,"%s: ",relname); if (!relname) { mbstowcs(fl_tts_msg,"",FL_MAX_MSG_CHARS); return u; } for (item=relation_head(utt_relation(u,relname)); item; item=item_next(item)) { name = item_feat_string(item,"name"); if (cst_strlen(name)+1+4 < FL_MAX_MSG_CHARS) cst_sprintf(rst,"%s%s%s",rst,space,name); else if (cst_strlen(rst)+4 < FL_MAX_MSG_CHARS) cst_sprintf(rst,"%s ...",rst); else break; space = " "; } mbstowcs(fl_tts_msg,rst,FL_MAX_MSG_CHARS); return u; }
static int ru_syl_boundary(const cst_item *i,const cst_val *v) { const char *p; const char *n; const char *nn; if (v == NULL) return TRUE; n=val_string(val_car(v)); if (is_silence(n)) return TRUE; if (!has_vowel_in_list(v)) return FALSE; if (!has_vowel_in_syl(i)) return FALSE; if (is_vowel(n)) return TRUE; if (val_cdr(v) == NULL) return FALSE; p = item_feat_string(i,"name"); nn = val_string(val_car(val_cdr(v))); if(is_vowel(p)) { if(is_vowel(nn)) return TRUE; if(is_sonorant(n)&&!is_sonorant(nn)) return FALSE; if(is_j(n)) return FALSE; return TRUE; } if(is_sonorant(p)) return TRUE; if(is_j(p)) return TRUE; return FALSE; }
static cst_utterance *cg_predict_params(cst_utterance *utt) { cst_cg_db *cg_db; cst_track *param_track; cst_track *str_track = NULL; cst_item *mcep; const cst_cart *mcep_tree, *f0_tree; int i,j,f,p,fd,o; const char *mname; float f0_val; int fff; int extra_feats = 0; cg_db = val_cg_db(utt_feat_val(utt,"cg_db")); param_track = new_track(); if (cg_db->do_mlpg) /* which should be the default */ fff = 1; /* copy details with stddevs */ else fff = 2; /* copy details without stddevs */ extra_feats = 1; /* voicing */ if (cg_db->mixed_excitation) { extra_feats += 5; str_track = new_track(); cst_track_resize(str_track, utt_feat_int(utt,"param_track_num_frames"), 5); } cst_track_resize(param_track, utt_feat_int(utt,"param_track_num_frames"), (cg_db->num_channels0/fff)- (2 * extra_feats));/* no voicing or str */ for (i=0,mcep=utt_rel_head(utt,"mcep"); mcep; i++,mcep=item_next(mcep)) { mname = item_feat_string(mcep,"name"); for (p=0; cg_db->types[p]; p++) if (cst_streq(mname,cg_db->types[p])) break; if (cg_db->types[0] == NULL) p=0; /* if there isn't a matching tree, use the first one */ /* Predict F0 */ f0_tree = cg_db->f0_trees[p]; f0_val = val_float(cart_interpret(mcep,f0_tree)); param_track->frames[i][0] = f0_val; /* what about stddev ? */ if (cg_db->multimodel) { /* MULTI model */ f = val_int(cart_interpret(mcep,cg_db->param_trees0[p])); fd = val_int(cart_interpret(mcep,cg_db->param_trees1[p])); item_set_int(mcep,"clustergen_param_frame",f); param_track->frames[i][0] = (param_track->frames[i][0]+ CG_MODEL_VECTOR(cg_db,model_vectors0,f,0)+ CG_MODEL_VECTOR(cg_db,model_vectors1,fd,0))/3.0; for (j=2; j<param_track->num_channels; j++) param_track->frames[i][j] = (CG_MODEL_VECTOR(cg_db,model_vectors0,f,(j)*fff)+ CG_MODEL_VECTOR(cg_db,model_vectors1,fd,(j)*fff))/2.0; if (cg_db->mixed_excitation) { o = j; for (j=0; j<5; j++) { str_track->frames[i][j] = (CG_MODEL_VECTOR(cg_db,model_vectors0,f,(o+(2*j))*fff)+ CG_MODEL_VECTOR(cg_db,model_vectors1,fd,(o+(2*j))*fff))/2.0; } } } else { /* SINGLE model */ /* Predict Spectral */ mcep_tree = cg_db->param_trees0[p]; f = val_int(cart_interpret(mcep,mcep_tree)); item_set_int(mcep,"clustergen_param_frame",f); param_track->frames[i][0] = (param_track->frames[i][0]+ CG_MODEL_VECTOR(cg_db,model_vectors0,f,0))/2.0; for (j=2; j<param_track->num_channels; j++) param_track->frames[i][j] = CG_MODEL_VECTOR(cg_db,model_vectors0,f,(j)*fff); if (cg_db->mixed_excitation) { o = j; for (j=0; j<5; j++) { str_track->frames[i][j] = CG_MODEL_VECTOR(cg_db,model_vectors0,f,(o+(2*j))*fff); } } } /* last coefficient is average voicing for cluster */ item_set_float(mcep,"voicing", CG_MODEL_VECTOR(cg_db,model_vectors0,f, cg_db->num_channels0-2)); param_track->times[i] = i * cg_db->frame_advance; } cg_smooth_F0(utt,cg_db,param_track); utt_set_feat(utt,"param_track",track_val(param_track)); if (cg_db->mixed_excitation) utt_set_feat(utt,"str_track",track_val(str_track)); return utt; }
cst_val *default_tokentowords(cst_item *i) { return cons_val(string_val(item_feat_string(i,"name")), NULL); }
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; }
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; }