ref: 1be6e96f18e4cfa572d56851ad1ff14ac345e426
dir: /src/wavesynth/cst_diphone.c/
/*************************************************************************/ /* */ /* Language Technologies Institute */ /* Carnegie Mellon University */ /* Copyright (c) 2001 */ /* All Rights Reserved. */ /* */ /* Permission is hereby granted, free of charge, to use and distribute */ /* this software and its documentation without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of this work, and to */ /* permit persons to whom this work is furnished to do so, subject to */ /* the following conditions: */ /* 1. The code must retain the above copyright notice, this list of */ /* conditions and the following disclaimer. */ /* 2. Any modifications must be clearly marked as such. */ /* 3. Original authors' names are not deleted. */ /* 4. The authors' names are not used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK */ /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */ /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */ /* SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE */ /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */ /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */ /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */ /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */ /* THIS SOFTWARE. */ /* */ /*************************************************************************/ /* Author: Alan W Black (awb@cs.cmu.edu) */ /* Date: January 2001 */ /*************************************************************************/ /* */ /* Diphone specific functions */ /* */ /*************************************************************************/ #include "cst_math.h" #include "cst_hrg.h" #include "cst_utt_utils.h" #include "cst_wave.h" #include "cst_track.h" #include "cst_diphone.h" #include "cst_units.h" #include "cst_sigpr.h" CST_VAL_REGISTER_TYPE_NODEL(diphone_db,cst_diphone_db) static int get_diphone_entry(cst_diphone_db *udb,const char *name); static int get_diphone_entry_bsearch(const cst_diphone_entry *entries, int start, int end, const char *key); cst_utterance* diphone_synth(cst_utterance *utt) { get_diphone_units(utt); join_units(utt); return utt; } cst_utterance *get_diphone_units(cst_utterance *utt) { /* Select units from db with times etc */ cst_relation *units; cst_item *s0, *s1, *u; float end0,end1; char diphone_name[22]; cst_diphone_db *udb; int unit_entry = -1; udb = val_diphone_db(utt_feat_val(utt,"diphone_db")); utt_set_feat(utt,"sts_list",sts_list_val(udb->sts)); units = utt_relation_create(utt,"Unit"); for (s0=relation_head(utt_relation(utt,"Segment")); s0 && item_next(s0); s0=s1) { s1 = item_next(s0); unit_entry = -1; if (cst_streq("-",ffeature_string(s0,"ph_vc")) && cst_streq("-",ffeature_string(s0,"R:SylStructure.n.ph_vc"))) { /* Might have consonant cluster diphones */ cst_sprintf(diphone_name, "%.10s_-_%.10s", item_name(s0), item_name(s1)); unit_entry = get_diphone_entry(udb,diphone_name); } if (unit_entry == -1) /* no consonant cluster diphone */ { cst_sprintf(diphone_name, "%.10s-%.10s", item_name(s0), item_name(s1)); unit_entry = get_diphone_entry(udb,diphone_name); } if (unit_entry == -1) { cst_errmsg("flite: udb failed to find entry for: %s\n", diphone_name); unit_entry = 0; } /* first half of diphone */ u = relation_append(units,NULL); item_add_daughter(s0,u); item_set_string(u,"name",diphone_name); end0 = item_feat_float(s0,"end"); item_set_int(u,"target_end", (int)(end0*udb->sts->sample_rate)); item_set_int(u,"unit_entry",unit_entry); item_set_int(u,"unit_start",udb->diphones[unit_entry].start_pm); item_set_int(u,"unit_end", udb->diphones[unit_entry].start_pm + udb->diphones[unit_entry].pb_pm); /* second half of diphone */ u = relation_append(units,NULL); item_add_daughter(s1,u); item_set_string(u,"name",diphone_name); end1 = item_feat_float(s1,"end"); item_set_int(u,"target_end",(int)(((end0+end1)/2.0)*udb->sts->sample_rate)); item_set_int(u,"unit_entry",unit_entry); item_set_int(u,"unit_start", udb->diphones[unit_entry].start_pm + udb->diphones[unit_entry].pb_pm); item_set_int(u,"unit_end", udb->diphones[unit_entry].start_pm + udb->diphones[unit_entry].pb_pm+ udb->diphones[unit_entry].end_pm); } return utt; } static int get_diphone_entry(cst_diphone_db *udb, const char *name) { return get_diphone_entry_bsearch(udb->diphones,0, udb->num_entries, name); } static int get_diphone_entry_bsearch(const cst_diphone_entry *entries, int start, int end, const char *key) { int mid,c; while (start < end) { mid = (start+end)/2; c = strcmp(entries[mid].name,key); if (c == 0) return mid; else if (c > 0) end = mid; else start = mid + 1; } return -1; /* can't find it */ }