Пример #1
0
int
main(int argc, char *argv[])
{
	listelem_alloc_t *le;
	struct bogus *bogus1, *bogus2;
	int i;

	TEST_ASSERT(le = listelem_alloc_init(sizeof(struct bogus)));
	bogus1 = listelem_malloc(le);
	bogus1->str = "hello";
	bogus1->foobie = 42;
	bogus2 = listelem_malloc(le);
	bogus2->str = "goodbye";
	bogus2->foobie = 69;
	TEST_EQUAL(bogus1->foobie, 42);
	TEST_EQUAL(0, strcmp(bogus1->str, "hello"));
	listelem_free(le, bogus1);
	listelem_free(le, bogus2);
	listelem_alloc_free(le);

	TEST_ASSERT(le = listelem_alloc_init(sizeof(struct bogus)));
	listelem_stats(le);
	for (i = 0; i < 60; ++i)
		bogus1 = listelem_malloc(le);
	listelem_stats(le);
	listelem_alloc_free(le);

	{
		struct bogus *bogus[600];
		int32 bogus_id[600];

		le = listelem_alloc_init(sizeof(struct bogus));
		for (i = 0; i < 600; ++i)
			bogus[i] = listelem_malloc_id(le, bogus_id + i);
		listelem_stats(le);
		for (i = 0; i < 600; ++i) {
			TEST_EQUAL(bogus[i], listelem_get_item(le, bogus_id[i]));
		}
		for (i = 0; i < 600; ++i)
			listelem_free(le, bogus[i]);
		listelem_stats(le);
		for (i = 0; i < 600; ++i)
			bogus[i] = listelem_malloc_id(le, bogus_id + i);
		listelem_stats(le);
		for (i = 0; i < 600; ++i)
			TEST_EQUAL(bogus[i], listelem_get_item(le, bogus_id[i]));
		listelem_alloc_free(le);
	}


	return 0;
}
/**
 * Free HMM network for one utterance of fwdflat search.
 */
static void
destroy_fwdflat_chan(ngram_search_t *ngs)
{
    int32 i, wid;

    for (i = 0; ngs->fwdflat_wordlist[i] >= 0; i++) {
        root_chan_t *rhmm;
        chan_t *thmm;
        wid = ngs->fwdflat_wordlist[i];
        if (dict_is_single_phone(ps_search_dict(ngs),wid))
            continue;
        assert(ngs->word_chan[wid] != NULL);

        /* The first HMM in ngs->word_chan[wid] was allocated with
         * ngs->root_chan_alloc, but this will attempt to free it
         * using ngs->chan_alloc, which will not work.  Therefore we
         * free it manually and move the list forward before handing
         * it off. */
        rhmm = (root_chan_t *)ngs->word_chan[wid];
        thmm = rhmm->next;
        listelem_free(ngs->root_chan_alloc, rhmm);
        ngs->word_chan[wid] = thmm;
        ngram_search_free_all_rc(ngs, wid);
    }
}
Пример #3
0
static void hyp_free (hyp_t *list)
{
    hyp_t *h;
    
    while (list) {
	h = list->next;
	listelem_free ((char *)list, sizeof(hyp_t));
	list = h;
    }
}
static void slinks_free (slink_t *l)
{
    slink_t *tmp;
    
    while (l) {
	tmp = l->next;
	listelem_free ((char *) l, sizeof(slink_t));
	l = tmp;
    }
}
/* Free all allocated pnodes */
static void pnodes_free ( void )
{
    pnode_t *p;
    
    while (pnode_list) {
	p = pnode_list->alloc_next;
	listelem_free ((char *) pnode_list, sizeof(pnode_t));
	pnode_list = p;
    }
}
Пример #6
0
static void delete_unreachable ( void )
{
    latnode_t *node, *t_node, *prev_node;
    latlink_t *link, *t_link;
    
    prev_node = NULL;
    for (node = latnode_list; node; node = t_node) {
	t_node = node->next;
	if (! node->reachable) {
	    /* Node and its links can be removed */
	    if (prev_node)
		prev_node->next = node->next;
	    else
		latnode_list = node->next;
	    for (link = node->links; link; link = t_link) {
		t_link = link->next;
		listelem_free (link, sizeof(latlink_t));
	    }
	    listelem_free (node, sizeof(latnode_t));
	} else
	    prev_node = node;
    }
}
/**
 * Destroy wordlist from the current utterance.
 */
static void
destroy_fwdflat_wordlist(ngram_search_t *ngs)
{
    ps_latnode_t *node, *tnode;
    int32 f;

    if (!ngs->fwdtree)
        return;

    for (f = 0; f < ngs->n_frame; f++) {
        for (node = ngs->frm_wordlist[f]; node; node = tnode) {
            tnode = node->next;
            listelem_free(ngs->latnode_alloc, node);
        }
    }
}
/*
 * Remove src->dst link and return the associated prob.
 */
static int32 un_slink_succ (snode_t *src, snode_t *dst)
{
    slink_t *l, *prevl;
    int32 prob;
    
    /* Find link from src to dst */
    prevl = NULL;
    for (l = src->succlist; l && (l->node != dst); l = l->next)
	prevl = l;
    assert (l);	/* The link must exist */
    
    if (! prevl)
	src->succlist = l->next;
    else
	prevl->next = l->next;
    
    prob = l->prob;
    listelem_free ((char *)l, sizeof(slink_t));
    
    return prob;
}
Пример #9
0
static void bypass_filler_nodes ( void )
{
    latnode_t *node, *to, *from, *prev_node, *t_node;
    latlink_t *link, *f_link, *t_link, *prev_link;
    rev_latlink_t *revlink, *t_revlink;
    int32 score;
    
    /* Create reverse links for all links pointing to filler nodes */
    for (node = latnode_list; node; node = node->next) {
	for (link = node->links; link; link = link->next) {
	    to = link->to;
	    if (ISA_FILLER_WORD(to->wid)) {
		revlink = (rev_latlink_t *) listelem_alloc (sizeof (rev_latlink_t));
		revlink->link = link;
		revlink->next = to->revlinks;
		to->revlinks = revlink;
	    }
	}
    }

    /* Bypass filler nodes */
    for (node = latnode_list; node; node = node->next) {
	if (! ISA_FILLER_WORD(node->wid))
	    continue;
	
	/* Replace each link entering filler node with links to all its successors */
	for (revlink = node->revlinks; revlink; revlink = revlink->next) {
	    link = revlink->link;	/* link entering filler node */
	    from = link->from;
	    
	    score = (node->wid == sil_wid) ? sil_pen : filler_pen;
	    score += link->link_scr;
	    
	    /*
	     * Make links from predecessor of filler (from) to successors of filler.
	     * But if successor is a filler, it has already been eliminated since it
	     * appears earlier in latnode_list (see build...).  So it can be skipped.
	     * Likewise, no reverse links needed for the new links; none of them
	     * points to a filler node.
	     */
	    for (f_link = node->links; f_link; f_link = f_link->next) {
		if (! ISA_FILLER_WORD(f_link->to->wid))
		    link_latnodes (from, f_link->to, score + f_link->link_scr, link->ef);
	    }
	}
    }

    /* Delete filler nodes and all links and reverse links from it */
    prev_node = NULL;
    for (node = latnode_list; node; node = t_node) {
	t_node = node->next;
	if (ISA_FILLER_WORD(node->wid)) {
	    for (revlink = node->revlinks; revlink; revlink = t_revlink) {
		t_revlink = revlink->next;
		revlink->link->to = NULL;
		listelem_free (revlink, sizeof(rev_latlink_t));
	    }

	    for (link = node->links; link; link = t_link) {
		t_link = link->next;
		listelem_free (link, sizeof(latlink_t));
	    }

	    if (prev_node)
		prev_node->next = t_node;
	    else
		latnode_list = t_node;
		
	    listelem_free (node, sizeof(latnode_t));
	} else
	    prev_node = node;
    }

    /* Reclaim links pointing nowhere */
    for (node = latnode_list; node; node = node->next) {
	prev_link = NULL;
	for (link = node->links; link; link = t_link) {
	    t_link = link->next;
	    if (link->to == NULL) {
		if (prev_link)
		    prev_link->next = t_link;
		else
		    node->links = t_link;
		listelem_free (link, sizeof(latlink_t));
	    } else
		prev_link = link;
	}
    }
}
/**
 * Find all active words in backpointer table and sort by frame.
 */
static void
build_fwdflat_wordlist(ngram_search_t *ngs)
{
    int32 i, f, sf, ef, wid, nwd;
    bptbl_t *bp;
    ps_latnode_t *node, *prevnode, *nextnode;

    /* No tree-search, use statically allocated wordlist. */
    if (!ngs->fwdtree)
        return;

    memset(ngs->frm_wordlist, 0, ngs->n_frame_alloc * sizeof(*ngs->frm_wordlist));

    /* Scan the backpointer table for all active words and record
     * their exit frames. */
    for (i = 0, bp = ngs->bp_table; i < ngs->bpidx; i++, bp++) {
        sf = (bp->bp < 0) ? 0 : ngs->bp_table[bp->bp].frame + 1;
        ef = bp->frame;
        wid = bp->wid;

        /* Anything that can be transitioned to in the LM can go in
         * the word list. */
        if (!ngram_model_set_known_wid(ngs->lmset,
                                       dict_basewid(ps_search_dict(ngs), wid)))
            continue;

        /* Look for it in the wordlist. */
        for (node = ngs->frm_wordlist[sf]; node && (node->wid != wid);
             node = node->next);

        /* Update last end frame. */
        if (node)
            node->lef = ef;
        else {
            /* New node; link to head of list */
            node = listelem_malloc(ngs->latnode_alloc);
            node->wid = wid;
            node->fef = node->lef = ef;

            node->next = ngs->frm_wordlist[sf];
            ngs->frm_wordlist[sf] = node;
        }
    }

    /* Eliminate "unlikely" words, for which there are too few end points */
    for (f = 0; f < ngs->n_frame; f++) {
        prevnode = NULL;
        for (node = ngs->frm_wordlist[f]; node; node = nextnode) {
            nextnode = node->next;
            /* Word has too few endpoints */
            if ((node->lef - node->fef < ngs->min_ef_width) ||
                /* Word is </s> and doesn't actually end in last frame */
                ((node->wid == ps_search_finish_wid(ngs)) && (node->lef < ngs->n_frame - 1))) {
                if (!prevnode)
                    ngs->frm_wordlist[f] = nextnode;
                else
                    prevnode->next = nextnode;
                listelem_free(ngs->latnode_alloc, node);
            }
            else
                prevnode = node;
        }
    }

    /* Form overall wordlist for 2nd pass */
    nwd = 0;
    bitvec_clear_all(ngs->word_active, ps_search_n_words(ngs));
    for (f = 0; f < ngs->n_frame; f++) {
        for (node = ngs->frm_wordlist[f]; node; node = node->next) {
            if (!bitvec_is_set(ngs->word_active, node->wid)) {
                bitvec_set(ngs->word_active, node->wid);
                ngs->fwdflat_wordlist[nwd++] = node->wid;
            }
        }
    }
    ngs->fwdflat_wordlist[nwd] = -1;
    E_INFO("Utterance vocabulary contains %d words\n", nwd);
}
/*
 * All frames consumed.  Trace back best Viterbi state sequence and dump it out.
 */
int32 align_end_utt (align_stseg_t **stseg_out,
		     align_phseg_t **phseg_out,
		     align_wdseg_t **wdseg_out)
{
    slink_t *l;
    snode_t *s;
    history_t *h, *ph, *nh;
    align_stseg_t *stseg;
    align_phseg_t *phseg;
    align_wdseg_t *wdseg;
    
    /* Free up previous result, if any */
    while (align_stseg) {
	stseg = align_stseg->next;
	listelem_free ((char *) align_stseg, sizeof(align_stseg_t));
	align_stseg = stseg;
    }
    while (align_phseg) {
	phseg = align_phseg->next;
	listelem_free ((char *) align_phseg, sizeof(align_phseg_t));
	align_phseg = phseg;
    }
    while (align_wdseg) {
	wdseg = align_wdseg->next;
	listelem_free ((char *) align_wdseg, sizeof(align_wdseg_t));
	align_wdseg = wdseg;
    }
    
    /* First find best ending history and link to stail */
    stail.score = (int32)0x80000000;
    stail.hist = NULL;
    for (l = stail.predlist; l; l = l->next) {
	s = l->node;
	if ((s->active_frm == curfrm) && (s->score + l->prob > stail.score)) {
	    stail.score = s->score + l->prob;
	    stail.hist = s->hist;
	}
    }
    
    if (stail.hist) {
	/* Reverse the best Viterbi path (back trace) so it is forward in time */
	nh = NULL;
	for (h = stail.hist; h; h = ph) {
	    ph = h->pred;
	    h->pred = nh;
	    nh = h;
	}
	
	/* Trace state, phone, and word segmentations */
	build_stseg (nh);
	build_phseg (nh);
	build_wdseg (nh);
    }
    
    *stseg_out = align_stseg;
    *phseg_out = align_phseg;
    *wdseg_out = align_wdseg;
    
    /* delete history list */
    while (hist_head) {
	h = hist_head->alloc_next;
	listelem_free ((char *) hist_head, sizeof(history_t));
	hist_head = h;
    }

    return (stail.hist ? 0 : -1);
}