/*
 * Build a glist of triphone senone-sequence IDs (ssids) derivable from [b] as a single
 * phone word, with a given left context l.  If no triphone found in mdef, include the ssid
 * for basephone b.  Return the generated glist.
 */
static glist_t single_lc_comsseq (mdef_t *mdef, int32 b, int32 l)
{
    int32 r, p, ssid;
    glist_t g;
    
    g = NULL;
    for (r = 0; r < mdef_n_ciphone(mdef); r++) {
	p = mdef_phone_id (mdef, (s3cipid_t)b, (s3cipid_t)l, (s3cipid_t)r, WORD_POSN_SINGLE);
	
	if (IS_S3PID(p)) {
	    ssid = mdef_pid2ssid(mdef, p);
	    if (! glist_chkdup_int32 (g, ssid))
		g = glist_add_int32 (g, ssid);
	}
    }
    if (! g)
	g = glist_add_int32 (g, mdef_pid2ssid(mdef, b));
    
    return g;
}
/*
 * Build a glist of triphone senone-sequence IDs (ssids) derivable from [b][r] at the word
 * begin position.  If no triphone found in mdef, include the ssid for basephone b.
 * Return the generated glist.
 */
static glist_t ldiph_comsseq (mdef_t *mdef, int32 b, int32 r)
{
    int32 l, p, ssid;
    glist_t g;
    
    g = NULL;
    for (l = 0; l < mdef_n_ciphone(mdef); l++) {
	p = mdef_phone_id (mdef, (s3cipid_t)b, (s3cipid_t)l, (s3cipid_t)r, WORD_POSN_BEGIN);
	
	if (IS_S3PID(p)) {
	    ssid = mdef_pid2ssid(mdef, p);
	    if (! glist_chkdup_int32 (g, ssid))
		g = glist_add_int32 (g, ssid);
	}
    }
    if (! g)
	g = glist_add_int32 (g, mdef_pid2ssid(mdef, b));
    
    return g;
}
Esempio n. 3
0
s3pid_t
mdef_phone_id_nearest(mdef_t * m,
                      s3cipid_t b, s3cipid_t l, s3cipid_t r,
                      word_posn_t pos)
{
    word_posn_t tmppos;
    s3pid_t p;
    s3cipid_t newl, newr;
    char *wpos_name;

    assert(m);
    assert((b >= 0) && (b < m->n_ciphone));
    assert((pos >= 0) && (pos < N_WORD_POSN));

    if ((NOT_S3CIPID(l)) || (NOT_S3CIPID(r)))
        return ((s3pid_t) b);

    assert((l >= 0) && (l < m->n_ciphone));
    assert((r >= 0) && (r < m->n_ciphone));

    p = mdef_phone_id(m, b, l, r, pos);
    if (IS_S3PID(p))
        return p;

    /* Exact triphone not found; backoff to other word positions */
    for (tmppos = 0; tmppos < N_WORD_POSN; tmppos++) {
        if (tmppos != pos) {
            p = mdef_phone_id(m, b, l, r, tmppos);
            if (IS_S3PID(p))
                return p;
        }
    }

    /* Nothing yet; backoff to silence phone if non-silence filler context */
    if (IS_S3CIPID(m->sil)) {
        newl = m->ciphone[(int) l].filler ? m->sil : l;
        newr = m->ciphone[(int) r].filler ? m->sil : r;
        if ((newl != l) || (newr != r)) {
            p = mdef_phone_id(m, b, newl, newr, pos);
            if (IS_S3PID(p))
                return p;

            for (tmppos = 0; tmppos < N_WORD_POSN; tmppos++) {
                if (tmppos != pos) {
                    p = mdef_phone_id(m, b, newl, newr, tmppos);
                    if (IS_S3PID(p))
                        return p;
                }
            }
        }
    }

    /* Nothing yet; backoff to base phone */
    if ((m->n_phone > m->n_ciphone) && (!m->ciphone[(int) b].filler)) {
        wpos_name = WPOS_NAME;
#if 0
        E_WARN("Triphone(%s,%s,%s,%c) not found; backing off to CIphone\n",
               mdef_ciphone_str(m, b),
               mdef_ciphone_str(m, l),
               mdef_ciphone_str(m, r), wpos_name[pos]);
#endif
    }
    return ((s3pid_t) b);
}