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; }
static int cmu_grapheme_contains_vowel(const cst_val *r) { const cst_val *x; for (x=r; x; x=val_cdr(x)) { if (cmu_grapheme_is_vowel(val_string(val_car(x)))) return TRUE; } return FALSE; }
static int cmulex_onset_bigram(const cst_val *rest) { char x[10]; int i; cst_sprintf(x,"%s%s",val_string(val_car(rest)), val_string(val_car(val_cdr(rest)))); for (i=0; cmulex_onset_bigrams[i]; i++) if (cst_streq(x,cmulex_onset_bigrams[i])) return TRUE; return FALSE; }
static cst_val *add_lts_boundary_marks(const cst_val *l) { cst_val *l1; const cst_val *v; l1 = cons_val(string_val("#"),NULL); for (v=l;v;v=val_cdr(v)) { l1=cons_val(val_car(v),l1); } l1 = cons_val(string_val("#"),l1); l1 = val_reverse(l1); return l1; }
static int rule_matches(const cst_val *LC, const cst_val *RC, const cst_val *RLC, const cst_val *RA, const cst_val *RRC, const cst_val *sets) { const cst_val *rc, *ra; /* Check [ X ] bit */ for (rc=RC,ra=RA; ra; ra=val_cdr(ra),rc=val_cdr(rc)) { if (!rc) return FALSE; if (!cst_streq(val_string(val_car(ra)), val_string(val_car(rc)))) return FALSE; } /* Check LC bit: LC may have some limited regex stuff */ if (context_match(RLC,LC,sets) && context_match(RRC,rc,sets)) return TRUE; else return FALSE; }
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; } }
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; }
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; }
char *ru_implode(const cst_val *l) { const cst_val *v; size_t n=1; char *s,*p; for(v=l;(v!=NULL);v=val_cdr(v)) { if(val_stringp(val_car(v))) n+=strlen(val_string(val_car(v))); } s=cst_alloc(char,n); p=s; for(v=l;(v!=NULL);v=val_cdr(v)) { if(val_stringp(val_car(v))) { n=strlen(val_string(val_car(v))); memcpy(p,val_string(val_car(v)),n); p+=n; } } *p='\0'; return s; }
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; }
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; }
static int item_match(const cst_val *PATT, const cst_val *THING, const cst_val *sets) { const cst_val *sss; if (cst_streq(val_string(PATT),val_string(THING))) return TRUE; for (sss=sets; sss; sss=val_cdr(sss)) { if (cst_streq(val_string(val_car(val_car(sss))),val_string(PATT))) { /* Its a set not a letter */ if (val_member_string(val_string(THING),val_cdr(val_car(sss)))) { return TRUE; } else { return FALSE; } } } return FALSE; }
static void flite_voice_list_print(void) { cst_voice *voice; const cst_val *v; printf("Voices available: "); for (v=flite_voice_list; v; v=val_cdr(v)) { voice = val_voice(val_car(v)); printf("%s ",voice->name); } printf("\n"); return; }
cst_val *lts_rewrites(const cst_val *itape, const cst_lts_rewrites *r) { /* Returns list of rewritten "letters" to "phones" by r */ cst_val *LC; const cst_val *RC, *i; const cst_val *rule; cst_val *otape; LC = cons_val(val_car(itape),NULL); RC = val_cdr(itape); otape = NULL; while (val_cdr(RC)) { rule = find_rewrite_rule(LC,RC,r); if (!rule) break; /* val_print(stdout,rule); printf("\n"); */ /* Shift itape head */ for (i=val_car(val_cdr(rule)); i; i=val_cdr(i)) { LC = cons_val(val_car(RC),LC); RC = val_cdr(RC); } /* Output things to otape */ for (i=val_car(val_cdr(val_cdr(val_cdr(rule)))); i; i=val_cdr(i)) otape = cons_val(val_car(i),otape); } delete_val_list(LC); return val_reverse(otape); }
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); }
cst_val *cmu_grapheme_lex_lts_function(const struct lexicon_struct *l, const char *word, const char *pos, const cst_features *feats) { cst_val *phones = 0; cst_val *utflets = 0; const cst_val *v; char ord[10]; int i,phindex; /* string to utf8 chars */ utflets = cst_utf8_explode(word); for (v=utflets; v; v=val_cdr(v)) { /* We will add the found phones in reverse order and reverse then */ /* afterwards */ cst_utf8_as_hex(val_string(val_car(v)),ord); phindex = cst_find_u2sampa(ord); if (phindex < 0) printf("awb_debug no sampa %s %s\n",val_string(val_car(v)),ord); for (i=4; (phindex>=0) && (i>0); i--) { if (unicode_sampa_mapping[phindex][i]) phones = cons_val(string_val(unicode_sampa_mapping[phindex][i]), phones); } } phones = val_reverse(phones); #if 1 printf("cmu_grapheme_lex.c: word \"%s\" ",word); val_print(stdout,phones); printf("\n"); #endif delete_val(utflets); return phones; }
cst_utterance *default_lexical_insertion(cst_utterance *u) { cst_item *word; cst_relation *sylstructure,*seg,*syl; cst_lexicon *lex, *ulex = NULL; const cst_val *p; char *phone_name; char *stress = "0"; cst_val *phones; cst_item *ssword, *sssyl, *segitem, *sylitem, *seg_in_syl; lex = val_lexicon(feat_val(u->features,"lexicon")); if (feat_present(u->features, "user_lexicon")) ulex = val_lexicon(feat_val(u->features, "user_lexicon")); 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); phones = NULL; /* 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 { if (ulex) phones = lex_lookup(ulex,item_feat_string(word, "name"),0); if (phones == NULL) phones = lex_lookup(lex,item_feat_string(word,"name"),0); } 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[strlen(phone_name)-1] == '1') { stress = "1"; phone_name[strlen(phone_name)-1] = '\0'; } else if (phone_name[strlen(phone_name)-1] == '0') { stress = "0"; phone_name[strlen(phone_name)-1] = '\0'; } item_set_string(segitem,"name",phone_name); seg_in_syl = item_add_daughter(sssyl,segitem); if ((lex->syl_boundary)(seg_in_syl,val_cdr(p))) { 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")) delete_val(phones); } return u; }
static int context_match(const cst_val *PATTERN, const cst_val *STRING, const cst_val *sets) { if (!PATTERN) return TRUE; else if (!STRING) return FALSE; else if (val_cdr(PATTERN) && (cst_streq("*",val_string(val_car(PATTERN))))) return context_match(val_cdr(val_cdr(PATTERN)),STRING,sets) || /* skip */ context_match(val_cdr(PATTERN),STRING,sets) || /* last match */ (item_match(val_car(val_cdr(PATTERN)),val_car(STRING),sets) && context_match(val_cdr(val_cdr(PATTERN)), /* loop match */ val_cdr(STRING),sets)); #if 0 else if (val_cdr(PATTERN) && (cst_streq("+",val_string(val_car(PATTERN))))) return context_match(val_cdr(PATTERN),STRING,sets) || /* last match */ (item_match(val_car(val_cdr(PATTERN)),val_car(STRING),sets) && context_match(val_cdr(val_cdr(PATTERN)), /* loop match */ val_cdr(STRING),sets)); #endif else if (item_match(val_car(PATTERN),val_car(STRING),sets)) return context_match(val_cdr(PATTERN),val_cdr(STRING),sets); else return FALSE; }
int cmu_grapheme_syl_boundary(const cst_item *i,const cst_val *rest) { if (!rest) return TRUE; else if (!cmu_grapheme_contains_vowel(rest)) return FALSE; else if (!cmu_grapheme_has_vowel_in_syl(i)) return FALSE; #if 0 else if (rest && val_cdr(rest) && cst_streq("n",val_string(val_car(rest))) && !cmu_grapheme_is_vowel(val_string(val_car(rest)))) return FALSE; else if (rest && val_cdr(rest) && cmu_grapheme_is_vowel(ffeature_string(i,"name")) && !cmu_grapheme_is_vowel(val_string(val_car(rest))) && !cmu_grapheme_is_vowel(val_string(val_car(val_cdr(rest))))) return FALSE; else if (rest && val_cdr(rest) && val_cdr(val_cdr(rest)) && !cmu_grapheme_is_vowel(val_string(val_car(rest))) && !cmu_grapheme_is_vowel(val_string(val_car(val_cdr(rest)))) && !cmu_grapheme_is_vowel(val_string(val_car(val_cdr(val_cdr(rest)))))) return FALSE; else if (rest && val_cdr(rest) && (cst_streq(val_string(val_car(rest)), val_string(val_car(val_cdr(rest)))))) return FALSE; #endif else return TRUE; }
int main(int argc, char **argv) { cst_track *t1; cst_track *me_filters = NULL; cst_wave *w1, *w2, *res = NULL; cst_val *files; cst_features *args; int i, j; int order, o, s; int frame_length; float *lpcs, *residual; float m; const char *f1, *f2; const char *resfn = NULL; int last_peak = 0, next_peak; int period; float power; int rfc = 0; int str = 0; int fn, fo, ss; float xpulse, xnoise; float fxpulse, fxnoise; float x, me; float *hpulse = NULL, *hnoise = NULL; float *xpulsesig = NULL, *xnoisesig = NULL; int q = 0; int position; int lpc_start = 0; args = new_features(); files = cst_args(argv, argc, "usage: lpc_resynth OPTIONS INTRACK OUTWAVE\n" "Resynth an lpc track\n" "-res <string> residual (as waveform)\n" "-save_res Save the generated residual\n" "-lpc_start <int> start of lpc params in lpc track {1}\n" "-order <int> LPC order {16}\n" "-str mixed excitation strengths\n" "-me_filters <string> mixed excitation filters\n" "-rfc Coefficents are reflection coefficients\n", args); f1 = val_string(val_car(files)); f2 = val_string(val_car(val_cdr(files))); t1 = new_track(); lpc_start = mimic_get_param_int(args, "-lpc_start", 1); if (feat_present(args, "-rfc")) rfc = 1; if (feat_present(args, "-str")) str = 1; if (feat_present(args, "-me_filters")) { me_filters = new_track(); if (cst_track_load_est (me_filters, mimic_get_param_string(args, "-me_filters", "me_filters.track")) != CST_OK_FORMAT) { fprintf(stderr, "lpc_resynth: can't read file or wrong format \"%s\"\n", f1); return -1; } hpulse = cst_alloc(float, me_filters->num_channels); hnoise = cst_alloc(float, me_filters->num_channels); xpulsesig = cst_alloc(float, me_filters->num_channels); xnoisesig = cst_alloc(float, me_filters->num_channels); }
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; }
cst_utterance *russian_lexical_insertion(cst_utterance *u) { cst_item *word; cst_relation *sylstructure,*seg,*syl,*sylvowel,*transcription; const cst_val *p; const char *phone_name; cst_val *phones; cst_item *ssword, *sssyl, *segitem, *sylitem, *seg_in_syl, *svsyl, *vowel_in_syl, *tword, *seg_in_word; cst_item *i,*tmp; int num_segs; int total_num_segs=0; syl = utt_relation_create(u,"Syllable"); sylstructure = utt_relation_create(u,"SylStructure"); seg = utt_relation_create(u,"Segment"); sylvowel = utt_relation_create(u,"SylVowel"); transcription = utt_relation_create(u,"Transcription"); for (word=relation_head(utt_relation(u,"Word"));word;word=item_next(word)) { phones=word_to_phones(word); if(!phones) continue; num_segs=val_length(phones); if((total_num_segs+num_segs)>max_num_segs) { delete_val(phones); break; } ssword = relation_append(sylstructure,word); tword = relation_append(transcription,word); 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); } segitem = relation_append(seg,NULL); phone_name = val_string(val_car(p)); item_set_string(segitem,"name",phone_name); seg_in_syl = item_add_daughter(sssyl,segitem); seg_in_word = item_add_daughter(tword,segitem); if(is_vowel(phone_name)) { svsyl=relation_append(sylvowel,sylitem); vowel_in_syl=item_add_daughter(svsyl,segitem); } if (ru_syl_boundary(seg_in_syl,val_cdr(p))) { sylitem = NULL; if (sssyl) item_set_string(sssyl,"stress","0"); } } assign_stress(word); delete_val(phones); total_num_segs+=num_segs; } i=relation_head(utt_relation(u,"Word")); while(i) { tmp=item_next(i); if(item_as(i,"Transcription")==NULL) { delete_item(item_as(i,"Token")); delete_item(item_as(i,"Phrase")); delete_item(i); } i=tmp; } i=relation_head(utt_relation(u,"Phrase")); while(i) { tmp=item_next(i); if(item_daughter(i)==NULL) delete_item(i); i=tmp; } return u; }