42 #include <sphinxbase/err.h>
43 #include <sphinxbase/ckd_alloc.h>
44 #include <sphinxbase/strfuncs.h>
45 #include <sphinxbase/pio.h>
46 #include <sphinxbase/cmd_ln.h>
49 #include "allphone_search.h"
67 allphone_search_seg_free(
ps_seg_t * seg)
77 seg->
ascr = phseg->score;
78 seg->
lscr = phseg->tscore;
83 allphone_search_seg_next(
ps_seg_t * seg)
88 itor->seg = itor->seg->next;
90 if (itor->seg == NULL) {
91 allphone_search_seg_free(seg);
94 phseg = gnode_ptr(itor->seg);
95 allphone_search_fill_iter(seg, phseg);
101 allphone_search_seg_next,
102 allphone_search_seg_free
112 allphone_backtrace(allphs, allphs->
frame - 1, NULL);
113 if (allphs->segments == NULL)
118 iter->base.
vt = &fsg_segfuncs;
119 iter->base.
search = search;
120 iter->seg = allphs->segments;
121 allphone_search_fill_iter((
ps_seg_t *)iter, gnode_ptr(iter->seg));
127 allphone_search_start,
128 allphone_search_step,
129 allphone_search_finish,
130 allphone_search_reinit,
131 allphone_search_free,
132 allphone_search_lattice,
134 allphone_search_prob,
135 allphone_search_seg_iter,
152 for (p = ci_phmm[bin_mdef_pid2ci(
mdef, pid)]; p; p = p->
next) {
153 if (mdef_pid2tmatid(
mdef, p->
pid) == mdef_pid2tmatid(
mdef, pid))
154 if (mdef_pid2ssid(
mdef, p->
pid) == mdef_pid2ssid(
mdef, pid))
175 rclist = (int32 *) ckd_calloc(
mdef->
n_ciphone + 1,
sizeof(int32));
180 for (p = ci_phmm[ci]; p; p = p->
next) {
184 if (bitvec_is_set(p->
rc, rc))
190 for (i = 0; IS_S3CIPID(rclist[i]); i++) {
191 for (p2 = ci_phmm[rclist[i]]; p2; p2 = p2->
next) {
192 if (bitvec_is_set(p2->
lc, ci)) {
194 l = (
plink_t *) ckd_calloc(1,
sizeof(*l));
235 nphone = allphs->
ci_only ? bin_mdef_n_ciphone(
mdef) : bin_mdef_n_phone(
mdef);
236 E_INFO(
"Building PHMM net of %d phones\n", nphone);
237 for (pid = 0; pid < nphone; pid++) {
238 if ((p = phmm_lookup(allphs, pid)) == NULL) {
240 p = (
phmm_t *) ckd_calloc(1,
sizeof(*p));
244 p->
ci = bin_mdef_pid2ci(
mdef, pid);
254 lrc_size = bitvec_size(bin_mdef_n_ciphone(
mdef));
255 lc = ckd_calloc(n_phmm * 2 * lrc_size,
sizeof(bitvec_t));
256 rc = lc + (n_phmm * lrc_size);
273 for (ci = 0; ci < bin_mdef_n_ciphone(
mdef); ci++) {
275 bitvec_set_all(p->
lc, bin_mdef_n_ciphone(
mdef));
276 bitvec_set_all(p->
rc, bin_mdef_n_ciphone(
mdef));
285 for (pid = bin_mdef_n_ciphone(
mdef); pid < nphone;
290 for (i = 0; IS_S3CIPID(filler[i]); i++)
291 bitvec_set(p->
lc, filler[i]);
294 bitvec_set(p->
lc,
mdef->
phone[pid].info.cd.ctx[1]);
297 for (i = 0; IS_S3CIPID(filler[i]); i++)
298 bitvec_set(p->
rc, filler[i]);
301 bitvec_set(p->
rc,
mdef->
phone[pid].info.cd.ctx[2]);
307 n_link = phmm_link(allphs);
309 E_INFO(
"%d nodes, %d links\n", n_phmm, n_link);
323 for (ci = 0; ci < mdef_n_ciphone(
mdef); ++ci) {
326 for (p = allphs->
ci_phmm[ci]; p; p = next) {
330 for (l = p->
succlist; l; l = lnext) {
358 for (p = ci_phmm[(
unsigned) ci]; p; p = p->
next) {
359 if (hmm_frame(&(p->
hmm)) == allphs->
frame) {
385 th = best + allphs->
pbeam;
388 mdef = ps_search_acmod(allphs)->mdef;
389 curfrm = allphs->
frame;
396 for (p = ci_phmm[(
unsigned) ci]; p; p = p->
next) {
397 if (hmm_frame(&(p->
hmm)) == curfrm) {
399 if (hmm_bestscore(&(p->
hmm)) >= th) {
401 h = (
history_t *) ckd_calloc(1,
sizeof(*h));
404 h->
hist = hmm_out_history(&(p->
hmm));
405 h->
score = hmm_out_score(&(p->
hmm));
414 blkarray_list_get(history, h->
hist);
416 if (pred->
hist > 0) {
418 blkarray_list_get(history,
421 ngram_tg_score(allphs->
lm,
432 ngram_bg_score(allphs->
lm,
449 blkarray_list_append(history, h);
452 hmm_frame(&(p->
hmm)) = nf;
465 int32 frame_history_start)
470 int32 newscore, nf, curfrm;
474 curfrm = allphs->
frame;
479 for (hist_idx = frame_history_start;
480 hist_idx < blkarray_list_n_valid(allphs->
history); hist_idx++) {
481 h = blkarray_list_get(allphs->
history, hist_idx);
496 ngram_tg_score(allphs->
lm,
503 tscore = ngram_bg_score(allphs->
lm,
510 newscore = h->
score + tscore;
511 if ((newscore > best + allphs->beam)
512 && (newscore > hmm_in_score(&(to->
hmm)))) {
520 allphone_search_init(
const char *name,
530 ps_search_init(ps_search_base(allphs), &allphone_funcs, PS_SEARCH_TYPE_ALLPHONE, name,
config, acmod,
536 if (allphs->
hmmctx == NULL) {
537 ps_search_free(ps_search_base(allphs));
542 allphs->lw = cmd_ln_float32_r(
config,
"-lw");
549 allphs->
lm = ngram_model_retain(lm);
554 if (silwid == ngram_unknown_wid(allphs->
lm)) {
555 E_ERROR(
"Phonetic LM does not have SIL phone in vocabulary\n");
565 ngram_wid(allphs->
lm,
568 if (allphs->
ci2lmwid[i] == ngram_unknown_wid(allphs->
lm))
574 (
"Failed to load language model specified in -allphone, doing unconstrained phone-loop decoding\n");
583 allphs->segments = NULL;
588 (int32) logmath_log(acmod->
lmath,
589 cmd_ln_float64_r(
config,
"-beam"))
593 (int32) logmath_log(acmod->
lmath,
594 cmd_ln_float64_r(
config,
"-pbeam"))
598 allphs->
history = blkarray_list_init();
601 allphs->
ascale = 1.0 / cmd_ln_float32_r(
config,
"-ascale");
603 E_INFO(
"Allphone(beam: %d, pbeam: %d)\n", allphs->beam, allphs->
pbeam);
605 ptmr_init(&allphs->
perf);
621 (
"-lm argument missing; doing unconstrained phone-loop decoding\n");
625 cmd_ln_float32_r(search->
config,
640 / cmd_ln_int32_r(ps_search_config(allphs),
"-frate");
642 E_INFO(
"TOTAL allphone %.2f CPU %.3f xRT\n",
643 allphs->
perf.t_tot_cpu,
644 allphs->
perf.t_tot_cpu / n_speech);
645 E_INFO(
"TOTAL allphone %.2f wall %.3f xRT\n",
646 allphs->
perf.t_tot_elapsed,
647 allphs->
perf.t_tot_elapsed / n_speech);
654 ngram_model_free(allphs->
lm);
658 blkarray_list_free(allphs->
history);
675 for (ci = 0; ci < bin_mdef_n_ciphone(
mdef); ci++) {
676 for (p = allphs->
ci_phmm[(
unsigned) ci]; p; p = p->
next) {
685 blkarray_list_reset(allphs->
history);
689 ci = bin_mdef_silphone(
mdef);
697 ptmr_reset(&allphs->
perf);
698 ptmr_start(&allphs->
perf);
711 acmod = ps_search_acmod(allphs);
715 for (ci = 0; ci < bin_mdef_n_ciphone(
mdef); ci++)
717 if (hmm_frame(&(p->
hmm)) == allphs->
frame)
722 allphone_search_step(
ps_search_t * search,
int frame_idx)
724 int32 bestscr, frame_history_start;
730 allphone_search_sen_active(allphs);
733 bestscr = phmm_eval_all(allphs, senscr);
735 frame_history_start = blkarray_list_n_valid(allphs->
history);
736 phmm_exit(allphs, bestscr);
737 phmm_trans(allphs, bestscr, frame_history_start);
747 int32 score = h->
score;
751 score -= pred->
score;
761 for (gn = allphs->segments; gn; gn = gn->next) {
762 ckd_free(gnode_ptr(gn));
764 glist_free(allphs->segments);
765 allphs->segments = NULL;
771 int32 best, hist_idx, best_idx;
777 allphone_clear_segments(allphs);
781 hist_idx = blkarray_list_n_valid(allphs->
history) - 1;
782 while (hist_idx > 0) {
783 h = blkarray_list_get(allphs->
history, hist_idx);
785 frm = last_frm = h->
ef;
795 best = (int32) 0x80000000;
797 while (frm == last_frm && hist_idx > 0) {
798 h = blkarray_list_get(allphs->
history, hist_idx);
800 if (h->
score > best && frm == last_frm) {
814 while (best_idx > 0) {
815 h = blkarray_list_get(allphs->
history, best_idx);
821 h->
hist))->ef + 1 : 0;
823 s->score = ascore(allphs, h);
825 allphs->segments = glist_add_ptr(allphs->segments, s);
842 n_hist = blkarray_list_n_valid(allphs->
history);
844 (
"%d frames, %d HMMs (%d/fr), %d senones (%d/fr), %d history entries (%d/fr)\n",
849 n_hist, (allphs->
frame > 0) ? n_hist / allphs->
frame : 0);
852 allphone_backtrace(allphs, allphs->
frame - 1, NULL);
855 ptmr_stop(&allphs->
perf);
857 cf = ps_search_acmod(allphs)->output_frame;
859 double n_speech = (double) (cf + 1)
860 / cmd_ln_int32_r(ps_search_config(allphs),
"-frate");
861 E_INFO(
"allphone %.2f CPU %.3f xRT\n",
862 allphs->
perf.t_cpu, allphs->
perf.t_cpu / n_speech);
863 E_INFO(
"allphone %.2f wall %.3f xRT\n",
864 allphs->
perf.t_elapsed, allphs->
perf.t_elapsed / n_speech);
872 allphone_search_hyp(
ps_search_t * search, int32 * out_score)
877 const char *phone_str;
879 int len, hyp_idx, phone_idx;
889 allphone_backtrace(allphs, allphs->
frame - 1, out_score);
890 if (allphs->segments == NULL) {
894 len = glist_count(allphs->segments) * 10;
896 search->
hyp_str = (
char *) ckd_calloc(len,
sizeof(*search->
hyp_str));
898 for (gn = allphs->segments; gn; gn = gn->next) {
902 while (phone_str[phone_idx] !=
'\0')
903 search->
hyp_str[hyp_idx++] = phone_str[phone_idx++];
904 search->
hyp_str[hyp_idx++] =
' ';
906 search->
hyp_str[--hyp_idx] =
'\0';
907 E_INFO(
"Hyp: %s\n", search->
hyp_str);