48 #include <sphinxbase/ckd_alloc.h>
49 #include <sphinxbase/listelem_alloc.h>
50 #include <sphinxbase/strfuncs.h>
51 #include <sphinxbase/err.h>
52 #include <sphinxbase/pio.h>
66 int32 score, int32 ef)
71 for (fwdlink = from->
exits; fwdlink; fwdlink = fwdlink->next)
72 if (fwdlink->link->
to == to)
75 if (fwdlink == NULL) {
88 link->best_prev = NULL;
90 fwdlink->link = revlink->link = link;
91 fwdlink->next = from->
exits;
92 from->
exits = fwdlink;
99 fwdlink->link->
ascr = score;
100 fwdlink->link->
ef = ef;
110 for (node = dag->
nodes; node; node = node->
next) {
113 for (linklist = node->
entries; linklist; linklist = linklist->next)
124 for (x = node->
exits; x; x = next_x) {
126 x->link->
from = NULL;
129 for (x = node->
entries; x; x = next_x) {
144 for (x = node->
exits; x; x = next_x) {
146 if (x->link->
to == NULL) {
148 prev_x->next = next_x;
150 node->
exits = next_x;
158 for (x = node->
entries; x; x = next_x) {
160 if (x->link->
from == NULL) {
162 prev_x->next = next_x;
181 for (node = dag->
nodes; node; node = next_node) {
182 next_node = node->
next;
185 prev_node->
next = next_node;
187 dag->
nodes = next_node;
189 delete_node(dag, node);
197 for (node = dag->
nodes; node; node = node->
next) {
205 remove_dangling_links(dag, node);
216 initial = dag->
start;
219 E_INFO(
"Writing lattice file: %s\n", filename);
220 if ((fp = fopen(filename,
"w")) == NULL) {
221 E_ERROR_SYSTEM(
"Failed to open lattice file '%s' for writing", filename);
226 fprintf(fp,
"# getcwd: /this/is/bogus\n");
227 fprintf(fp,
"# -logbase %e\n", logmath_get_base(dag->
lmath));
230 fprintf(fp,
"Frames %d\n", dag->
n_frames);
233 for (i = 0, d = dag->
nodes; d; d = d->
next, i++);
235 "Nodes %d (NODEID WORD STARTFRAME FIRST-ENDFRAME LAST-ENDFRAME)\n",
237 for (i = 0, d = dag->
nodes; d; d = d->
next, i++) {
239 fprintf(fp,
"%d %s %d %d %d ; %d\n",
240 i, dict_wordstr(dag->
dict, d->
wid),
245 fprintf(fp,
"Initial %d\nFinal %d\n", initial->
id, final->id);
249 fprintf(fp,
"BestSegAscr %d (NODEID ENDFRAME ASCORE)\n",
253 fprintf(fp,
"Edges (FROM-NODEID TO-NODEID ASCORE)\n");
256 for (l = d->
exits; l; l = l->next) {
259 fprintf(fp,
"%d %d %d\n",
263 fprintf(fp,
"End\n");
274 int32 j, n_links, n_nodes;
276 initial = dag->
start;
279 E_INFO(
"Writing lattice file: %s\n", filename);
280 if ((fp = fopen(filename,
"w")) == NULL) {
281 E_ERROR_SYSTEM(
"Failed to open lattice file '%s' for writing", filename);
285 for (n_links = n_nodes = 0, d = dag->
nodes; d; d = d->
next) {
290 for (l = d->
exits; l; l = l->next) {
300 fprintf(fp,
"# Lattice generated by PocketSphinx\n");
301 fprintf(fp,
"#\n# Header\n#\n");
302 fprintf(fp,
"VERSION=1.0\n");
303 fprintf(fp,
"start=%d\n", initial->
id);
304 fprintf(fp,
"end=%d\n", final->id);
307 fprintf(fp,
"N=%d\tL=%d\n", n_nodes, n_links);
308 fprintf(fp,
"#\n# Node definitions\n#\n");
310 char const *word = dict_wordstr(dag->
dict, d->
wid);
311 char const *c = strrchr(word,
'(');
316 altpron = atoi(c + 1);
317 word = dict_basestr(dag->
dict, d->
wid);
318 if (d->
wid == dict_startwid(dag->
dict))
319 word =
"!SENT_START";
320 else if (d->
wid == dict_finishwid(dag->
dict))
324 fprintf(fp,
"I=%d\tt=%.2f\tW=%s\tv=%d\n",
328 fprintf(fp,
"#\n# Link definitions\n#\n");
329 for (j = 0, d = dag->
nodes; d; d = d->
next) {
333 for (l = d->
exits; l; l = l->next) {
338 fprintf(fp,
"J=%d\tS=%d\tE=%d\ta=%f\tp=%g\n", j++,
351 dag_param_read(lineiter_t *li,
char *param)
355 while ((li = lineiter_next(li)) != NULL) {
359 if (li->buf[0] ==
'#')
363 c = strchr(li->buf,
' ');
364 if (c == NULL)
continue;
367 if (strncmp(li->buf, param, strlen(param)) == 0
368 && sscanf(c + 1,
"%d", &n) == 1)
381 for (l = d->
entries; l; l = l->next)
383 dag_mark_reachable(l->link->
from);
399 int32 pip, silpen, fillpen;
401 dag = ckd_calloc(1,
sizeof(*dag));
411 dag->
lmath = logmath_init(1.0001, 0, FALSE);
423 E_INFO(
"Reading DAG file: %s\n", file);
424 if ((fp = fopen_compchk(file, &ispipe)) == NULL) {
425 E_ERROR_SYSTEM(
"Failed to open DAG file '%s' for reading", file);
428 line = lineiter_start(fp);
432 E_ERROR(
"Premature EOF(%s)\n", file);
435 if (strncmp(line->buf,
"# getcwd: ", 10) != 0) {
436 E_ERROR(
"%s does not begin with '# getcwd: '\n%s", file, line->buf);
439 if ((line = lineiter_next(line)) == NULL) {
440 E_ERROR(
"Premature EOF(%s)\n", file);
443 if ((strncmp(line->buf,
"# -logbase ", 11) != 0)
444 || (sscanf(line->buf + 11,
"%lf", &lb) != 1)) {
445 E_WARN(
"%s: Cannot find -logbase in header\n", file);
449 if (dag->
lmath == NULL)
450 dag->
lmath = logmath_init(lb, 0, TRUE);
452 float32 pb = logmath_get_base(dag->
lmath);
453 if (fabs(lb - pb) >= 0.0001) {
454 E_WARN(
"Inconsistent logbases: %f vs %f: will compensate\n", lb, pb);
455 logratio = (float32)(log(lb) / log(pb));
456 E_INFO(
"Lattice log ratio: %f\n", logratio);
460 dag->
n_frames = dag_param_read(line,
"Frames");
462 E_ERROR(
"Frames parameter missing or invalid\n");
466 n_nodes = dag_param_read(line,
"Nodes");
468 E_ERROR(
"Nodes parameter missing or invalid\n");
473 darray = ckd_calloc(n_nodes,
sizeof(*darray));
474 for (i = 0; i < n_nodes; i++) {
477 int seqid, sf, fef, lef;
480 if ((line = lineiter_next(line)) == NULL) {
481 E_ERROR(
"Premature EOF while loading Nodes(%s)\n", file);
486 sscanf(line->buf,
"%d %255s %d %d %d", &seqid, wd, &sf, &fef,
488 E_ERROR(
"Cannot parse line: %s, value of count %d\n", line->buf, k);
494 if (dag->
search == NULL) {
495 char *ww = ckd_salloc(wd);
504 E_ERROR(
"Unknown word in line: %s\n", line->buf);
510 E_ERROR(
"Seqno error: %s\n", line->buf);
534 k = dag_param_read(line,
"Initial");
535 if ((k < 0) || (k >= n_nodes)) {
536 E_ERROR(
"Initial node parameter missing or invalid\n");
539 dag->
start = darray[k];
542 k = dag_param_read(line,
"Final");
543 if ((k < 0) || (k >= n_nodes)) {
544 E_ERROR(
"Final node parameter missing or invalid\n");
547 dag->
end = darray[k];
550 if ((k = dag_param_read(line,
"BestSegAscr")) < 0) {
551 E_ERROR(
"BestSegAscr parameter missing\n");
554 for (i = 0; i < k; i++) {
555 if ((line = lineiter_next(line)) == NULL) {
556 E_ERROR(
"Premature EOF while (%s) ignoring BestSegAscr\n",
563 while ((line = lineiter_next(line)) != NULL) {
564 if (line->buf[0] ==
'#')
566 if (0 == strncmp(line->buf,
"Edges", 5))
570 E_ERROR(
"Edges missing\n");
573 while ((line = lineiter_next(line)) != NULL) {
577 if (sscanf(line->buf,
"%d %d %d", &from, &to, &ascr) != 3)
583 if (logratio != 1.0f)
584 ascr = (int32)(ascr * logratio);
587 if (strcmp(line->buf,
"End\n") != 0) {
588 E_ERROR(
"Terminating 'End' missing\n");
592 fclose_comp(fp, ispipe);
600 ? ps_search_finish_wid(dag->
search)
604 dag_mark_reachable(dag->
end);
614 pip = logmath_log(dag->
lmath, cmd_ln_float32_r(ps->
config,
"-pip"));
615 silpen = pip + logmath_log(dag->
lmath,
616 cmd_ln_float32_r(ps->
config,
"-silprob"));
617 fillpen = pip + logmath_log(dag->
lmath,
618 cmd_ln_float32_r(ps->
config,
"-fillprob"));
625 E_ERROR(
"Failed to load %s\n", file);
627 if (fp) fclose_comp(fp, ispipe);
643 dag = ckd_calloc(1,
sizeof(*dag));
671 logmath_free(dag->
lmath);
714 if (out_fef) *out_fef = (int16)node->
fef;
715 if (out_lef) *out_lef = (int16)node->
lef;
722 return dict_wordstr(dag->
dict, node->
wid);
736 int32 bestpost = logmath_get_zero(dag->
lmath);
738 for (links = node->
exits; links; links = links->next) {
739 int32 post = links->link->
alpha + links->link->
beta - dag->
norm;
740 if (post > bestpost) {
741 if (out_link) *out_link = links->link;
795 if (out_src) *out_src = link->
from;
802 if (link->
from == NULL)
810 if (link->
from == NULL)
818 return link->best_prev;
842 len += strlen(wstr) + 1;
844 for (l = link; l; l = l->best_prev) {
848 len += strlen(wstr) + 1;
854 dag->
hyp_str = ckd_calloc(1, len+1);
861 memcpy(c, wstr, len);
868 for (l = link; l; l = l->best_prev) {
874 memcpy(c, wstr, len);
889 ngram_model_t *lmset;
893 if (0 != strcmp(ps_search_type(seg->
search), PS_SEARCH_TYPE_NGRAM)) {
901 if (link->best_prev == NULL) {
920 if (link->best_prev->best_prev)
947 logmath_t *lmath = ps_search_acmod(seg->
search)->lmath;
954 for (n = node; n; n = n->
alt) {
955 for (x = n->
exits; x; x = x->next) {
958 seg->
prob = logmath_add(lmath, seg->
prob,
963 seg->
word = dict_wordstr(ps_search_dict(seg->
search), node->
wid);
967 ps_lattice_compute_lscr(seg, link, to);
975 ckd_free(itor->
links);
986 ps_lattice_seg_free(seg);
991 ps_lattice_link2itor(seg, itor->
links[itor->
cur - 1], TRUE);
994 ps_lattice_link2itor(seg, itor->
links[itor->
cur], FALSE);
1001 ps_lattice_seg_next,
1015 itor = ckd_calloc(1,
sizeof(*itor));
1016 itor->
base.
vt = &ps_lattice_segfuncs;
1022 for (l = link; l; l = l->best_prev) {
1032 for (l = link; l; l = l->best_prev) {
1033 itor->
links[cur] = l;
1037 ps_lattice_link2itor((
ps_seg_t *)itor, itor->
links[0], FALSE);
1073 link = dag->
q_head->link;
1100 for (node = dag->
nodes; node; node = node->
next)
1101 node->info.
fanin = 0;
1102 for (node = dag->
nodes; node; node = node->
next) {
1103 for (x = node->
exits; x; x = x->next)
1108 if (start == NULL) start = dag->
start;
1109 for (x = start->
exits; x; x = x->next)
1128 if (next->
to->info.
fanin == 0) {
1131 if (end == NULL) end = dag->
end;
1132 if (next->
to == end) {
1141 for (x = next->
to->
exits; x; x = x->next)
1157 for (node = dag->
nodes; node; node = node->
next) {
1158 node->info.
fanin = 0;
1159 for (x = node->
exits; x; x = x->next)
1164 if (end == NULL) end = dag->
end;
1165 for (x = end->
entries; x; x = x->next)
1187 if (start == NULL) start = dag->
start;
1188 if (next->
from == start) {
1216 float32 lwf, float32 ascale)
1232 for (node = dag->
nodes; node; node = node->
next) {
1233 for (x = node->
exits; x; x = x->next) {
1235 x->link->
alpha = logmath_get_zero(lmath);
1238 for (x = dag->
start->
exits; x; x = x->next) {
1246 if (lmset && !to_is_fil)
1248 ps_search_start_wid(search), &n_used) >>
SENSCR_SHIFT) * lwf;
1249 x->link->best_prev = NULL;
1257 int32 bprob, n_used;
1258 int32 w3_wid, w2_wid;
1259 int16 w3_is_fil, w2_is_fil;
1264 assert(link->
path_scr != MAX_NEG_INT32);
1274 while (prev_link->best_prev != NULL) {
1275 prev_link = prev_link->best_prev;
1285 if (lmset && !w3_is_fil && !w2_is_fil)
1286 bprob = ngram_ng_prob(lmset, w2_wid, &w3_wid, 1, &n_used);
1294 w2_is_fil = w3_is_fil;
1297 while (prev_link->best_prev != NULL) {
1298 prev_link = prev_link->best_prev;
1308 for (x = link->
to->
exits; x; x = x->next) {
1317 x->link->
alpha = logmath_add(lmath, x->link->
alpha, link->
alpha + bprob);
1322 if (lmset && !w1_is_fil && !w2_is_fil) {
1325 score += (ngram_bg_score(lmset, w1_wid, w2_wid, &n_used) >>
SENSCR_SHIFT) * lwf;
1328 score += (ngram_tg_score(lmset, w1_wid, w2_wid, w3_wid, &n_used) >>
SENSCR_SHIFT) * lwf;
1333 x->link->best_prev = link;
1341 bestescr = MAX_NEG_INT32;
1345 dag->
norm = logmath_get_zero(lmath);
1346 for (x = dag->
end->
entries; x; x = x->next) {
1347 int32 bprob, n_used;
1355 while (prev_link->best_prev != NULL) {
1356 prev_link = prev_link->best_prev;
1359 from_is_fil = FALSE;
1365 if (lmset && !from_is_fil)
1366 bprob = ngram_ng_prob(lmset,
1368 &from_wid, 1, &n_used);
1371 dag->
norm = logmath_add(lmath, dag->
norm, x->link->
alpha + bprob);
1380 E_INFO(
"Bestpath score: %d\n", bestescr);
1381 E_INFO(
"Normalizer P(O) = alpha(%s:%d:%d) = %d\n",
1391 ngram_model_t *lmset;
1395 if (dag->
search && 0 == strcmp(ps_search_type(dag->
search), PS_SEARCH_TYPE_NGRAM))
1404 int32 from_wid, to_wid;
1405 int16 from_is_fil, to_is_fil;
1413 if (!to_is_fil && from_is_fil) {
1415 while (prev_link->best_prev != NULL) {
1416 prev_link = prev_link->best_prev;
1419 from_is_fil = FALSE;
1430 if (!from_is_fil && !to_is_fil)
1431 jprob += ngram_ng_prob(lmset, to_wid,
1432 &from_wid, 1, &lback);
1438 link = link->best_prev;
1441 E_INFO(
"Joint P(O,S) = %d P(S|O) = %d\n", jprob, jprob - dag->
norm);
1459 for (node = dag->
nodes; node; node = node->
next) {
1460 for (x = node->
exits; x; x = x->next) {
1461 x->link->
beta = logmath_get_zero(lmath);
1466 bestescr = MAX_NEG_INT32;
1470 int32 bprob, n_used;
1471 int32 from_wid, to_wid;
1472 int16 from_is_fil, to_is_fil;
1480 if (!to_is_fil && from_is_fil) {
1482 while (prev_link->best_prev != NULL) {
1483 prev_link = prev_link->best_prev;
1486 from_is_fil = FALSE;
1493 if (lmset && !from_is_fil && !to_is_fil)
1494 bprob = ngram_ng_prob(lmset, to_wid, &from_wid, 1, &n_used);
1498 if (link->
to == dag->
end) {
1511 for (x = link->
to->
exits; x; x = x->next) {
1512 link->
beta = logmath_add(lmath, link->
beta,
1513 x->link->
beta + bprob
1520 return ps_lattice_joint(dag, bestend, ascale) - dag->
norm;
1535 for (x = link->
from->
exits; x; x = next) {
1537 if (x->link == link) {
1547 for (x = link->
to->
entries; x; x = next) {
1549 if (x->link == link) {
1562 dag_mark_reachable(dag->
end);
1569 #define MAX_PATHS 500
1570 #define MAX_HYP_TRIES 10000
1582 int32 bestscore, score;
1589 for (x = from->
exits; x; x = x->next) {
1592 score = best_rem_score(nbest, x->link->
to);
1593 score += x->link->
ascr;
1595 score += (ngram_bg_score(nbest->lmset, x->link->
to->
basewid,
1618 for (i = 0, p = nbest->path_list; (i < MAX_PATHS) && p; p = p->
next, i++) {
1625 if (i < MAX_PATHS) {
1629 nbest->path_list = newpath;
1631 prev->
next = newpath;
1633 nbest->path_tail = newpath;
1636 nbest->n_hyp_insert++;
1637 nbest->insert_depth += i;
1641 nbest->path_tail = prev;
1643 nbest->n_path = MAX_PATHS;
1646 nbest->n_hyp_reject++;
1647 for (; p; p = newpath) {
1650 nbest->n_hyp_reject++;
1661 int32 total_score, tail_score;
1664 for (x = path->
node->
exits; x; x = x->next) {
1673 newpath->
node = x->link->
to;
1678 newpath->
score += nbest->lwf
1679 * (ngram_tg_score(nbest->lmset, newpath->
node->
basewid,
1685 newpath->
score += nbest->lwf
1686 * (ngram_bg_score(nbest->lmset, newpath->
node->
basewid,
1692 nbest->n_hyp_tried++;
1696 if (nbest->n_path >= MAX_PATHS) {
1698 nbest->path_tail->
score
1700 if (total_score < tail_score) {
1702 nbest->n_hyp_reject++;
1707 path_insert(nbest, newpath, total_score);
1713 ngram_model_t *lmset,
1721 nbest = ckd_calloc(1,
sizeof(*nbest));
1723 nbest->lmset = lmset;
1735 for (node = dag->
nodes; node; node = node->
next) {
1736 if (node == dag->
end)
1738 else if (node->
exits == NULL)
1745 nbest->path_list = nbest->path_tail = NULL;
1746 for (node = dag->
nodes; node; node = node->
next) {
1747 if (node->
sf == sf) {
1751 best_rem_score(nbest, node);
1756 path->
score = nbest->lwf *
1758 ? ngram_bg_score(nbest->lmset, node->
basewid, w2, &n_used)
1759 : ngram_tg_score(nbest->lmset, node->
basewid, w2, w1, &n_used));
1778 while ((nbest->top = nbest->path_list) != NULL) {
1779 nbest->path_list = nbest->path_list->
next;
1780 if (nbest->top == nbest->path_tail)
1781 nbest->path_tail = NULL;
1785 if ((nbest->top->
node->
sf >= nbest->ef)
1786 || ((nbest->top->
node == dag->
end) &&
1787 (nbest->ef > dag->
end->
sf))) {
1794 if (nbest->top->
node->
fef < nbest->ef)
1795 path_extend(nbest, nbest->top);
1812 search = nbest->dag->
search;
1816 for (p = path; p; p = p->
parent) {
1818 char *wstr = dict_wordstr(ps_search_dict(search), p->
node->
basewid);
1820 len += strlen(wstr) + 1;
1829 hyp = ckd_calloc(1, len);
1831 for (p = path; p; p = p->
parent) {
1833 char *wstr = dict_wordstr(ps_search_dict(search), p->
node->
basewid);
1837 memcpy(c, wstr, len);
1846 nbest->
hyps = glist_add_ptr(nbest->
hyps, hyp);
1856 assert(itor->cur < itor->n_nodes);
1857 node = itor->nodes[itor->cur];
1858 if (itor->cur == itor->n_nodes - 1)
1859 seg->
ef = node->
lef;
1861 seg->
ef = itor->nodes[itor->cur + 1]->
sf - 1;
1862 seg->
word = dict_wordstr(ps_search_dict(seg->
search), node->
wid);
1871 ckd_free(itor->nodes);
1881 if (itor->cur == itor->n_nodes) {
1882 ps_astar_seg_free(seg);
1886 ps_astar_node2itor(itor);
1905 itor = ckd_calloc(1,
sizeof(*itor));
1906 itor->base.
vt = &ps_astar_segfuncs;
1908 itor->base.
lwf = lwf;
1909 itor->n_nodes = itor->cur = 0;
1910 for (p = path; p; p = p->
parent) {
1913 itor->nodes = ckd_calloc(itor->n_nodes,
sizeof(*itor->nodes));
1914 cur = itor->n_nodes - 1;
1915 for (p = path; p; p = p->
parent) {
1916 itor->nodes[cur] = p->
node;
1920 ps_astar_node2itor(itor);
1930 for (gn = nbest->
hyps; gn; gn = gnode_next(gn)) {
1931 ckd_free(gnode_ptr(gn));
1933 glist_free(nbest->
hyps);
dict_t * dict_init(cmd_ln_t *config, bin_mdef_t *mdef)
Initialize a new dictionary.
ps_latlink_iter_t * ps_latnode_exits(ps_latnode_t *node)
Iterate over exits from this node.
Internal implementation of PocketSphinx decoder.
int32 ps_lattice_posterior(ps_lattice_t *dag, ngram_model_t *lmset, float32 ascale)
Calculate link posterior probabilities on a word graph.
ps_latlink_t * ps_lattice_traverse_edges(ps_lattice_t *dag, ps_latnode_t *start, ps_latnode_t *end)
Start a forward traversal of edges in a word graph.
void ps_astar_finish(ps_astar_t *nbest)
Finish N-best search, releasing resources associated with it.
ps_latpath_t * ps_astar_next(ps_astar_t *nbest)
Find next best hypothesis of A* on a word graph.
void ps_lattice_delq(ps_lattice_t *dag)
Clear and reset the traversal queue.
char const * ps_astar_hyp(ps_astar_t *nbest, ps_latpath_t *path)
Get hypothesis string from A* search.
listelem_alloc_t * latlink_list_alloc
List element allocator for this DAG.
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.
Base structure for search module.
ps_seg_t * ps_lattice_seg_iter(ps_lattice_t *dag, ps_latlink_t *link, float32 lwf)
Get hypothesis segmentation iterator after bestpath search.
logmath_t * lmath
Log-math object.
dict_t * dict
Pronunciation dictionary.
int32 fanin
Number nodes with links to this node.
POCKETSPHINX_EXPORT s3wid_t dict_wordid(dict_t *d, const char *word)
Return word id for given word string if present.
frame_idx_t ef
Ending frame of this word.
ps_latnode_iter_t * ps_latnode_iter(ps_lattice_t *dag)
Start iterating over nodes in the lattice.
acmod_t * acmod
Acoustic model.
int dict_free(dict_t *d)
Release a pointer to a dictionary.
int32 id
Unique id for this node.
void ps_lattice_penalize_fillers(ps_lattice_t *dag, int32 silpen, int32 fillpen)
Insert penalty for fillers.
ps_seg_t base
Base structure.
char const * ps_latlink_baseword(ps_lattice_t *dag, ps_latlink_t *link)
Get base word string from a lattice link.
glist_t hyps
List of hypothesis strings.
int ps_lattice_free(ps_lattice_t *dag)
Free a lattice.
ps_latnode_t * start
Starting node.
ps_segfuncs_t * vt
V-table of seg methods.
logmath_t * lmath
Log-math computation.
ps_latnode_t * ps_latnode_iter_node(ps_latnode_iter_t *itor)
Get node from iterator.
ps_latlink_t ** links
Array of lattice links.
int32 lscr
Language model score.
Operations on dictionary.
latlink_list_t * q_head
Queue of links for traversal.
ps_latnode_t * ps_latlink_nodes(ps_latlink_t *link, ps_latnode_t **out_src)
Get destination and source nodes from a lattice link.
ps_search_t * search
Search (if generated by search).
#define BAD_S3WID
Dictionary word id.
ps_lattice_t * ps_lattice_retain(ps_lattice_t *dag)
Retain a lattice.
struct ps_latnode_s * from
From node.
frame_idx_t n_frames
Number of frames for this utterance.
ps_latlink_t * ps_lattice_reverse_next(ps_lattice_t *dag, ps_latnode_t *start)
Get the next link in reverse traversal.
Word graph search implementation.
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.
ps_latnode_t * nodes
List of all nodes.
listelem_alloc_t * latnode_alloc
Node allocator for this DAG.
int32 alpha
Forward probability of this link P(w,o_1^{ef})
ps_latlink_t * ps_latlink_pred(ps_latlink_t *link)
Get predecessor link in best path.
int32 prob
Log posterior probability.
int ps_latlink_times(ps_latlink_t *link, int16 *out_sf)
Get start and end times from a lattice link.
dict_t * dict_retain(dict_t *d)
Retain a pointer to an dict_t.
latlink_list_t * entries
Links into this node.
struct ps_latnode_s * alt
Node with alternate pronunciation for this word.
char const * ps_latnode_word(ps_lattice_t *dag, ps_latnode_t *node)
Get word string for this node.
char const * ps_latnode_baseword(ps_lattice_t *dag, ps_latnode_t *node)
Get base word string for this node.
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.
ps_search_t * search
Currently active search module.
ps_latlink_t * ps_lattice_traverse_next(ps_lattice_t *dag, ps_latnode_t *end)
Get the next link in forward traversal.
ps_latlink_t * ps_lattice_popq(ps_lattice_t *dag)
Remove an edge from the traversal queue.
ps_latlink_iter_t * ps_latlink_iter_next(ps_latlink_iter_t *itor)
Get next link from a lattice link iterator.
struct ps_latpath_s * next
Pointer to next path in list of paths.
logmath_t * lmath
Log math computation.
void ps_lattice_pushq(ps_lattice_t *dag, ps_latlink_t *link)
Add an edge to the traversal queue.
int32 ps_latnode_prob(ps_lattice_t *dag, ps_latnode_t *node, ps_latlink_t **out_link)
Get best posterior probability and associated acoustic score from a lattice node. ...
N-Gram search module structure.
struct ps_latpath_s * parent
Previous element in this path.
int32 ps_lattice_write_htk(ps_lattice_t *dag, char const *filename)
Write a lattice to disk in HTK format.
void ps_lattice_delete_unreachable(ps_lattice_t *dag)
Remove nodes marked as unreachable.
int16 n_links
Number of lattice links.
ps_latnode_t * end
Ending node.
frame_idx_t sf
Start frame.
logmath_t * ps_lattice_get_logmath(ps_lattice_t *dag)
Get the log-math computation object for this lattice.
latlink_list_t * exits
Links out of this node.
int32 silence
Silence word ID.
#define WORST_SCORE
Large "bad" score.
N-Gram based multi-pass search ("FBS")
int32 ascr
Acoustic score.
cmd_ln_t * config
Configuration.
void ps_latlink_iter_free(ps_latlink_iter_t *itor)
Stop iterating over links.
int dict_filler_word(dict_t *d, s3wid_t w)
Return 1 if w is a filler word, 0 if not.
dict_t * dict
Dictionary for this DAG.
listelem_alloc_t * latpath_alloc
Path allocator for N-best search.
int32 beta
Backward probability of this link P(w|o_{ef+1}^T)
listelem_alloc_t * latlink_alloc
Link allocator for this DAG.
int32 path_scr
Best path score from root of DAG.
int32 wid
Dictionary word id.
int32 node_id
Node from fsg model, used to map lattice back to model.
#define SENSCR_SHIFT
Shift count for senone scores.
ps_latlink_iter_t * ps_latnode_entries(ps_latnode_t *node)
Iterate over entries to this node.
char const * ps_lattice_hyp(ps_lattice_t *dag, ps_latlink_t *link)
Get hypothesis string after bestpath search.
POCKETSPHINX_EXPORT int dict_real_word(dict_t *d, s3wid_t w)
Test if w is a "real" word, i.e.
Word graph structure used in bestpath/nbest search.
#define WORSE_THAN
Is one score worse than another?
ps_astar_t * ps_astar_start(ps_lattice_t *dag, ngram_model_t *lmset, float32 lwf, int sf, int ef, int w1, int w2)
Begin N-Gram based A* search on a word graph.
int32 norm
Normalizer for posterior probabilities.
Segmentation "iterator" for A* search results.
int refcount
Reference count.
latlink_list_t * q_tail
Queue of links for traversal.
int ps_lattice_n_frames(ps_lattice_t *dag)
Get the number of frames in the lattice.
int32 ascr
Score for from->wid (from->sf to this->ef)
int16 cur
Current position in bpidx.
Partial path structure used in N-best (A*) search.
ps_latlink_t * ps_latlink_iter_link(ps_latlink_iter_t *itor)
Get link from iterator.
Segmentation "iterator" for backpointer table results.
#define BETTER_THAN
Is one score better than another?
dict_t * dict
Pronunciation dictionary.
int32 fef
First end frame.
int32 norm
Normalizer for posterior probabilities.
int32 lback
Language model backoff.
int32 basewid
Dictionary base word id.
latlink_list_t * latlink_list_new(ps_lattice_t *dag, ps_latlink_t *link, latlink_list_t *next)
Create a new lattice link element.
int ps_latnode_times(ps_latnode_t *node, int16 *out_fef, int16 *out_lef)
Get start and end time range for a node.
ps_latlink_t * ps_lattice_reverse_edges(ps_lattice_t *dag, ps_latnode_t *start, ps_latnode_t *end)
Start a reverse traversal of edges in a word graph.
ps_latnode_iter_t * ps_latnode_iter_next(ps_latnode_iter_t *itor)
Move to next node in iteration.
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.
ps_lattice_t * ps_lattice_read(ps_decoder_t *ps, char const *file)
Read a lattice from a file on disk.
Linked list of DAG link pointers.
s3wid_t dict_add_word(dict_t *d, char const *word, s3cipid_t const *p, int32 np)
Add a word with the given ciphone pronunciation list to the dictionary.
char const * ps_latlink_word(ps_lattice_t *dag, ps_latlink_t *link)
Get word string from a lattice link.
struct ps_latnode_s * next
Next node in DAG (no ordering implied)
int32 rem_score
Estimated best score from node.sf to end.
void ps_latnode_iter_free(ps_latnode_iter_t *itor)
Stop iterating over nodes.
ps_seg_t * ps_astar_seg_iter(ps_astar_t *astar, ps_latpath_t *path, float32 lwf)
Get hypothesis segmentation from A* search.
char * hyp_str
Current hypothesis string.
Base structure for hypothesis segmentation iterator.
cmd_ln_t * config
Configuration.
ps_latnode_t * node
Node ending this path.
int32 score
Exact score from start node up to node->sf.
int32 ps_lattice_posterior_prune(ps_lattice_t *dag, int32 beam)
Prune all links (and associated nodes) below a certain posterior probability.
int32 ps_latlink_prob(ps_lattice_t *dag, ps_latlink_t *link, int32 *out_ascr)
Get acoustic score and posterior probability from a lattice link.
float32 lwf
Language weight factor (for second-pass searches)
frame_idx_t sf
Start frame.
struct ps_latnode_s * to
To node.
int32 ps_lattice_write(ps_lattice_t *dag, char const *filename)
Write a lattice to disk.
int32 dict_word2basestr(char *word)
If the given word contains a trailing "(....)" (i.e., a Sphinx-II style alternative pronunciation spe...