49 #include <sphinxbase/ckd_alloc.h>
50 #include <sphinxbase/err.h>
58 int16
const *senscore,
63 assert(n_emit_state > 0);
65 E_ERROR(
"Number of emitting states must be <= %d\n",
HMM_MAX_NSTATE);
69 ctx = ckd_calloc(1,
sizeof(*ctx));
70 ctx->n_emit_state = n_emit_state;
72 ctx->senscore = senscore;
74 ctx->st_sen_scr = ckd_calloc(n_emit_state,
sizeof(*ctx->st_sen_scr));
84 ckd_free(ctx->st_sen_scr);
93 hmm->n_emit_state = ctx->n_emit_state;
98 for (i = 1; i < hmm_n_emit_state(hmm); ++i) {
104 memcpy(hmm->senid, ctx->sseq[ssid], hmm->n_emit_state *
sizeof(*hmm->senid));
106 hmm->tmatid = tmatid;
121 if (hmm_is_mpx(hmm)) {
123 for (i = 0; i < hmm_n_emit_state(hmm); i++)
124 fprintf(fp,
" %11d", hmm_senid(hmm, i));
126 for (i = 0; i < hmm_n_emit_state(hmm); i++)
127 fprintf(fp,
"%d ", hmm_ssid(hmm, i));
131 fprintf(fp,
"SSID ");
132 for (i = 0; i < hmm_n_emit_state(hmm); i++)
133 fprintf(fp,
" %11d", hmm_senid(hmm, i));
134 fprintf(fp,
" (%d)\n", hmm_ssid(hmm, 0));
137 if (hmm->ctx->senscore) {
138 fprintf(fp,
"SENSCR");
139 for (i = 0; i < hmm_n_emit_state(hmm); i++)
140 fprintf(fp,
" %11d", hmm_senscr(hmm, i));
144 fprintf(fp,
"SCORES %11d", hmm_in_score(hmm));
145 for (i = 1; i < hmm_n_emit_state(hmm); i++)
146 fprintf(fp,
" %11d", hmm_score(hmm, i));
147 fprintf(fp,
" %11d", hmm_out_score(hmm));
150 fprintf(fp,
"HISTID %11d", hmm_in_history(hmm));
151 for (i = 1; i < hmm_n_emit_state(hmm); i++)
152 fprintf(fp,
" %11d", hmm_history(hmm, i));
153 fprintf(fp,
" %11d", hmm_out_history(hmm));
156 if (hmm_in_score(hmm) > 0)
158 "ALERT!! The input score %d is large than 0. Probably wrap around.\n",
160 if (hmm_out_score(hmm) > 0)
162 "ALERT!! The output score %d is large than 0. Probably wrap around\n.",
175 for (i = 1; i < hmm_n_emit_state(h); i++)
188 hmm_in_history(h) = -1;
189 for (i = 1; i < hmm_n_emit_state(h); i++) {
191 hmm_history(h, i) = -1;
194 hmm_out_history(h) = -1;
203 hmm_in_score(h) = score;
204 hmm_in_history(h) = histid;
205 hmm_frame(h) = frame;
213 for (i = 0; i < hmm_n_emit_state(h); i++) {
215 hmm_score(h, i) -= bestscr;
218 hmm_out_score(h) -= bestscr;
221 #define hmm_tprob_5st(i, j) (-tp[(i)*6+(j)])
222 #define nonmpx_senscr(i) (-senscore[sseq[i]])
225 hmm_vit_eval_5st_lr(
hmm_t * hmm)
227 int16
const *senscore = hmm->ctx->senscore;
228 uint8
const *tp = hmm->ctx->tp[hmm->tmatid][0];
229 uint16
const *sseq = hmm->senid;
230 int32 s5, s4, s3, s2, s1, s0, t2, t1, t0, bestScore;
236 s4 = hmm_score(hmm, 4) + nonmpx_senscr(4);
237 s3 = hmm_score(hmm, 3) + nonmpx_senscr(3);
240 t1 = s4 + hmm_tprob_5st(4, 5);
241 t2 = s3 + hmm_tprob_5st(3, 5);
244 hmm_out_history(hmm) = hmm_history(hmm, 4);
247 hmm_out_history(hmm) = hmm_history(hmm, 3);
250 hmm_out_score(hmm) = s5;
254 s2 = hmm_score(hmm, 2) + nonmpx_senscr(2);
257 t0 = s4 + hmm_tprob_5st(4, 4);
258 t1 = s3 + hmm_tprob_5st(3, 4);
259 t2 = s2 + hmm_tprob_5st(2, 4);
263 hmm_history(hmm, 4) = hmm_history(hmm, 2);
269 hmm_history(hmm, 4) = hmm_history(hmm, 2);
272 hmm_history(hmm, 4) = hmm_history(hmm, 3);
277 hmm_score(hmm, 4) = s4;
280 s1 = hmm_score(hmm, 1) + nonmpx_senscr(1);
283 t0 = s3 + hmm_tprob_5st(3, 3);
284 t1 = s2 + hmm_tprob_5st(2, 3);
285 t2 = s1 + hmm_tprob_5st(1, 3);
289 hmm_history(hmm, 3) = hmm_history(hmm, 1);
295 hmm_history(hmm, 3) = hmm_history(hmm, 1);
298 hmm_history(hmm, 3) = hmm_history(hmm, 2);
303 hmm_score(hmm, 3) = s3;
306 s0 = hmm_in_score(hmm) + nonmpx_senscr(0);
308 t0 = s2 + hmm_tprob_5st(2, 2);
309 t1 = s1 + hmm_tprob_5st(1, 2);
310 t2 = s0 + hmm_tprob_5st(0, 2);
314 hmm_history(hmm, 2) = hmm_in_history(hmm);
320 hmm_history(hmm, 2) = hmm_in_history(hmm);
323 hmm_history(hmm, 2) = hmm_history(hmm, 1);
328 hmm_score(hmm, 2) = s2;
332 t0 = s1 + hmm_tprob_5st(1, 1);
333 t1 = s0 + hmm_tprob_5st(0, 1);
338 hmm_history(hmm, 1) = hmm_in_history(hmm);
342 hmm_score(hmm, 1) = s1;
345 s0 = s0 + hmm_tprob_5st(0, 0);
348 hmm_in_score(hmm) = s0;
350 hmm_bestscore(hmm) = bestScore;
354 #define mpx_senid(st) sseq[ssid[st]][st]
355 #define mpx_senscr(st) (-senscore[mpx_senid(st)])
358 hmm_vit_eval_5st_lr_mpx(
hmm_t * hmm)
360 uint8
const *tp = hmm->ctx->tp[hmm->tmatid][0];
361 int16
const *senscore = hmm->ctx->senscore;
362 uint16 *
const *sseq = hmm->ctx->sseq;
363 uint16 *ssid = hmm->senid;
365 int32 s5, s4, s3, s2, s1, s0, t2, t1, t0;
371 s4 = hmm_score(hmm, 4) + mpx_senscr(4);
372 t1 = s4 + hmm_tprob_5st(4, 5);
377 s3 = hmm_score(hmm, 3) + mpx_senscr(3);
378 t2 = s3 + hmm_tprob_5st(3, 5);
382 hmm_out_history(hmm) = hmm_history(hmm, 4);
386 hmm_out_history(hmm) = hmm_history(hmm, 3);
389 hmm_out_score(hmm) = s5;
396 s2 = hmm_score(hmm, 2) + mpx_senscr(2);
397 t2 = s2 + hmm_tprob_5st(2, 4);
401 if (s4 != WORST_SCORE)
402 t0 = s4 + hmm_tprob_5st(4, 4);
403 if (s3 != WORST_SCORE)
404 t1 = s3 + hmm_tprob_5st(3, 4);
408 hmm_history(hmm, 4) = hmm_history(hmm, 2);
417 hmm_history(hmm, 4) = hmm_history(hmm, 2);
422 hmm_history(hmm, 4) = hmm_history(hmm, 3);
429 hmm_score(hmm, 4) = s4;
435 s1 = hmm_score(hmm, 1) + mpx_senscr(1);
436 t2 = s1 + hmm_tprob_5st(1, 3);
439 if (s3 != WORST_SCORE)
440 t0 = s3 + hmm_tprob_5st(3, 3);
441 if (s2 != WORST_SCORE)
442 t1 = s2 + hmm_tprob_5st(2, 3);
446 hmm_history(hmm, 3) = hmm_history(hmm, 1);
455 hmm_history(hmm, 3) = hmm_history(hmm, 1);
460 hmm_history(hmm, 3) = hmm_history(hmm, 2);
466 hmm_score(hmm, 3) = s3;
469 s0 = hmm_in_score(hmm) + mpx_senscr(0);
473 if (s2 != WORST_SCORE)
474 t0 = s2 + hmm_tprob_5st(2, 2);
475 if (s1 != WORST_SCORE)
476 t1 = s1 + hmm_tprob_5st(1, 2);
477 t2 = s0 + hmm_tprob_5st(0, 2);
481 hmm_history(hmm, 2) = hmm_in_history(hmm);
490 hmm_history(hmm, 2) = hmm_in_history(hmm);
495 hmm_history(hmm, 2) = hmm_history(hmm, 1);
501 hmm_score(hmm, 2) = s2;
505 if (s1 != WORST_SCORE)
506 t0 = s1 + hmm_tprob_5st(1, 1);
507 t1 = s0 + hmm_tprob_5st(0, 1);
513 hmm_history(hmm, 1) = hmm_in_history(hmm);
518 hmm_score(hmm, 1) = s1;
520 s0 += hmm_tprob_5st(0, 0);
523 hmm_in_score(hmm) = s0;
525 hmm_bestscore(hmm) = bestScore;
529 #define hmm_tprob_3st(i, j) (-tp[(i)*4+(j)])
532 hmm_vit_eval_3st_lr(
hmm_t * hmm)
534 int16
const *senscore = hmm->ctx->senscore;
535 uint8
const *tp = hmm->ctx->tp[hmm->tmatid][0];
536 uint16
const *sseq = hmm->senid;
537 int32 s3, s2, s1, s0, t2, t1, t0, bestScore;
539 s2 = hmm_score(hmm, 2) + nonmpx_senscr(2);
540 s1 = hmm_score(hmm, 1) + nonmpx_senscr(1);
541 s0 = hmm_in_score(hmm) + nonmpx_senscr(0);
549 t1 = s2 + hmm_tprob_3st(2, 3);
551 t2 = s1 + hmm_tprob_3st(1, 3);
554 hmm_out_history(hmm) = hmm_history(hmm, 2);
557 hmm_out_history(hmm) = hmm_history(hmm, 1);
560 hmm_out_score(hmm) = s3;
565 t0 = s2 + hmm_tprob_3st(2, 2);
566 t1 = s1 + hmm_tprob_3st(1, 2);
567 if (hmm_tprob_3st(0, 2)
BETTER_THAN TMAT_WORST_SCORE)
568 t2 = s0 + hmm_tprob_3st(0, 2);
572 hmm_history(hmm, 2) = hmm_in_history(hmm);
578 hmm_history(hmm, 2) = hmm_in_history(hmm);
581 hmm_history(hmm, 2) = hmm_history(hmm, 1);
586 hmm_score(hmm, 2) = s2;
589 t0 = s1 + hmm_tprob_3st(1, 1);
590 t1 = s0 + hmm_tprob_3st(0, 1);
595 hmm_history(hmm, 1) = hmm_in_history(hmm);
599 hmm_score(hmm, 1) = s1;
602 s0 = s0 + hmm_tprob_3st(0, 0);
605 hmm_in_score(hmm) = s0;
607 hmm_bestscore(hmm) = bestScore;
612 hmm_vit_eval_3st_lr_mpx(
hmm_t * hmm)
614 uint8
const *tp = hmm->ctx->tp[hmm->tmatid][0];
615 int16
const *senscore = hmm->ctx->senscore;
616 uint16 *
const *sseq = hmm->ctx->sseq;
617 uint16 *ssid = hmm->senid;
619 int32 s3, s2, s1, s0, t2, t1, t0;
626 s2 = hmm_score(hmm, 2) + mpx_senscr(2);
627 t1 = s2 + hmm_tprob_3st(2, 3);
632 s1 = hmm_score(hmm, 1) + mpx_senscr(1);
633 if (hmm_tprob_3st(1,3)
BETTER_THAN TMAT_WORST_SCORE)
634 t2 = s1 + hmm_tprob_3st(1, 3);
638 hmm_out_history(hmm) = hmm_history(hmm, 2);
642 hmm_out_history(hmm) = hmm_history(hmm, 1);
645 hmm_out_score(hmm) = s3;
649 s0 = hmm_in_score(hmm) + mpx_senscr(0);
653 if (s2 != WORST_SCORE)
654 t0 = s2 + hmm_tprob_3st(2, 2);
655 if (s1 != WORST_SCORE)
656 t1 = s1 + hmm_tprob_3st(1, 2);
657 if (hmm_tprob_3st(0,2)
BETTER_THAN TMAT_WORST_SCORE)
658 t2 = s0 + hmm_tprob_3st(0, 2);
662 hmm_history(hmm, 2) = hmm_in_history(hmm);
671 hmm_history(hmm, 2) = hmm_in_history(hmm);
676 hmm_history(hmm, 2) = hmm_history(hmm, 1);
682 hmm_score(hmm, 2) = s2;
686 if (s1 != WORST_SCORE)
687 t0 = s1 + hmm_tprob_3st(1, 1);
688 t1 = s0 + hmm_tprob_3st(0, 1);
694 hmm_history(hmm, 1) = hmm_in_history(hmm);
699 hmm_score(hmm, 1) = s1;
702 s0 += hmm_tprob_3st(0, 0);
705 hmm_in_score(hmm) = s0;
707 hmm_bestscore(hmm) = bestScore;
712 hmm_vit_eval_anytopo(
hmm_t * hmm)
715 int32 to, from, bestfrom;
716 int32 newscr, scr, bestscr;
720 ctx->st_sen_scr[0] = hmm_in_score(hmm) + hmm_senscr(hmm, 0);
721 for (from = 1; from < hmm_n_emit_state(hmm); ++from) {
722 if ((ctx->st_sen_scr[from] =
724 ctx->st_sen_scr[from] = WORST_SCORE;
729 final_state = hmm_n_emit_state(hmm);
733 for (from = to - 1; from >= 0; --from) {
734 if ((hmm_tprob(hmm, from, to)
BETTER_THAN TMAT_WORST_SCORE) &&
735 ((newscr = ctx->st_sen_scr[from]
741 hmm_out_score(hmm) = scr;
743 hmm_out_history(hmm) = hmm_history(hmm, bestfrom);
747 for (to = final_state - 1; to >= 0; --to) {
750 (hmm_tprob(hmm, to, to)
BETTER_THAN TMAT_WORST_SCORE)
751 ? ctx->st_sen_scr[to] + hmm_tprob(hmm, to, to)
756 for (from = to - 1; from >= 0; --from) {
757 if ((hmm_tprob(hmm, from, to)
BETTER_THAN TMAT_WORST_SCORE) &&
758 ((newscr = ctx->st_sen_scr[from]
767 hmm_in_score(hmm) = scr;
769 hmm_in_history(hmm) = hmm_history(hmm, bestfrom);
772 hmm_score(hmm, to) = scr;
774 hmm_history(hmm, to) = hmm_history(hmm, bestfrom);
777 if (bestfrom >= 0 && hmm_is_mpx(hmm))
778 hmm->senid[to] = hmm->senid[bestfrom];
784 hmm_bestscore(hmm) = bestscr;
791 if (hmm_is_mpx(hmm)) {
792 if (hmm_n_emit_state(hmm) == 5)
793 return hmm_vit_eval_5st_lr_mpx(hmm);
794 else if (hmm_n_emit_state(hmm) == 3)
795 return hmm_vit_eval_3st_lr_mpx(hmm);
797 return hmm_vit_eval_anytopo(hmm);
800 if (hmm_n_emit_state(hmm) == 5)
801 return hmm_vit_eval_5st_lr(hmm);
802 else if (hmm_n_emit_state(hmm) == 3)
803 return hmm_vit_eval_3st_lr(hmm);
805 return hmm_vit_eval_anytopo(hmm);
815 fprintf(fp,
"BEFORE:\n");
820 fprintf(fp,
"AFTER:\n");
int32 hmm_dump_vit_eval(hmm_t *hmm, FILE *fp)
Like hmm_vit_eval, but dump HMM state and relevant senscr to fp first, for debugging;.
void hmm_init(hmm_context_t *ctx, hmm_t *hmm, int mpx, int ssid, int tmatid)
Populate a previously-allocated HMM structure, allocating internal data.
An individual HMM among the HMM search space.
void hmm_deinit(hmm_t *hmm)
Free an HMM structure, releasing internal data (but not the HMM structure itself).
#define BAD_SSID
Invalid senone sequence ID (limited to 16 bits for PocketSphinx).
Implementation of HMM base structure.
#define HMM_MAX_NSTATE
Hard-coded limit on the number of emitting states.
int32 hmm_vit_eval(hmm_t *hmm)
Viterbi evaluation of given HMM.
void hmm_normalize(hmm_t *h, int32 bestscr)
Renormalize the scores in this HMM based on the given best score.
hmm_context_t * hmm_context_init(int32 n_emit_state, uint8 **const *tp, int16 const *senscore, uint16 *const *sseq)
Create an HMM context.
#define WORST_SCORE
Large "bad" score.
Shared information between a set of HMMs.
void hmm_enter(hmm_t *h, int32 score, int32 histid, int frame)
Enter an HMM with the given path score and history ID.
void hmm_dump(hmm_t *h, FILE *fp)
For debugging, dump the whole HMM out.
#define WORSE_THAN
Is one score worse than another?
void hmm_clear(hmm_t *h)
Reset the states of the HMM to the invalid condition.
#define TMAT_WORST_SCORE
Watch out, though! Transition matrix entries that are supposed to be "zero" don't actually get that...
#define BETTER_THAN
Is one score better than another?
void hmm_clear_scores(hmm_t *h)
Reset the scores of the HMM.
void hmm_context_free(hmm_context_t *ctx)
Free an HMM context.