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; }
void fsg_model_trans_add(fsg_model_t * fsg, int32 from, int32 to, int32 logp, int32 wid) { fsg_link_t *link; glist_t gl; gnode_t *gn; if (fsg->trans[from].trans == NULL) fsg->trans[from].trans = hash_table_new(5, HASH_CASE_YES); /* Check for duplicate link (i.e., link already exists with label=wid) */ for (gn = gl = fsg_model_trans(fsg, from, to); gn; gn = gnode_next(gn)) { link = (fsg_link_t *) gnode_ptr(gn); if (link->wid == wid) { if (link->logs2prob < logp) link->logs2prob = logp; return; } } /* Create transition object */ link = listelem_malloc(fsg->link_alloc); link->from_state = from; link->to_state = to; link->logs2prob = logp; link->wid = wid; /* Add it to the list of transitions and update the hash table */ gl = glist_add_ptr(gl, (void *) link); hash_table_replace_bkey(fsg->trans[from].trans, (char const *) &link->to_state, sizeof(link->to_state), gl); }
int fsg_model_add_alt(fsg_model_t * fsg, char const *baseword, char const *altword) { int i, basewid, altwid; int ntrans; /* FIXME: This will get slow, eventually... */ for (basewid = 0; basewid < fsg->n_word; ++basewid) if (0 == strcmp(fsg->vocab[basewid], baseword)) break; if (basewid == fsg->n_word) { E_ERROR("Base word %s not present in FSG vocabulary!\n", baseword); return -1; } altwid = fsg_model_word_add(fsg, altword); if (fsg->altwords == NULL) fsg->altwords = bitvec_alloc(fsg->n_word_alloc); bitvec_set(fsg->altwords, altwid); E_DEBUG(2,("Adding alternate word transitions (%s,%s) to FSG\n", baseword, altword)); /* Look for all transitions involving baseword and duplicate them. */ /* FIXME: This will also get slow, eventually... */ ntrans = 0; for (i = 0; i < fsg->n_state; ++i) { hash_iter_t *itor; if (fsg->trans[i].trans == NULL) continue; for (itor = hash_table_iter(fsg->trans[i].trans); itor; itor = hash_table_iter_next(itor)) { glist_t trans; gnode_t *gn; trans = hash_entry_val(itor->ent); for (gn = trans; gn; gn = gnode_next(gn)) { fsg_link_t *fl = gnode_ptr(gn); if (fl->wid == basewid) { fsg_link_t *link; /* Create transition object */ link = listelem_malloc(fsg->link_alloc); link->from_state = fl->from_state; link->to_state = fl->to_state; link->logs2prob = fl->logs2prob; /* FIXME!!!??? */ link->wid = altwid; trans = glist_add_ptr(trans, (void *) link); ++ntrans; } } hash_entry_val(itor->ent) = trans; } } E_DEBUG(2,("Added %d alternate word transitions\n", ntrans)); return ntrans; }
int32 fsg_model_tag_trans_add(fsg_model_t * fsg, int32 from, int32 to, int32 logp, int32 wid) { fsg_link_t *link, *link2; /* Check for transition probability */ if (logp > 0) { E_FATAL("Null transition prob must be <= 1.0 (state %d -> %d)\n", from, to); } /* Self-loop null transitions (with prob <= 1.0) are redundant */ if (from == to) return -1; if (fsg->trans[from].null_trans == NULL) fsg->trans[from].null_trans = hash_table_new(5, HASH_CASE_YES); /* Check for a duplicate link; if found, keep the higher prob */ link = fsg_model_null_trans(fsg, from, to); if (link) { if (link->logs2prob < logp) { link->logs2prob = logp; return 0; } else return -1; } /* Create null transition object */ link = listelem_malloc(fsg->link_alloc); link->from_state = from; link->to_state = to; link->logs2prob = logp; link->wid = -1; link2 = (fsg_link_t *) hash_table_enter_bkey(fsg->trans[from].null_trans, (char const *) &link->to_state, sizeof(link->to_state), link); assert(link == link2); return 1; }
static void load_tginfo(NGRAM_MODEL_TYPE *model, int32 lw1, int32 lw2) { int32 i, n, b, t; bigram_t *bg; tginfo_t *tginfo; /* First allocate space for tg information for bg lw1,lw2 */ tginfo = (tginfo_t *) listelem_malloc(model->lm3g.le); tginfo->w1 = lw1; tginfo->tg = NULL; tginfo->next = model->lm3g.tginfo[lw2]; model->lm3g.tginfo[lw2] = tginfo; /* Locate bigram lw1,lw2 */ b = model->lm3g.unigrams[lw1].bigrams; n = model->lm3g.unigrams[lw1 + 1].bigrams - b; bg = model->lm3g.bigrams + b; if ((n > 0) && ((i = find_bg(bg, n, lw2)) >= 0)) { tginfo->bowt = model->lm3g.bo_wt2[bg[i].bo_wt2].l; /* Find t = Absolute first trigram index for bigram lw1,lw2 */ b += i; /* b = Absolute index of bigram lw1,lw2 on disk */ t = FIRST_TG(model, b); tginfo->tg = model->lm3g.trigrams + t; /* Find #tg for bigram w1,w2 */ tginfo->n_tg = FIRST_TG(model, b + 1) - t; } else { /* No bigram w1,w2 */ tginfo->bowt = 0; tginfo->n_tg = 0; } }
/** * Build HMM network for one utterance of fwdflat search. */ static void build_fwdflat_chan(ngram_search_t *ngs) { int32 i, wid, p; root_chan_t *rhmm; chan_t *hmm, *prevhmm; dict_t *dict; dict2pid_t *d2p; dict = ps_search_dict(ngs); d2p = ps_search_dict2pid(ngs); /* Build word HMMs for each word in the lattice. */ for (i = 0; ngs->fwdflat_wordlist[i] >= 0; i++) { wid = ngs->fwdflat_wordlist[i]; /* Single-phone words are permanently allocated */ if (dict_is_single_phone(dict, wid)) continue; assert(ngs->word_chan[wid] == NULL); /* Multiplex root HMM for first phone (one root per word, flat * lexicon). diphone is irrelevant here, for the time being, * at least. */ rhmm = listelem_malloc(ngs->root_chan_alloc); rhmm->ci2phone = dict_second_phone(dict, wid); rhmm->ciphone = dict_first_phone(dict, wid); rhmm->next = NULL; hmm_init(ngs->hmmctx, &rhmm->hmm, TRUE, bin_mdef_pid2ssid(ps_search_acmod(ngs)->mdef, rhmm->ciphone), bin_mdef_pid2tmatid(ps_search_acmod(ngs)->mdef, rhmm->ciphone)); /* HMMs for word-internal phones */ prevhmm = NULL; for (p = 1; p < dict_pronlen(dict, wid) - 1; p++) { hmm = listelem_malloc(ngs->chan_alloc); hmm->ciphone = dict_pron(dict, wid, p); hmm->info.rc_id = (p == dict_pronlen(dict, wid) - 1) ? 0 : -1; hmm->next = NULL; hmm_init(ngs->hmmctx, &hmm->hmm, FALSE, dict2pid_internal(d2p,wid,p), bin_mdef_pid2tmatid(ps_search_acmod(ngs)->mdef, hmm->ciphone)); if (prevhmm) prevhmm->next = hmm; else rhmm->next = hmm; prevhmm = hmm; } /* Right-context phones */ ngram_search_alloc_all_rc(ngs, wid); /* Link in just allocated right-context phones */ if (prevhmm) prevhmm->next = ngs->word_chan[wid]; else rhmm->next = ngs->word_chan[wid]; ngs->word_chan[wid] = (chan_t *) rhmm; } }
/** * 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); }