57 #include <sphinxbase/err.h> 58 #include <sphinxbase/ckd_alloc.h> 59 #include <sphinxbase/strfuncs.h> 60 #include <sphinxbase/cmd_ln.h> 65 #include "fsg_search_internal.h" 66 #include "fsg_history.h" 67 #include "fsg_lextree.h" 71 #define __FSG_DBG_CHAN__ 0 91 fsg_search_init(cmd_ln_t *config,
99 fsgs = ckd_calloc(1,
sizeof(*fsgs));
100 ps_search_init(ps_search_base(fsgs), &fsg_funcs, config, acmod, dict, d2p);
105 if (fsgs->
hmmctx == NULL) {
106 ps_search_free(ps_search_base(fsgs));
111 fsgs->
history = fsg_history_init(NULL, dict);
115 fsgs->
fsgs = hash_table_new(5, HASH_CASE_YES);
120 = (int32) logmath_log(acmod->
lmath, cmd_ln_float64_r(config,
"-beam"))
123 = (int32) logmath_log(acmod->
lmath, cmd_ln_float64_r(config,
"-pbeam"))
126 = (int32) logmath_log(acmod->
lmath, cmd_ln_float64_r(config,
"-wbeam"))
130 fsgs->lw = cmd_ln_float32_r(config,
"-lw");
131 fsgs->pip = (int32) (logmath_log(acmod->
lmath, cmd_ln_float32_r(config,
"-pip"))
134 fsgs->
wip = (int32) (logmath_log(acmod->
lmath, cmd_ln_float32_r(config,
"-wip"))
139 if (cmd_ln_boolean_r(config,
"-bestpath"))
143 fsgs->
ascale = 1.0 / cmd_ln_float32_r(config,
"-ascale");
145 E_INFO(
"FSG(beam: %d, pbeam: %d, wbeam: %d; wip: %d, pip: %d)\n",
147 fsgs->
wip, fsgs->pip);
150 if ((path = cmd_ln_str_r(config,
"-fsg"))) {
153 if ((fsg = fsg_model_readfile(path, acmod->
lmath, fsgs->lw)) == NULL)
155 if (
fsg_set_add(fsgs, fsg_model_name(fsg), fsg) != fsg) {
161 if (fsg_search_reinit(ps_search_base(fsgs),
162 ps_search_dict(fsgs),
163 ps_search_dict2pid(fsgs)) < 0)
167 else if ((path = cmd_ln_str_r(config,
"-jsgf"))) {
172 if ((fsgs->
jsgf = jsgf_parse_file(path, NULL)) == NULL)
177 if ((toprule = cmd_ln_str_r(config,
"-toprule"))) {
179 anglerule = string_join(
"<", toprule,
">", NULL);
180 rule = jsgf_get_rule(fsgs->
jsgf, anglerule);
183 E_ERROR(
"Start rule %s not found\n", toprule);
189 jsgf_rule_iter_t *itor;
191 for (itor = jsgf_rule_iter(fsgs->
jsgf); itor;
192 itor = jsgf_rule_iter_next(itor)) {
193 rule = jsgf_rule_iter_rule(itor);
194 if (jsgf_rule_public(rule)) {
195 jsgf_rule_iter_free(itor);
200 E_ERROR(
"No public rules found in %s\n", path);
204 fsg = jsgf_build_fsg(fsgs->
jsgf, rule, acmod->
lmath, fsgs->lw);
205 if (
fsg_set_add(fsgs, fsg_model_name(fsg), fsg) != fsg) {
211 if (fsg_search_reinit(ps_search_base(fsgs),
212 ps_search_dict(fsgs),
213 ps_search_dict2pid(fsgs)) < 0)
217 return ps_search_base(fsgs);
220 fsg_search_free(ps_search_base(fsgs));
232 jsgf_grammar_free(fsgs->
jsgf);
235 fsg_history_reset(fsgs->
history);
236 fsg_history_set_fsg(fsgs->
history, NULL, NULL);
237 fsg_history_free(fsgs->
history);
240 for (itor = hash_table_iter(fsgs->
fsgs);
241 itor; itor = hash_table_iter_next(itor)) {
242 fsg_model_t *fsg = (fsg_model_t *) hash_entry_val(itor->ent);
245 hash_table_free(fsgs->
fsgs);
264 if (fsgs->
fsg == NULL)
272 ps_search_acmod(fsgs)->mdef,
276 fsg_history_set_fsg(fsgs->
history, fsgs->
fsg, dict);
283 fsg_search_add_silences(
fsg_search_t *fsgs, fsg_model_t *fsg)
289 dict = ps_search_dict(fsgs);
303 fsg_model_add_silence(fsg,
"<sil>", -1,
304 cmd_ln_float32_r(ps_search_config(fsgs),
"-silprob"));
307 for (wid = dict_filler_start(dict); wid < dict_filler_end(dict); ++wid) {
308 char const *word = dict_wordstr(dict, wid);
309 if (wid == dict_startwid(dict) || wid == dict_finishwid(dict))
311 fsg_model_add_silence(fsg, word, -1,
312 cmd_ln_float32_r(ps_search_config(fsgs),
"-fillprob"));
321 fsg_search_check_dict(
fsg_search_t *fsgs, fsg_model_t *fsg)
326 dict = ps_search_dict(fsgs);
327 for (i = 0; i < fsg_model_n_word(fsg); ++i) {
331 word = fsg_model_word_str(fsg, i);
334 E_ERROR(
"The word '%s' is missing in the dictionary\n", word);
343 fsg_search_add_altpron(
fsg_search_t *fsgs, fsg_model_t *fsg)
349 dict = ps_search_dict(fsgs);
352 n_word = fsg_model_n_word(fsg);
353 for (i = 0; i < n_word; ++i) {
357 word = fsg_model_word_str(fsg, i);
360 while ((wid = dict_nextalt(dict, wid)) !=
BAD_S3WID) {
361 n_alt += fsg_model_add_alt(fsg, word, dict_wordstr(dict, wid));
366 E_INFO(
"Added %d alternate word transitions\n", n_alt);
375 if (hash_table_lookup(fsgs->
fsgs, name, &val) < 0)
377 return (fsg_model_t *)val;
384 name = fsg_model_name(fsg);
386 if (!fsg_search_check_dict(fsgs, fsg))
390 if (cmd_ln_boolean_r(ps_search_config(fsgs),
"-fsgusefiller")
391 && !fsg_model_has_sil(fsg))
392 fsg_search_add_silences(fsgs, fsg);
393 if (cmd_ln_boolean_r(ps_search_config(fsgs),
"-fsgusealtpron")
394 && !fsg_model_has_alt(fsg))
395 fsg_search_add_altpron(fsgs, fsg);
397 return (fsg_model_t *)hash_table_enter(fsgs->
fsgs, name, fsg);
408 if (hash_table_lookup(fsgs->
fsgs, key, &val) < 0) {
409 E_ERROR(
"FSG `%s' to be deleted not found\n", key);
415 hash_table_delete(fsgs->
fsgs, key);
417 if (fsgs->
fsg == oldfsg) {
420 fsg_history_set_fsg(fsgs->
history, NULL, NULL);
434 for (itor = hash_table_iter(fsgs->
fsgs);
435 itor; itor = hash_table_iter_next(itor)) {
438 oldfsg = (fsg_model_t *) hash_entry_val(itor->ent);
440 key = hash_entry_key(itor->ent);
441 hash_table_iter_free(itor);
446 E_WARN(
"FSG '%s' to be deleted not found\n", fsg_model_name(fsg));
461 E_ERROR(
"FSG '%s' not known; cannot make it current\n", name);
471 return hash_table_iter(fsgs->
fsgs);
477 return hash_table_iter_next(itor);
483 return ((fsg_model_t *)itor->ent->val);
489 hash_table_iter_free(itor);
501 for (gn = fsgs->
pnode_active; gn; gn = gnode_next(gn)) {
503 hmm = fsg_pnode_hmmptr(pnode);
504 assert(hmm_frame(hmm) == fsgs->
frame);
526 E_ERROR(
"Frame %d: No active HMM!!\n", fsgs->
frame);
530 for (n = 0, gn = fsgs->
pnode_active; gn; gn = gnode_next(gn), n++) {
534 hmm = fsg_pnode_hmmptr(pnode);
535 assert(hmm_frame(hmm) == fsgs->
frame);
538 E_INFO(
"pnode(%08x) active @frm %5d\n", (int32) pnode,
544 E_INFO(
"pnode(%08x) after eval @frm %5d\n",
545 (int32) pnode, fsgs->
frame);
554 E_INFO(
"[%5d] %6d HMM; bestscr: %11d\n", fsgs->
frame, n, bestscore);
559 maxhmmpf = cmd_ln_int32_r(ps_search_config(fsgs),
"-maxhmmpf");
560 if (maxhmmpf != -1 && n > maxhmmpf) {
582 if (n > fsg_lextree_n_pnode(fsgs->
lextree))
583 E_FATAL(
"PANIC! Frame %d: #HMM evaluated(%d) > #PNodes(%d)\n",
595 int32 newscore, thresh, nf;
598 assert(!fsg_pnode_leaf(pnode));
600 nf = fsgs->
frame + 1;
603 hmm = fsg_pnode_hmmptr(pnode);
605 for (child = fsg_pnode_succ(pnode);
606 child; child = fsg_pnode_sibling(child)) {
607 newscore = hmm_out_score(hmm) + child->logs2prob;
610 && (newscore
BETTER_THAN hmm_in_score(&child->hmm))) {
612 if (hmm_frame(&child->hmm) < nf) {
619 hmm_enter(&child->hmm, newscore, hmm_out_history(hmm), nf);
634 assert(fsg_pnode_leaf(pnode));
636 hmm = fsg_pnode_hmmptr(pnode);
637 fl = fsg_pnode_fsglink(pnode);
640 wid = fsg_link_wid(fl);
644 E_INFO(
"[%5d] Exit(%08x) %10d(score) %5d(pred)\n",
645 fsgs->
frame, (int32) pnode,
646 hmm_out_score(hmm), hmm_out_history(hmm));
653 if (fsg_model_is_filler(fsgs->
fsg, wid)
655 || (dict_is_single_phone(ps_search_dict(fsgs),
657 fsg_model_word_str(fsgs->
fsg, wid))))) {
662 fsg_history_entry_add(fsgs->
history,
666 hmm_out_history(hmm),
667 pnode->ci_ext, ctxt);
672 fsg_history_entry_add(fsgs->
history,
676 hmm_out_history(hmm),
677 pnode->ci_ext, pnode->ctxt);
694 int32 thresh, word_thresh, phone_thresh;
699 phone_thresh = fsgs->
bestscore + fsgs->pbeam;
702 for (gn = fsgs->
pnode_active; gn; gn = gnode_next(gn)) {
704 hmm = fsg_pnode_hmmptr(pnode);
706 if (hmm_bestscore(hmm) >= thresh) {
708 if (hmm_frame(hmm) == fsgs->
frame) {
709 hmm_frame(hmm) = fsgs->
frame + 1;
715 assert(hmm_frame(hmm) == fsgs->
frame + 1);
718 if (!fsg_pnode_leaf(pnode)) {
719 if (hmm_out_score(hmm) >= phone_thresh) {
721 fsg_search_pnode_trans(fsgs, pnode);
725 if (hmm_out_score(hmm) >= word_thresh) {
727 fsg_search_pnode_exit(fsgs, pnode);
741 int32 bpidx, n_entries, thresh, newscore;
750 n_entries = fsg_history_n_entries(fsgs->
history);
752 for (bpidx = fsgs->
bpidx_start; bpidx < n_entries; bpidx++) {
754 hist_entry = fsg_history_entry_get(fsgs->
history, bpidx);
756 l = fsg_hist_entry_fsglink(hist_entry);
759 s = l ? fsg_link_to_state(l) : fsg_model_start_state(fsg);
767 for (itor = fsg_model_arcs(fsg, s); itor;
768 itor = fsg_arciter_next(itor)) {
769 fsg_link_t *l = fsg_arciter_get(itor);
772 if (fsg_link_wid(l) != -1)
775 fsg_hist_entry_score(hist_entry) +
778 if (newscore >= thresh) {
779 fsg_history_entry_add(fsgs->
history, l,
780 fsg_hist_entry_frame(hist_entry),
783 fsg_hist_entry_lc(hist_entry),
784 fsg_hist_entry_rc(hist_entry));
798 int32 bpidx, n_entries;
801 int32 score, newscore, thresh, nf, d;
805 n_entries = fsg_history_n_entries(fsgs->
history);
808 nf = fsgs->
frame + 1;
810 for (bpidx = fsgs->
bpidx_start; bpidx < n_entries; bpidx++) {
811 hist_entry = fsg_history_entry_get(fsgs->
history, bpidx);
813 score = fsg_hist_entry_score(hist_entry);
814 assert(fsgs->
frame == fsg_hist_entry_frame(hist_entry));
816 l = fsg_hist_entry_fsglink(hist_entry);
819 d = l ? fsg_link_to_state(l) : fsg_model_start_state(fsgs->
822 lc = fsg_hist_entry_lc(hist_entry);
825 for (root = fsg_lextree_root(fsgs->
lextree, d);
826 root; root = root->sibling) {
829 if ((root->ctxt.bv[lc >> 5] & (1 << (lc & 0x001f))) &&
830 (hist_entry->rc.bv[rc >> 5] & (1 << (rc & 0x001f)))) {
838 newscore = score + root->logs2prob;
841 && (newscore
BETTER_THAN hmm_in_score(&root->hmm))) {
842 if (hmm_frame(&root->hmm) < nf) {
849 (
"[%5d] WordTrans bpidx[%d] -> pnode[%08x] (activated)\n",
850 fsgs->
frame, bpidx, (int32) root);
856 (
"[%5d] WordTrans bpidx[%d] -> pnode[%08x]\n",
857 fsgs->
frame, bpidx, (int32) root);
861 hmm_enter(&root->hmm, newscore, bpidx, nf);
870 fsg_search_step(
ps_search_t *search,
int frame_idx)
881 fsg_search_sen_active(fsgs);
891 fsg_search_hmm_eval(fsgs);
898 fsg_search_hmm_prune_prop(fsgs);
899 fsg_history_end_frame(fsgs->
history);
905 fsg_search_null_prop(fsgs);
906 fsg_history_end_frame(fsgs->
history);
912 fsg_search_word_trans(fsgs);
920 for (gn = fsgs->
pnode_active; gn; gn = gnode_next(gn)) {
922 hmm = fsg_pnode_hmmptr(pnode);
924 if (hmm_frame(hmm) == fsgs->
frame) {
929 assert(hmm_frame(hmm) == (fsgs->
frame + 1));
971 fsg_history_reset(fsgs->
history);
972 fsg_history_utt_start(fsgs->
history);
981 fsg_history_entry_add(fsgs->
history,
982 NULL, -1, 0, -1, silcipid, ctxt);
986 fsg_search_null_prop(fsgs);
989 fsg_search_word_trans(fsgs);
1015 for (gn = fsgs->
pnode_active; gn; gn = gnode_next(gn)) {
1031 n_hist = fsg_history_n_entries(fsgs->
history);
1033 (
"%d frames, %d HMMs (%d/fr), %d senones (%d/fr), %d history entries (%d/fr)\n\n",
1038 n_hist, (fsgs->
frame > 0) ? n_hist / fsgs->
frame : 0);
1044 fsg_search_find_exit(
fsg_search_t *fsgs,
int frame_idx,
int final, int32 *out_score, int32* out_is_final)
1048 int bpidx, frm, last_frm, besthist;
1051 if (frame_idx == -1)
1052 frame_idx = fsgs->
frame - 1;
1053 last_frm = frm = frame_idx;
1056 bpidx = fsg_history_n_entries(fsgs->
history) - 1;
1058 hist_entry = fsg_history_entry_get(fsgs->
history, bpidx);
1059 if (fsg_hist_entry_frame(hist_entry) <= frame_idx) {
1060 frm = last_frm = fsg_hist_entry_frame(hist_entry);
1070 bestscore = INT_MIN;
1073 while (frm == last_frm) {
1077 fl = fsg_hist_entry_fsglink(hist_entry);
1078 score = fsg_hist_entry_score(hist_entry);
1084 if (score == bestscore && fsg_link_to_state(fl) == fsg_model_final_state(fsg)) {
1089 || fsg_link_to_state(fl) == fsg_model_final_state(fsg)) {
1098 hist_entry = fsg_history_entry_get(fsgs->
history, bpidx);
1099 frm = fsg_hist_entry_frame(hist_entry);
1103 if (besthist == -1) {
1104 E_ERROR(
"Final result does not match the grammar in frame %d\n", frame_idx);
1110 *out_score = bestscore;
1113 hist_entry = fsg_history_entry_get(fsgs->
history, besthist);
1114 fl = fsg_hist_entry_fsglink(hist_entry);
1115 *out_is_final = (fsg_link_to_state(fl) == fsg_model_final_state(fsg));
1122 fsg_search_bestpath(
ps_search_t *search, int32 *out_score,
int backward)
1133 if (search->
post == 0)
1142 fsg_search_hyp(
ps_search_t *search, int32 *out_score, int32 *out_is_final)
1145 dict_t *dict = ps_search_dict(search);
1151 bpidx = fsg_search_find_exit(fsgs, fsgs->
frame, fsgs->
final, out_score, out_is_final);
1161 if ((dag = fsg_search_lattice(search)) == NULL) {
1162 E_WARN(
"Failed to obtain the lattice while bestpath enabled\n");
1165 if ((link = fsg_search_bestpath(search, out_score, FALSE)) == NULL) {
1166 E_WARN(
"Failed to find the bestpath in a lattice\n");
1176 fsg_link_t *fl = fsg_hist_entry_fsglink(hist_entry);
1177 char const *baseword;
1180 bp = fsg_hist_entry_pred(hist_entry);
1181 wid = fsg_link_wid(fl);
1182 if (wid < 0 || fsg_model_is_filler(fsgs->
fsg, wid))
1184 baseword = dict_basestr(dict,
1186 fsg_model_word_str(fsgs->
fsg, wid)));
1187 len += strlen(baseword) + 1;
1195 search->
hyp_str = ckd_calloc(1, len);
1198 c = search->
hyp_str + len - 1;
1201 fsg_link_t *fl = fsg_hist_entry_fsglink(hist_entry);
1202 char const *baseword;
1205 bp = fsg_hist_entry_pred(hist_entry);
1206 wid = fsg_link_wid(fl);
1207 if (wid < 0 || fsg_model_is_filler(fsgs->
fsg, wid))
1209 baseword = dict_basestr(dict,
1211 fsg_model_word_str(fsgs->
fsg, wid)));
1212 len = strlen(baseword);
1214 memcpy(c, baseword, len);
1231 if ((bp = fsg_hist_entry_pred(hist_entry)) >= 0)
1232 ph = fsg_history_entry_get(fsgs->
history, bp);
1233 seg->
word = fsg_model_word_str(fsgs->
fsg, hist_entry->fsglink->wid);
1234 seg->
ef = fsg_hist_entry_frame(hist_entry);
1235 seg->
sf = ph ? fsg_hist_entry_frame(ph) + 1 : 0;
1237 if (seg->
sf > seg->
ef) seg->
sf = seg->
ef;
1241 seg->
lscr = hist_entry->fsglink->logs2prob;
1244 seg->
ascr = hist_entry->score - ph->score - seg->
lscr;
1247 seg->
ascr = hist_entry->score - seg->
lscr;
1255 ckd_free(itor->
hist);
1269 fsg_seg_bp2itor(seg, itor->
hist[itor->
cur]);
1279 fsg_search_seg_iter(
ps_search_t *search, int32 *out_score)
1285 bpidx = fsg_search_find_exit(fsgs, fsgs->
frame, fsgs->
final, out_score, NULL);
1295 if ((dag = fsg_search_lattice(search)) == NULL)
1297 if ((link = fsg_search_bestpath(search, out_score, TRUE)) == NULL)
1306 itor = ckd_calloc(1,
sizeof(*itor));
1307 itor->
base.
vt = &fsg_segfuncs;
1314 bp = fsg_hist_entry_pred(hist_entry);
1326 itor->
hist[cur] = hist_entry;
1327 bp = fsg_hist_entry_pred(hist_entry);
1332 fsg_seg_bp2itor((
ps_seg_t *)itor, itor->hist[0]);
1347 if ((dag = fsg_search_lattice(search)) == NULL)
1349 if ((link = fsg_search_bestpath(search, NULL, TRUE)) == NULL)
1351 return search->
post;
1360 find_node(
ps_lattice_t *dag, fsg_model_t *fsg,
int sf, int32 wid, int32 node_id)
1364 for (node = dag->
nodes; node; node = node->
next)
1365 if ((node->
sf == sf) && (node->
wid == wid) && (node->
node_id == node_id))
1371 new_node(
ps_lattice_t *dag, fsg_model_t *fsg,
int sf,
int ef, int32 wid, int32 node_id, int32 ascr)
1375 node = find_node(dag, fsg, sf, wid, node_id);
1379 if (node->
lef == -1 || node->
lef < ef)
1381 if (node->
fef == -1 || node->
fef > ef)
1392 node->
fef = node->
lef = ef;
1411 glist_t start = NULL;
1415 for (node = dag->
nodes; node; node = node->
next) {
1416 if (node->
sf == 0 && node->
exits) {
1417 E_INFO(
"Start node %s.%d:%d:%d\n",
1418 fsg_model_word_str(fsgs->
fsg, node->
wid),
1420 start = glist_add_ptr(start, node);
1429 node = gnode_ptr(start);
1435 wid = fsg_model_word_add(fsgs->
fsg,
"<s>");
1436 if (fsgs->
fsg->silwords)
1437 bitvec_set(fsgs->
fsg->silwords, wid);
1438 node = new_node(dag, fsgs->
fsg, 0, 0, wid, -1, 0);
1439 for (st = start; st; st = gnode_next(st))
1454 for (node = dag->
nodes; node; node = node->
next) {
1456 E_INFO(
"End node %s.%d:%d:%d (%d)\n",
1457 fsg_model_word_str(fsgs->
fsg, node->
wid),
1459 end = glist_add_ptr(end, node);
1465 node = gnode_ptr(end);
1467 else if (nend == 0) {
1473 for (node = dag->
nodes; node; node = node->
next) {
1481 E_INFO(
"End node %s.%d:%d:%d (%d)\n",
1482 fsg_model_word_str(fsgs->
fsg, node->
wid),
1491 wid = fsg_model_word_add(fsgs->
fsg,
"</s>");
1492 if (fsgs->
fsg->silwords)
1493 bitvec_set(fsgs->
fsg->silwords, wid);
1494 node = new_node(dag, fsgs->
fsg, fsgs->
frame, fsgs->
frame, wid, -1, 0);
1497 for (st = end; st; st = gnode_next(st)) {
1513 q = glist_add_ptr(NULL, end);
1519 q = gnode_free(q, NULL);
1521 for (x = node->
entries; x; x = x->next) {
1525 q = glist_add_ptr(q, next);
1567 n = fsg_history_n_entries(fsgs->
history);
1568 for (i = 0; i < n; ++i) {
1574 if (fh->fsglink == NULL || fh->fsglink->wid == -1)
1587 ascr = fh->score - pfh->score;
1588 sf = pfh->frame + 1;
1601 new_node(dag, fsg, sf, fh->frame, fh->fsglink->wid, fsg_link_to_state(fh->fsglink), ascr);
1607 n = fsg_history_n_entries(fsgs->
history);
1608 for (i = 0; i < n; ++i) {
1610 fsg_arciter_t *itor;
1616 if (fh->fsglink == NULL || fh->fsglink->wid == -1)
1622 sf = pfh->frame + 1;
1623 ascr = fh->score - pfh->score;
1629 src = find_node(dag, fsg, sf, fh->fsglink->wid, fsg_link_to_state(fh->fsglink));
1632 for (itor = fsg_model_arcs(fsg, fsg_link_to_state(fh->fsglink));
1633 itor; itor = fsg_arciter_next(itor)) {
1634 fsg_link_t *link = fsg_arciter_get(itor);
1637 if (link->wid >= 0) {
1642 if ((dest = find_node(dag, fsg, sf, link->wid, fsg_link_to_state(link))) != NULL)
1650 fsg_arciter_t *itor2;
1653 for (itor2 = fsg_model_arcs(fsg, fsg_link_to_state(link));
1654 itor2; itor2 = fsg_arciter_next(itor2)) {
1655 fsg_link_t *link = fsg_arciter_get(itor2);
1657 if (link->wid == -1)
1660 if ((dest = find_node(dag, fsg, sf, link->wid, fsg_link_to_state(link))) != NULL) {
1670 if ((dag->
start = find_start_node(fsgs, dag)) == NULL) {
1671 E_WARN(
"Failed to find the start node\n");
1674 if ((dag->
end = find_end_node(fsgs, dag)) == NULL) {
1675 E_WARN(
"Failed to find the end node\n");
1680 E_INFO(
"lattice start node %s.%d end node %s.%d\n",
1682 fsg_model_word_str(fsg, dag->
end->
wid), dag->
end->
sf);
1688 for (node = dag->
nodes; node; node = node->
next) {
1690 fsg_model_word_str(fsg, node->
wid));
1700 mark_reachable(dag, dag->
end);
1704 int32 silpen, fillpen;
1706 silpen = (int32)(logmath_log(fsg->lmath,
1707 cmd_ln_float32_r(ps_search_config(fsgs),
"-silprob"))
1710 fillpen = (int32)(logmath_log(fsg->lmath,
1711 cmd_ln_float32_r(ps_search_config(fsgs),
"-fillprob"))
void fsg_lextree_free(fsg_lextree_t *lextree)
Free lextrees for an FSG.
glist_t pnode_active_next
Those activated for the next frame.
Implementation of FSG search (and "FSG set") structure.
Internal implementation of PocketSphinx decoder.
POCKETSPHINX_EXPORT fsg_model_t * fsg_set_select(fsg_set_t *fsgs, const char *name)
Switch to a new FSG (identified by its string name).
Base structure for search module.
POCKETSPHINX_EXPORT fsg_set_iter_t * fsg_set_iter_next(fsg_set_iter_t *itor)
Advance an iterator to the next grammar in the set.
ps_seg_t * ps_lattice_seg_iter(ps_lattice_t *dag, ps_latlink_t *link, float32 lwf)
Get hypothesis segmentation iterator after bestpath search.
int16 cur
Current position in hist.
POCKETSPHINX_EXPORT s3wid_t dict_wordid(dict_t *d, const char *word)
Return word id for given word string if present.
fsg_model_t * fsg
Currently active FSG; NULL if none.
int32 wbeam_orig
Pruning threshold for word exit.
void fsg_pnode_add_all_ctxt(fsg_pnode_ctxt_t *ctxt)
Set all flags on in the given context bitvector.
void ps_search_base_reinit(ps_search_t *search, dict_t *dict, dict2pid_t *d2p)
Re-initialize base structure with new dictionary.
int n_senone_active
Number of active GMMs.
acmod_t * acmod
Acoustic model.
Segmentation "iterator" for FSG history.
ps_seg_t base
Base structure.
An individual HMM among the HMM search space.
float32 beam_factor
Dynamic/adaptive factor (<=1) applied to above beams to determine actual effective beams...
ps_latnode_t * start
Starting node.
uint8 *** tp
The transition matrices; kept in the same scale as acoustic scores; tp[tmatid][from-state][to-state]...
ps_segfuncs_t * vt
V-table of seg methods.
logmath_t * lmath
Log-math computation.
hash_iter_t fsg_set_iter_t
Iterator over finite-state grammars.
int bin_mdef_ciphone_id(bin_mdef_t *m, const char *ciphone)
Context-independent phone lookup.
struct fsg_history_s * history
For storing the Viterbi search history.
uint16 ** sseq
Unique senone sequences (2D array built at load time)
int32 lscr
Language model score.
int32 n_words
Number of words known to search (may be less than in the dictionary)
int32 wbeam
Effective beams after applying beam_factor.
void acmod_activate_hmm(acmod_t *acmod, hmm_t *hmm)
Activate senones associated with an HMM.
float32 ascale
Acoustic score scale for posterior probabilities.
ps_search_t * search
Search (if generated by search).
#define BAD_S3WID
Dictionary word id.
struct ps_latnode_s * from
From node.
frame_idx_t n_frames
Number of frames for this utterance.
POCKETSPHINX_EXPORT fsg_model_t * fsg_set_remove(fsg_set_t *fsgs, fsg_model_t *wfsg)
Delete the given FSG from the known collection.
POCKETSPHINX_EXPORT fsg_model_t * fsg_set_add(fsg_set_t *fsgs, char const *name, fsg_model_t *wfsg)
Add the given FSG to the collection of FSGs known to this search object.
jsgf_t * jsgf
Active JSGF grammar file.
Word graph search implementation.
int32 n_hmm_eval
Total HMMs evaluated this utt.
ps_latnode_t * nodes
List of all nodes.
void ps_search_init(ps_search_t *search, ps_searchfuncs_t *vt, cmd_ln_t *config, acmod_t *acmod, dict_t *dict, dict2pid_t *d2p)
Initialize base structure.
listelem_alloc_t * latnode_alloc
Node allocator for this DAG.
int32 wip
Language weights.
int32 best_exit
Best exit score (used for final nodes only)
hash_table_t * fsgs
Table of all FSGs loaded.
int16 n_nodes
Number of nodes in this lattice.
int32 prob
Log posterior probability.
latlink_list_t * entries
Links into this node.
POCKETSPHINX_EXPORT int32 ps_lattice_posterior(ps_lattice_t *dag, ngram_model_t *lmset, float32 ascale)
Calculate link posterior probabilities on a word graph.
hmm_context_t * hmmctx
HMM context.
char const * word
Word string (pointer into dictionary hash)
ps_search_t * search
Search object from whence this came.
int32 final_node_ascr
Acoustic score of implicit link exiting final node.
fsg_hist_entry_t ** hist
Sequence of history entries.
int32 hmm_vit_eval(hmm_t *hmm)
Viterbi evaluation of given HMM.
void fsg_psubtree_pnode_deactivate(fsg_pnode_t *pnode)
Mark the given pnode as inactive (for search).
uint8 compallsen
Compute all senones?
hmm_context_t * hmm_context_init(int32 n_emit_state, uint8 **const *tp, int16 const *senscore, uint16 *const *sseq)
Create an HMM context.
void ps_lattice_delete_unreachable(ps_lattice_t *dag)
Remove nodes marked as unreachable.
ps_latnode_t * end
Ending node.
frame_idx_t sf
Start frame.
POCKETSPHINX_EXPORT ps_latlink_t * ps_lattice_bestpath(ps_lattice_t *dag, ngram_model_t *lmset, float32 lwf, float32 ascale)
Do N-Gram based best-path search on a word graph.
int32 beam_orig
Global pruning threshold.
POCKETSPHINX_EXPORT fsg_set_iter_t * fsg_set_iter(fsg_set_t *fsgs)
Get an iterator over all finite-state grammars in a set.
latlink_list_t * exits
Links out of this node.
#define WORST_SCORE
Large "bad" score.
tmat_t * tmat
Transition matrices.
int32 ascr
Acoustic score.
int32 path_scr
Best path score from root of DAG.
void hmm_enter(hmm_t *h, int32 score, int32 histid, int frame)
Enter an HMM with the given path score and history ID.
void acmod_clear_active(acmod_t *acmod)
Clear set of active senones.
int32 wid
Dictionary word id.
int32 node_id
Node from fsg model, used to map lattice back to model.
int32 pbeam_orig
Pruning threshold for phone transition.
#define hmm_context_set_senscore(ctx, senscr)
Change the senone score array for a context.
void hmm_dump(hmm_t *h, FILE *fp)
For debugging, dump the whole HMM out.
uint8 final
Decoding is finished for this utterance.
#define SENSCR_SHIFT
Shift count for senone scores.
POCKETSPHINX_EXPORT fsg_model_t * fsg_set_remove_byname(fsg_set_t *fsgs, char const *name)
Like fsg_set_del_fsg(), but identifies the FSG by its name.
a structure for a dictionary.
char const * ps_lattice_hyp(ps_lattice_t *dag, ps_latlink_t *link)
Get hypothesis string after bestpath search.
Word graph structure used in bestpath/nbest search.
int32 bestscore
For beam pruning.
int32 bpidx_start
First history entry index this frame.
POCKETSPHINX_EXPORT fsg_model_t * fsg_set_iter_fsg(fsg_set_iter_t *itor)
Get the current rule in an FSG iterator.
POCKETSPHINX_EXPORT fsg_model_t * fsg_set_get_fsg(fsg_set_t *fsgs, char const *name)
Lookup the FSG associated with the given name.
int32 post
Utterance posterior probability.
char * hyp_str
Current hypothesis string.
fsg_lextree_t * fsg_lextree_init(fsg_model_t *fsg, dict_t *dict, dict2pid_t *d2p, bin_mdef_t *mdef, hmm_context_t *ctx, int32 wip, int32 pip)
Create, initialize, and return a new phonetic lextree for the given FSG.
#define BETTER_THAN
Is one score better than another?
dict_t * dict
Pronunciation dictionary.
int32 fef
First end frame.
uint8 bestpath
Whether to run bestpath search and confidence annotation at end.
int32 lback
Language model backoff.
int32 n_sen_eval
Total senones evaluated this utt.
int32 basewid
Dictionary base word id.
glist_t pnode_active
Those active in this frame.
ps_lattice_t * ps_lattice_init_search(ps_search_t *search, int n_frame)
Construct an empty word graph with reference to a search structure.
void hmm_context_free(hmm_context_t *ctx)
Free an HMM context.
Linked list of DAG link pointers.
int16 n_hist
Number of history entries.
bin_mdef_t * mdef
Model definition.
ps_latlink_t * last_link
Final link in best path.
struct ps_latnode_s * next
Next node in DAG (no ordering implied)
void ps_lattice_bypass_fillers(ps_lattice_t *dag, int32 silpen, int32 fillpen)
Bypass filler words.
V-table for search algorithm.
frame_idx_t frame
Current frame.
ps_lattice_t * dag
Current hypothesis word graph.
Base structure for hypothesis segmentation iterator.
struct fsg_lextree_s * lextree
Lextree structure for the currently active FSG.
#define dict_size(d)
Packaged macro access to dictionary members.
POCKETSPHINX_EXPORT int ps_lattice_free(ps_lattice_t *dag)
Free a lattice.
Acoustic model structure.
float32 lwf
Language weight factor (for second-pass searches)
Building composite triphone (as well as word internal triphones) with the dictionary.
void ps_search_deinit(ps_search_t *search)
De-initialize base structure.
POCKETSPHINX_EXPORT void ps_lattice_link(ps_lattice_t *dag, ps_latnode_t *from, ps_latnode_t *to, int32 score, int32 ef)
Create a directed link between "from" and "to" nodes, but if a link already exists, choose one with the best link_scr.
frame_idx_t sf
Start frame.
int16 const * acmod_score(acmod_t *acmod, int *inout_frame_idx)
Score one frame of data.
POCKETSPHINX_EXPORT void fsg_set_iter_free(fsg_set_iter_t *itor)
Free an FSG iterator (if the end hasn't been reached).