blob: e52cad0ac5299da234a659b3a71cec0bdd6a423f [file] [log] [blame]
/*************************************************************************/
/* */
/* 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 */
}