void hmm_dump(hmm_t * hmm, FILE * fp) { int32 i; if (hmm_is_mpx(hmm)) { fprintf(fp, "MPX "); for (i = 0; i < hmm_n_emit_state(hmm); i++) fprintf(fp, " %11d", hmm_senid(hmm, i)); fprintf(fp, " ( "); for (i = 0; i < hmm_n_emit_state(hmm); i++) fprintf(fp, "%d ", hmm_ssid(hmm, i)); fprintf(fp, ")\n"); } else { fprintf(fp, "SSID "); for (i = 0; i < hmm_n_emit_state(hmm); i++) fprintf(fp, " %11d", hmm_senid(hmm, i)); fprintf(fp, " (%d)\n", hmm_ssid(hmm, 0)); } if (hmm->ctx->senscore) { fprintf(fp, "SENSCR"); for (i = 0; i < hmm_n_emit_state(hmm); i++) fprintf(fp, " %11d", hmm_senscr(hmm, i)); fprintf(fp, "\n"); } fprintf(fp, "SCORES %11d", hmm_in_score(hmm)); for (i = 1; i < hmm_n_emit_state(hmm); i++) fprintf(fp, " %11d", hmm_score(hmm, i)); fprintf(fp, " %11d", hmm_out_score(hmm)); fprintf(fp, "\n"); fprintf(fp, "HISTID %11d", hmm_in_history(hmm)); for (i = 1; i < hmm_n_emit_state(hmm); i++) fprintf(fp, " %11d", hmm_history(hmm, i)); fprintf(fp, " %11d", hmm_out_history(hmm)); fprintf(fp, "\n"); if (hmm_in_score(hmm) > 0) fprintf(fp, "ALERT!! The input score %d is large than 0. Probably wrap around.\n", hmm_in_score(hmm)); if (hmm_out_score(hmm) > 0) fprintf(fp, "ALERT!! The output score %d is large than 0. Probably wrap around\n.", hmm_out_score(hmm)); fflush(fp); }
static void phone_transition(phone_loop_search_t *pls, int frame_idx) { int32 thresh = pls->best_score + pls->pbeam; int nf = frame_idx + 1; int i; /* Now transition out of phones whose last states are inside the * phone transition beam. */ for (i = 0; i < pls->n_phones; ++i) { hmm_t *hmm = (hmm_t *)&pls->phones[i]; int32 newphone_score; int j; if (hmm_frame(hmm) != nf) continue; newphone_score = hmm_out_score(hmm) + pls->pip; if (newphone_score BETTER_THAN thresh) { /* Transition into all phones using the usual Viterbi rule. */ for (j = 0; j < pls->n_phones; ++j) { hmm_t *nhmm = (hmm_t *)&pls->phones[j]; if (hmm_frame(nhmm) < frame_idx || newphone_score BETTER_THAN hmm_in_score(nhmm)) { hmm_enter(nhmm, newphone_score, hmm_out_history(hmm), nf); } } } } }
void hmm_enter_obj(hmm_t *h, int32 score, void *histobj, int32 frame) { hmm_in_score(h) = score; hmm_in_histobj(h) = histobj; hmm_frame(h) = frame; }
void hmm_enter(hmm_t *h, int32 score, int32 histid, int frame) { hmm_in_score(h) = score; hmm_in_history(h) = histid; hmm_frame(h) = frame; }
void hmm_clear_scores(hmm_t * h) { int32 i; hmm_in_score(h) = WORST_SCORE; for (i = 1; i < hmm_n_emit_state(h); i++) hmm_score(h, i) = WORST_SCORE; hmm_out_score(h) = WORST_SCORE; h->bestscore = WORST_SCORE; }
void hmm_clear(hmm_t * h) { int32 i; hmm_in_score(h) = WORST_SCORE; hmm_in_history(h) = -1; for (i = 1; i < hmm_n_emit_state(h); i++) { hmm_score(h, i) = WORST_SCORE; hmm_history(h, i) = -1; } hmm_out_score(h) = WORST_SCORE; hmm_out_history(h) = -1; h->bestscore = WORST_SCORE; h->frame = -1; }
static void phone_transition(state_align_search_t *sas, int frame_idx) { int nf = frame_idx + 1; int i; for (i = 0; i < sas->n_phones - 1; ++i) { hmm_t *hmm, *nhmm; int32 newphone_score; hmm = sas->hmms + i; if (hmm_frame(hmm) != nf) continue; newphone_score = hmm_out_score(hmm); /* Transition into next phone using the usual Viterbi rule. */ nhmm = hmm + 1; if (hmm_frame(nhmm) < frame_idx || newphone_score BETTER_THAN hmm_in_score(nhmm)) { hmm_enter(nhmm, newphone_score, hmm_out_history(hmm), nf); } } }
static int32 hmm_vit_eval_anytopo(hmm_t * hmm) { hmm_context_t *ctx = hmm->ctx; int32 to, from, bestfrom; int32 newscr, scr, bestscr; int final_state; /* Compute previous state-score + observation output prob for each emitting state */ ctx->st_sen_scr[0] = hmm_in_score(hmm) + hmm_senscr(hmm, 0); for (from = 1; from < hmm_n_emit_state(hmm); ++from) { if ((ctx->st_sen_scr[from] = hmm_score(hmm, from) + hmm_senscr(hmm, from)) WORSE_THAN WORST_SCORE) ctx->st_sen_scr[from] = WORST_SCORE; } /* FIXME/TODO: Use the BLAS for all this. */ /* Evaluate final-state first, which does not have a self-transition */ final_state = hmm_n_emit_state(hmm); to = final_state; scr = WORST_SCORE; bestfrom = -1; for (from = to - 1; from >= 0; --from) { if ((hmm_tprob(hmm, from, to) BETTER_THAN TMAT_WORST_SCORE) && ((newscr = ctx->st_sen_scr[from] + hmm_tprob(hmm, from, to)) BETTER_THAN scr)) { scr = newscr; bestfrom = from; } } hmm_out_score(hmm) = scr; if (bestfrom >= 0) hmm_out_history(hmm) = hmm_history(hmm, bestfrom); bestscr = scr; /* Evaluate all other states, which might have self-transitions */ for (to = final_state - 1; to >= 0; --to) { /* Score from self-transition, if any */ scr = (hmm_tprob(hmm, to, to) BETTER_THAN TMAT_WORST_SCORE) ? ctx->st_sen_scr[to] + hmm_tprob(hmm, to, to) : WORST_SCORE; /* Scores from transitions from other states */ bestfrom = -1; for (from = to - 1; from >= 0; --from) { if ((hmm_tprob(hmm, from, to) BETTER_THAN TMAT_WORST_SCORE) && ((newscr = ctx->st_sen_scr[from] + hmm_tprob(hmm, from, to)) BETTER_THAN scr)) { scr = newscr; bestfrom = from; } } /* Update new result for state to */ if (to == 0) { hmm_in_score(hmm) = scr; if (bestfrom >= 0) hmm_in_history(hmm) = hmm_history(hmm, bestfrom); } else { hmm_score(hmm, to) = scr; if (bestfrom >= 0) hmm_history(hmm, to) = hmm_history(hmm, bestfrom); } /* Propagate ssid for multiplex HMMs */ if (bestfrom >= 0 && hmm_is_mpx(hmm)) hmm->senid[to] = hmm->senid[bestfrom]; if (bestscr WORSE_THAN scr) bestscr = scr; } hmm_bestscore(hmm) = bestscr; return bestscr; }
static int32 hmm_vit_eval_3st_lr_mpx(hmm_t * hmm) { uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0]; int16 const *senscore = hmm->ctx->senscore; uint16 * const *sseq = hmm->ctx->sseq; uint16 *ssid = hmm->senid; int32 bestScore; int32 s3, s2, s1, s0, t2, t1, t0; /* Don't propagate WORST_SCORE */ t2 = INT_MIN; /* Not used unless skipstate is true */ if (ssid[2] == BAD_SSID) s2 = t1 = WORST_SCORE; else { s2 = hmm_score(hmm, 2) + mpx_senscr(2); t1 = s2 + hmm_tprob_3st(2, 3); } if (ssid[1] == BAD_SSID) s1 = t2 = WORST_SCORE; else { s1 = hmm_score(hmm, 1) + mpx_senscr(1); if (hmm_tprob_3st(1,3) BETTER_THAN TMAT_WORST_SCORE) t2 = s1 + hmm_tprob_3st(1, 3); } if (t1 BETTER_THAN t2) { s3 = t1; hmm_out_history(hmm) = hmm_history(hmm, 2); } else { s3 = t2; hmm_out_history(hmm) = hmm_history(hmm, 1); } if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE; hmm_out_score(hmm) = s3; bestScore = s3; /* State 0 is always active */ s0 = hmm_in_score(hmm) + mpx_senscr(0); /* Don't propagate WORST_SCORE */ t0 = t1 = WORST_SCORE; if (s2 != WORST_SCORE) t0 = s2 + hmm_tprob_3st(2, 2); if (s1 != WORST_SCORE) t1 = s1 + hmm_tprob_3st(1, 2); if (hmm_tprob_3st(0,2) BETTER_THAN TMAT_WORST_SCORE) t2 = s0 + hmm_tprob_3st(0, 2); if (t0 BETTER_THAN t1) { if (t2 BETTER_THAN t0) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); ssid[2] = ssid[0]; } else s2 = t0; } else { if (t2 BETTER_THAN t1) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); ssid[2] = ssid[0]; } else { s2 = t1; hmm_history(hmm, 2) = hmm_history(hmm, 1); ssid[2] = ssid[1]; } } if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE; if (s2 BETTER_THAN bestScore) bestScore = s2; hmm_score(hmm, 2) = s2; /* Don't propagate WORST_SCORE */ t0 = WORST_SCORE; if (s1 != WORST_SCORE) t0 = s1 + hmm_tprob_3st(1, 1); t1 = s0 + hmm_tprob_3st(0, 1); if (t0 BETTER_THAN t1) { s1 = t0; } else { s1 = t1; hmm_history(hmm, 1) = hmm_in_history(hmm); ssid[1] = ssid[0]; } if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE; if (s1 BETTER_THAN bestScore) bestScore = s1; hmm_score(hmm, 1) = s1; /* State 0 is always active */ s0 += hmm_tprob_3st(0, 0); if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE; if (s0 BETTER_THAN bestScore) bestScore = s0; hmm_in_score(hmm) = s0; hmm_bestscore(hmm) = bestScore; return bestScore; }
static int32 hmm_vit_eval_3st_lr(hmm_t * hmm) { int16 const *senscore = hmm->ctx->senscore; uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0]; uint16 const *sseq = hmm->senid; int32 s3, s2, s1, s0, t2, t1, t0, bestScore; s2 = hmm_score(hmm, 2) + nonmpx_senscr(2); s1 = hmm_score(hmm, 1) + nonmpx_senscr(1); s0 = hmm_in_score(hmm) + nonmpx_senscr(0); /* It was the best of scores, it was the worst of scores. */ bestScore = WORST_SCORE; t2 = INT_MIN; /* Not used unless skipstate is true */ /* Transitions into non-emitting state 3 */ if (s1 BETTER_THAN WORST_SCORE) { t1 = s2 + hmm_tprob_3st(2, 3); if (hmm_tprob_3st(1,3) BETTER_THAN TMAT_WORST_SCORE) t2 = s1 + hmm_tprob_3st(1, 3); if (t1 BETTER_THAN t2) { s3 = t1; hmm_out_history(hmm) = hmm_history(hmm, 2); } else { s3 = t2; hmm_out_history(hmm) = hmm_history(hmm, 1); } if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE; hmm_out_score(hmm) = s3; bestScore = s3; } /* All transitions into state 2 (state 0 is always active) */ t0 = s2 + hmm_tprob_3st(2, 2); t1 = s1 + hmm_tprob_3st(1, 2); if (hmm_tprob_3st(0, 2) BETTER_THAN TMAT_WORST_SCORE) t2 = s0 + hmm_tprob_3st(0, 2); if (t0 BETTER_THAN t1) { if (t2 BETTER_THAN t0) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); } else s2 = t0; } else { if (t2 BETTER_THAN t1) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); } else { s2 = t1; hmm_history(hmm, 2) = hmm_history(hmm, 1); } } if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE; if (s2 BETTER_THAN bestScore) bestScore = s2; hmm_score(hmm, 2) = s2; /* All transitions into state 1 */ t0 = s1 + hmm_tprob_3st(1, 1); t1 = s0 + hmm_tprob_3st(0, 1); if (t0 BETTER_THAN t1) { s1 = t0; } else { s1 = t1; hmm_history(hmm, 1) = hmm_in_history(hmm); } if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE; if (s1 BETTER_THAN bestScore) bestScore = s1; hmm_score(hmm, 1) = s1; /* All transitions into state 0 */ s0 = s0 + hmm_tprob_3st(0, 0); if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE; if (s0 BETTER_THAN bestScore) bestScore = s0; hmm_in_score(hmm) = s0; hmm_bestscore(hmm) = bestScore; return bestScore; }
static int32 hmm_vit_eval_5st_lr_mpx(hmm_t * hmm) { uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0]; int16 const *senscore = hmm->ctx->senscore; uint16 * const *sseq = hmm->ctx->sseq; uint16 *ssid = hmm->senid; int32 bestScore; int32 s5, s4, s3, s2, s1, s0, t2, t1, t0; /* Don't propagate WORST_SCORE */ if (ssid[4] == BAD_SSID) s4 = t1 = WORST_SCORE; else { s4 = hmm_score(hmm, 4) + mpx_senscr(4); t1 = s4 + hmm_tprob_5st(4, 5); } if (ssid[3] == BAD_SSID) s3 = t2 = WORST_SCORE; else { s3 = hmm_score(hmm, 3) + mpx_senscr(3); t2 = s3 + hmm_tprob_5st(3, 5); } if (t1 BETTER_THAN t2) { s5 = t1; hmm_out_history(hmm) = hmm_history(hmm, 4); } else { s5 = t2; hmm_out_history(hmm) = hmm_history(hmm, 3); } if (s5 WORSE_THAN WORST_SCORE) s5 = WORST_SCORE; hmm_out_score(hmm) = s5; bestScore = s5; /* Don't propagate WORST_SCORE */ if (ssid[2] == BAD_SSID) s2 = t2 = WORST_SCORE; else { s2 = hmm_score(hmm, 2) + mpx_senscr(2); t2 = s2 + hmm_tprob_5st(2, 4); } t0 = t1 = WORST_SCORE; if (s4 != WORST_SCORE) t0 = s4 + hmm_tprob_5st(4, 4); if (s3 != WORST_SCORE) t1 = s3 + hmm_tprob_5st(3, 4); if (t0 BETTER_THAN t1) { if (t2 BETTER_THAN t0) { s4 = t2; hmm_history(hmm, 4) = hmm_history(hmm, 2); ssid[4] = ssid[2]; } else s4 = t0; } else { if (t2 BETTER_THAN t1) { s4 = t2; hmm_history(hmm, 4) = hmm_history(hmm, 2); ssid[4] = ssid[2]; } else { s4 = t1; hmm_history(hmm, 4) = hmm_history(hmm, 3); ssid[4] = ssid[3]; } } if (s4 WORSE_THAN WORST_SCORE) s4 = WORST_SCORE; if (s4 BETTER_THAN bestScore) bestScore = s4; hmm_score(hmm, 4) = s4; /* Don't propagate WORST_SCORE */ if (ssid[1] == BAD_SSID) s1 = t2 = WORST_SCORE; else { s1 = hmm_score(hmm, 1) + mpx_senscr(1); t2 = s1 + hmm_tprob_5st(1, 3); } t0 = t1 = WORST_SCORE; if (s3 != WORST_SCORE) t0 = s3 + hmm_tprob_5st(3, 3); if (s2 != WORST_SCORE) t1 = s2 + hmm_tprob_5st(2, 3); if (t0 BETTER_THAN t1) { if (t2 BETTER_THAN t0) { s3 = t2; hmm_history(hmm, 3) = hmm_history(hmm, 1); ssid[3] = ssid[1]; } else s3 = t0; } else { if (t2 BETTER_THAN t1) { s3 = t2; hmm_history(hmm, 3) = hmm_history(hmm, 1); ssid[3] = ssid[1]; } else { s3 = t1; hmm_history(hmm, 3) = hmm_history(hmm, 2); ssid[3] = ssid[2]; } } if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE; if (s3 BETTER_THAN bestScore) bestScore = s3; hmm_score(hmm, 3) = s3; /* State 0 is always active */ s0 = hmm_in_score(hmm) + mpx_senscr(0); /* Don't propagate WORST_SCORE */ t0 = t1 = WORST_SCORE; if (s2 != WORST_SCORE) t0 = s2 + hmm_tprob_5st(2, 2); if (s1 != WORST_SCORE) t1 = s1 + hmm_tprob_5st(1, 2); t2 = s0 + hmm_tprob_5st(0, 2); if (t0 BETTER_THAN t1) { if (t2 BETTER_THAN t0) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); ssid[2] = ssid[0]; } else s2 = t0; } else { if (t2 BETTER_THAN t1) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); ssid[2] = ssid[0]; } else { s2 = t1; hmm_history(hmm, 2) = hmm_history(hmm, 1); ssid[2] = ssid[1]; } } if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE; if (s2 BETTER_THAN bestScore) bestScore = s2; hmm_score(hmm, 2) = s2; /* Don't propagate WORST_SCORE */ t0 = WORST_SCORE; if (s1 != WORST_SCORE) t0 = s1 + hmm_tprob_5st(1, 1); t1 = s0 + hmm_tprob_5st(0, 1); if (t0 BETTER_THAN t1) { s1 = t0; } else { s1 = t1; hmm_history(hmm, 1) = hmm_in_history(hmm); ssid[1] = ssid[0]; } if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE; if (s1 BETTER_THAN bestScore) bestScore = s1; hmm_score(hmm, 1) = s1; s0 += hmm_tprob_5st(0, 0); if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE; if (s0 BETTER_THAN bestScore) bestScore = s0; hmm_in_score(hmm) = s0; hmm_bestscore(hmm) = bestScore; return bestScore; }
static int32 hmm_vit_eval_5st_lr(hmm_t * hmm) { int16 const *senscore = hmm->ctx->senscore; uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0]; uint16 const *sseq = hmm->senid; int32 s5, s4, s3, s2, s1, s0, t2, t1, t0, bestScore; /* It was the best of scores, it was the worst of scores. */ bestScore = WORST_SCORE; /* Cache problem here! */ s4 = hmm_score(hmm, 4) + nonmpx_senscr(4); s3 = hmm_score(hmm, 3) + nonmpx_senscr(3); /* Transitions into non-emitting state 5 */ if (s3 BETTER_THAN WORST_SCORE) { t1 = s4 + hmm_tprob_5st(4, 5); t2 = s3 + hmm_tprob_5st(3, 5); if (t1 BETTER_THAN t2) { s5 = t1; hmm_out_history(hmm) = hmm_history(hmm, 4); } else { s5 = t2; hmm_out_history(hmm) = hmm_history(hmm, 3); } if (s5 WORSE_THAN WORST_SCORE) s5 = WORST_SCORE; hmm_out_score(hmm) = s5; bestScore = s5; } s2 = hmm_score(hmm, 2) + nonmpx_senscr(2); /* All transitions into state 4 */ if (s2 BETTER_THAN WORST_SCORE) { t0 = s4 + hmm_tprob_5st(4, 4); t1 = s3 + hmm_tprob_5st(3, 4); t2 = s2 + hmm_tprob_5st(2, 4); if (t0 BETTER_THAN t1) { if (t2 BETTER_THAN t0) { s4 = t2; hmm_history(hmm, 4) = hmm_history(hmm, 2); } else s4 = t0; } else { if (t2 BETTER_THAN t1) { s4 = t2; hmm_history(hmm, 4) = hmm_history(hmm, 2); } else { s4 = t1; hmm_history(hmm, 4) = hmm_history(hmm, 3); } } if (s4 WORSE_THAN WORST_SCORE) s4 = WORST_SCORE; if (s4 BETTER_THAN bestScore) bestScore = s4; hmm_score(hmm, 4) = s4; } s1 = hmm_score(hmm, 1) + nonmpx_senscr(1); /* All transitions into state 3 */ if (s1 BETTER_THAN WORST_SCORE) { t0 = s3 + hmm_tprob_5st(3, 3); t1 = s2 + hmm_tprob_5st(2, 3); t2 = s1 + hmm_tprob_5st(1, 3); if (t0 BETTER_THAN t1) { if (t2 BETTER_THAN t0) { s3 = t2; hmm_history(hmm, 3) = hmm_history(hmm, 1); } else s3 = t0; } else { if (t2 BETTER_THAN t1) { s3 = t2; hmm_history(hmm, 3) = hmm_history(hmm, 1); } else { s3 = t1; hmm_history(hmm, 3) = hmm_history(hmm, 2); } } if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE; if (s3 BETTER_THAN bestScore) bestScore = s3; hmm_score(hmm, 3) = s3; } s0 = hmm_in_score(hmm) + nonmpx_senscr(0); /* All transitions into state 2 (state 0 is always active) */ t0 = s2 + hmm_tprob_5st(2, 2); t1 = s1 + hmm_tprob_5st(1, 2); t2 = s0 + hmm_tprob_5st(0, 2); if (t0 BETTER_THAN t1) { if (t2 BETTER_THAN t0) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); } else s2 = t0; } else { if (t2 BETTER_THAN t1) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); } else { s2 = t1; hmm_history(hmm, 2) = hmm_history(hmm, 1); } } if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE; if (s2 BETTER_THAN bestScore) bestScore = s2; hmm_score(hmm, 2) = s2; /* All transitions into state 1 */ t0 = s1 + hmm_tprob_5st(1, 1); t1 = s0 + hmm_tprob_5st(0, 1); if (t0 BETTER_THAN t1) { s1 = t0; } else { s1 = t1; hmm_history(hmm, 1) = hmm_in_history(hmm); } if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE; if (s1 BETTER_THAN bestScore) bestScore = s1; hmm_score(hmm, 1) = s1; /* All transitions into state 0 */ s0 = s0 + hmm_tprob_5st(0, 0); if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE; if (s0 BETTER_THAN bestScore) bestScore = s0; hmm_in_score(hmm) = s0; hmm_bestscore(hmm) = bestScore; return bestScore; }
static int32 hmm_vit_eval_5st_lr(hmm_t * hmm) { const int32 *senscore = hmm->ctx->senscore; const int32 *tp = hmm->ctx->tp[hmm->tmatid][0]; const s3senid_t *sseq = hmm->ctx->sseq[hmm_ssid(hmm, 0)]; int32 s5, s4, s3, s2, s1, s0, t2, t1, t0, bestScore; /* It was the best of scores, it was the worst of scores. */ bestScore = WORST_SCORE; s4 = hmm_score(hmm, 4) + nonmpx_senscr(4); s3 = hmm_score(hmm, 3) + nonmpx_senscr(3); /* Transitions into non-emitting state 5 */ if (s3 > WORST_SCORE) { t1 = s4 + hmm_tprob_5st(4, 5); t2 = s3 + hmm_tprob_5st(3, 5); if (t1 > t2) { s5 = t1; hmm_out_history(hmm) = hmm_history(hmm, 4); } else { s5 = t2; hmm_out_history(hmm) = hmm_history(hmm, 3); } if (s5 < WORST_SCORE) s5 = WORST_SCORE; hmm_out_score(hmm) = s5; bestScore = s5; } s2 = hmm_score(hmm, 2) + nonmpx_senscr(2); /* All transitions into state 4 */ if (s2 > WORST_SCORE) { t0 = s4 + hmm_tprob_5st(4, 4); t1 = s3 + hmm_tprob_5st(3, 4); t2 = s2 + hmm_tprob_5st(2, 4); if (t0 > t1) { if (t2 > t0) { s4 = t2; hmm_history(hmm, 4) = hmm_history(hmm, 2); } else s4 = t0; } else { if (t2 > t1) { s4 = t2; hmm_history(hmm, 4) = hmm_history(hmm, 2); } else { s4 = t1; hmm_history(hmm, 4) = hmm_history(hmm, 3); } } if (s4 < WORST_SCORE) s4 = WORST_SCORE; if (s4 > bestScore) bestScore = s4; hmm_score(hmm, 4) = s4; } s1 = hmm_score(hmm, 1) + nonmpx_senscr(1); /* All transitions into state 3 */ if (s1 > WORST_SCORE) { t0 = s3 + hmm_tprob_5st(3, 3); t1 = s2 + hmm_tprob_5st(2, 3); t2 = s1 + hmm_tprob_5st(1, 3); if (t0 > t1) { if (t2 > t0) { s3 = t2; hmm_history(hmm, 3) = hmm_history(hmm, 1); } else s3 = t0; } else { if (t2 > t1) { s3 = t2; hmm_history(hmm, 3) = hmm_history(hmm, 1); } else { s3 = t1; hmm_history(hmm, 3) = hmm_history(hmm, 2); } } if (s3 < WORST_SCORE) s3 = WORST_SCORE; if (s3 > bestScore) bestScore = s3; hmm_score(hmm, 3) = s3; } s0 = hmm_in_score(hmm) + nonmpx_senscr(0); /* All transitions into state 2 (state 0 is always active) */ t0 = s2 + hmm_tprob_5st(2, 2); t1 = s1 + hmm_tprob_5st(1, 2); t2 = s0 + hmm_tprob_5st(0, 2); if (t0 > t1) { if (t2 > t0) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); } else s2 = t0; } else { if (t2 > t1) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); } else { s2 = t1; hmm_history(hmm, 2) = hmm_history(hmm, 1); } } if (s2 < WORST_SCORE) s2 = WORST_SCORE; if (s2 > bestScore) bestScore = s2; hmm_score(hmm, 2) = s2; /* All transitions into state 1 */ t0 = s1 + hmm_tprob_5st(1, 1); t1 = s0 + hmm_tprob_5st(0, 1); if (t0 > t1) { s1 = t0; } else { s1 = t1; hmm_history(hmm, 1) = hmm_in_history(hmm); } if (s1 < WORST_SCORE) s1 = WORST_SCORE; if (s1 > bestScore) bestScore = s1; hmm_score(hmm, 1) = s1; /* All transitions into state 0 */ s0 = s0 + hmm_tprob_5st(0, 0); if (s0 < WORST_SCORE) s0 = WORST_SCORE; if (s0 > bestScore) bestScore = s0; hmm_in_score(hmm) = s0; hmm_bestscore(hmm) = bestScore; return bestScore; }
static int32 hmm_vit_eval_5st_lr_mpx(hmm_t * hmm) { const int32 *tp = hmm->ctx->tp[hmm->tmatid][0]; const int32 *senscore = hmm->ctx->senscore; const s3senid_t **sseq = hmm->ctx->sseq; int32 *ssid = hmm->s.mpx_ssid; int32 bestScore; int32 s5, s4, s3, s2, s1, s0, t2, t1, t0; /* Don't propagate WORST_SCORE */ if (ssid[4] == -1) s4 = t1 = WORST_SCORE; else { s4 = hmm_score(hmm, 4) + mpx_senscr(4); t1 = s4 + hmm_tprob_5st(4, 5); } if (ssid[3] == -1) s3 = t2 = WORST_SCORE; else { s3 = hmm_score(hmm, 3) + mpx_senscr(3); t2 = s3 + hmm_tprob_5st(3, 5); } if (t1 > t2) { s5 = t1; hmm_out_history(hmm) = hmm_history(hmm, 4); } else { s5 = t2; hmm_out_history(hmm) = hmm_history(hmm, 3); } if (s5 < WORST_SCORE) s5 = WORST_SCORE; hmm_out_score(hmm) = s5; bestScore = s5; /* Don't propagate WORST_SCORE */ if (ssid[2] == -1) s2 = t2 = WORST_SCORE; else { s2 = hmm_score(hmm, 2) + mpx_senscr(2); t2 = s2 + hmm_tprob_5st(2, 4); } t0 = t1 = WORST_SCORE; if (s4 != WORST_SCORE) t0 = s4 + hmm_tprob_5st(4, 4); if (s3 != WORST_SCORE) t1 = s3 + hmm_tprob_5st(3, 4); if (t0 > t1) { if (t2 > t0) { s4 = t2; hmm_history(hmm, 4) = hmm_history(hmm, 2); ssid[4] = ssid[2]; } else s4 = t0; } else { if (t2 > t1) { s4 = t2; hmm_history(hmm, 4) = hmm_history(hmm, 2); ssid[4] = ssid[2]; } else { s4 = t1; hmm_history(hmm, 4) = hmm_history(hmm, 3); ssid[4] = ssid[3]; } } if (s4 < WORST_SCORE) s4 = WORST_SCORE; if (s4 > bestScore) bestScore = s4; hmm_score(hmm, 4) = s4; /* Don't propagate WORST_SCORE */ if (ssid[1] == -1) s1 = t2 = WORST_SCORE; else { s1 = hmm_score(hmm, 1) + mpx_senscr(1); t2 = s1 + hmm_tprob_5st(1, 3); } t0 = t1 = WORST_SCORE; if (s3 != WORST_SCORE) t0 = s3 + hmm_tprob_5st(3, 3); if (s2 != WORST_SCORE) t1 = s2 + hmm_tprob_5st(2, 3); if (t0 > t1) { if (t2 > t0) { s3 = t2; hmm_history(hmm, 3) = hmm_history(hmm, 1); ssid[3] = ssid[1]; } else s3 = t0; } else { if (t2 > t1) { s3 = t2; hmm_history(hmm, 3) = hmm_history(hmm, 1); ssid[3] = ssid[1]; } else { s3 = t1; hmm_history(hmm, 3) = hmm_history(hmm, 2); ssid[3] = ssid[2]; } } if (s3 < WORST_SCORE) s3 = WORST_SCORE; if (s3 > bestScore) bestScore = s3; hmm_score(hmm, 3) = s3; /* State 0 is always active */ s0 = hmm_in_score(hmm) + mpx_senscr(0); /* Don't propagate WORST_SCORE */ t0 = t1 = WORST_SCORE; if (s2 != WORST_SCORE) t0 = s2 + hmm_tprob_5st(2, 2); if (s1 != WORST_SCORE) t1 = s1 + hmm_tprob_5st(1, 2); t2 = s0 + hmm_tprob_5st(0, 2); if (t0 > t1) { if (t2 > t0) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); ssid[2] = ssid[0]; } else s2 = t0; } else { if (t2 > t1) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); ssid[2] = ssid[0]; } else { s2 = t1; hmm_history(hmm, 2) = hmm_history(hmm, 1); ssid[2] = ssid[1]; } } if (s2 < WORST_SCORE) s2 = WORST_SCORE; if (s2 > bestScore) bestScore = s2; hmm_score(hmm, 2) = s2; /* Don't propagate WORST_SCORE */ t0 = WORST_SCORE; if (s1 != WORST_SCORE) t0 = s1 + hmm_tprob_5st(1, 1); t1 = s0 + hmm_tprob_5st(0, 1); if (t0 > t1) { s1 = t0; } else { s1 = t1; hmm_history(hmm, 1) = hmm_in_history(hmm); ssid[1] = ssid[0]; } if (s1 < WORST_SCORE) s1 = WORST_SCORE; if (s1 > bestScore) bestScore = s1; hmm_score(hmm, 1) = s1; s0 += hmm_tprob_5st(0, 0); if (s0 < WORST_SCORE) s0 = WORST_SCORE; if (s0 > bestScore) bestScore = s0; hmm_in_score(hmm) = s0; hmm_bestscore(hmm) = bestScore; return bestScore; }
static void fwdflat_word_transition(ngram_search_t *ngs, int frame_idx) { int32 cf, nf, b, thresh, pip, i, w, newscore; int32 best_silrc_score = 0, best_silrc_bp = 0; /* FIXME: good defaults? */ bptbl_t *bp; int32 *rcss; root_chan_t *rhmm; int32 *awl; float32 lwf; dict_t *dict = ps_search_dict(ngs); dict2pid_t *d2p = ps_search_dict2pid(ngs); cf = frame_idx; nf = cf + 1; thresh = ngs->best_score + ngs->fwdflatbeam; pip = ngs->pip; best_silrc_score = WORST_SCORE; lwf = ngs->fwdflat_fwdtree_lw_ratio; /* Search for all words starting within a window of this frame. * These are the successors for words exiting now. */ get_expand_wordlist(ngs, cf, ngs->max_sf_win); /* Scan words exited in current frame */ for (b = ngs->bp_table_idx[cf]; b < ngs->bpidx; b++) { xwdssid_t *rssid; int32 silscore; bp = ngs->bp_table + b; ngs->word_lat_idx[bp->wid] = NO_BP; if (bp->wid == ps_search_finish_wid(ngs)) continue; /* DICT2PID location */ /* Get the mapping from right context phone ID to index in the * right context table and the bscore_stack. */ rcss = ngs->bscore_stack + bp->s_idx; if (bp->last2_phone == -1) rssid = NULL; else rssid = dict2pid_rssid(d2p, bp->last_phone, bp->last2_phone); /* Transition to all successor words. */ for (i = 0; ngs->expand_word_list[i] >= 0; i++) { int32 n_used; w = ngs->expand_word_list[i]; /* Get the exit score we recorded in save_bwd_ptr(), or * something approximating it. */ if (rssid) newscore = rcss[rssid->cimap[dict_first_phone(dict, w)]]; else newscore = bp->score; if (newscore == WORST_SCORE) continue; /* FIXME: Floating point... */ newscore += lwf * (ngram_tg_score(ngs->lmset, dict_basewid(dict, w), bp->real_wid, bp->prev_real_wid, &n_used) >> SENSCR_SHIFT); newscore += pip; /* Enter the next word */ if (newscore BETTER_THAN thresh) { rhmm = (root_chan_t *) ngs->word_chan[w]; if ((hmm_frame(&rhmm->hmm) < cf) || (newscore BETTER_THAN hmm_in_score(&rhmm->hmm))) { hmm_enter(&rhmm->hmm, newscore, b, nf); /* DICT2PID: This is where mpx ssids get introduced. */ /* Look up the ssid to use when entering this mpx triphone. */ hmm_mpx_ssid(&rhmm->hmm, 0) = dict2pid_ldiph_lc(d2p, rhmm->ciphone, rhmm->ci2phone, dict_last_phone(dict, bp->wid)); assert(IS_S3SSID(hmm_mpx_ssid(&rhmm->hmm, 0))); E_DEBUG(6,("ssid %d(%d,%d) = %d\n", rhmm->ciphone, dict_last_phone(dict, bp->wid), rhmm->ci2phone, hmm_mpx_ssid(&rhmm->hmm, 0))); bitvec_set(ngs->word_active, w); } } } /* Get the best exit into silence. */ if (rssid) silscore = rcss[rssid->cimap[ps_search_acmod(ngs)->mdef->sil]]; else silscore = bp->score; if (silscore BETTER_THAN best_silrc_score) { best_silrc_score = silscore; best_silrc_bp = b; } } /* Transition to <sil> */ newscore = best_silrc_score + ngs->silpen + pip; if ((newscore BETTER_THAN thresh) && (newscore BETTER_THAN WORST_SCORE)) { w = ps_search_silence_wid(ngs); rhmm = (root_chan_t *) ngs->word_chan[w]; if ((hmm_frame(&rhmm->hmm) < cf) || (newscore BETTER_THAN hmm_in_score(&rhmm->hmm))) { hmm_enter(&rhmm->hmm, newscore, best_silrc_bp, nf); bitvec_set(ngs->word_active, w); } } /* Transition to noise words */ newscore = best_silrc_score + ngs->fillpen + pip; if ((newscore BETTER_THAN thresh) && (newscore BETTER_THAN WORST_SCORE)) { for (w = ps_search_silence_wid(ngs) + 1; w < ps_search_n_words(ngs); w++) { rhmm = (root_chan_t *) ngs->word_chan[w]; /* Noise words that aren't a single phone will have NULL here. */ if (rhmm == NULL) continue; if ((hmm_frame(&rhmm->hmm) < cf) || (newscore BETTER_THAN hmm_in_score(&rhmm->hmm))) { hmm_enter(&rhmm->hmm, newscore, best_silrc_bp, nf); bitvec_set(ngs->word_active, w); } } } /* Reset initial channels of words that have become inactive even after word trans. */ i = ngs->n_active_word[cf & 0x1]; awl = ngs->active_word_list[cf & 0x1]; for (w = *(awl++); i > 0; --i, w = *(awl++)) { rhmm = (root_chan_t *) ngs->word_chan[w]; if (hmm_frame(&rhmm->hmm) == cf) { hmm_clear_scores(&rhmm->hmm); } } }
static void fwdflat_prune_chan(ngram_search_t *ngs, int frame_idx) { int32 i, cf, nf, w, pip, newscore, thresh, wordthresh; int32 *awl; root_chan_t *rhmm; chan_t *hmm, *nexthmm; cf = frame_idx; nf = cf + 1; i = ngs->n_active_word[cf & 0x1]; awl = ngs->active_word_list[cf & 0x1]; bitvec_clear_all(ngs->word_active, ps_search_n_words(ngs)); thresh = ngs->best_score + ngs->fwdflatbeam; wordthresh = ngs->best_score + ngs->fwdflatwbeam; pip = ngs->pip; E_DEBUG(3,("frame %d thresh %d wordthresh %d\n", frame_idx, thresh, wordthresh)); /* Scan all active words. */ for (w = *(awl++); i > 0; --i, w = *(awl++)) { rhmm = (root_chan_t *) ngs->word_chan[w]; /* Propagate active root channels */ if (hmm_frame(&rhmm->hmm) == cf && hmm_bestscore(&rhmm->hmm) BETTER_THAN thresh) { hmm_frame(&rhmm->hmm) = nf; bitvec_set(ngs->word_active, w); /* Transitions out of root channel */ newscore = hmm_out_score(&rhmm->hmm); if (rhmm->next) { assert(!dict_is_single_phone(ps_search_dict(ngs), w)); newscore += pip; if (newscore BETTER_THAN thresh) { hmm = rhmm->next; /* Enter all right context phones */ if (hmm->info.rc_id >= 0) { for (; hmm; hmm = hmm->next) { if ((hmm_frame(&hmm->hmm) < cf) || (newscore BETTER_THAN hmm_in_score(&hmm->hmm))) { hmm_enter(&hmm->hmm, newscore, hmm_out_history(&rhmm->hmm), nf); } } } /* Just a normal word internal phone */ else { if ((hmm_frame(&hmm->hmm) < cf) || (newscore BETTER_THAN hmm_in_score(&hmm->hmm))) { hmm_enter(&hmm->hmm, newscore, hmm_out_history(&rhmm->hmm), nf); } } } } else { assert(dict_is_single_phone(ps_search_dict(ngs), w)); /* Word exit for single-phone words (where did their * whmms come from?) (either from * ngram_search_fwdtree, or from * ngram_fwdflat_allocate_1ph(), that's where) */ if (newscore BETTER_THAN wordthresh) { ngram_search_save_bp(ngs, cf, w, newscore, hmm_out_history(&rhmm->hmm), 0); } } } /* Transitions out of non-root channels. */ for (hmm = rhmm->next; hmm; hmm = hmm->next) { if (hmm_frame(&hmm->hmm) >= cf) { /* Propagate forward HMMs inside the beam. */ if (hmm_bestscore(&hmm->hmm) BETTER_THAN thresh) { hmm_frame(&hmm->hmm) = nf; bitvec_set(ngs->word_active, w); newscore = hmm_out_score(&hmm->hmm); /* Word-internal phones */ if (hmm->info.rc_id < 0) { newscore += pip; if (newscore BETTER_THAN thresh) { nexthmm = hmm->next; /* Enter all right-context phones. */ if (nexthmm->info.rc_id >= 0) { for (; nexthmm; nexthmm = nexthmm->next) { if ((hmm_frame(&nexthmm->hmm) < cf) || (newscore BETTER_THAN hmm_in_score(&nexthmm->hmm))) { hmm_enter(&nexthmm->hmm, newscore, hmm_out_history(&hmm->hmm), nf); } } } /* Enter single word-internal phone. */ else { if ((hmm_frame(&nexthmm->hmm) < cf) || (newscore BETTER_THAN hmm_in_score(&nexthmm->hmm))) { hmm_enter(&nexthmm->hmm, newscore, hmm_out_history(&hmm->hmm), nf); } } } } /* Right-context phones - apply word beam and exit. */ else { if (newscore BETTER_THAN wordthresh) { ngram_search_save_bp(ngs, cf, w, newscore, hmm_out_history(&hmm->hmm), hmm->info.rc_id); } } } /* Zero out inactive HMMs. */ else if (hmm_frame(&hmm->hmm) != nf) { hmm_clear_scores(&hmm->hmm); } } } } }
static int32 hmm_vit_eval_3st_lr_mpx(hmm_t * hmm) { const int32 *tp = hmm->ctx->tp[hmm->tmatid][0]; const int32 *senscore = hmm->ctx->senscore; const s3senid_t **sseq = hmm->ctx->sseq; int32 *ssid = hmm->s.mpx_ssid; int32 bestScore; int32 s3, s2, s1, s0, t2, t1, t0; /* Don't propagate WORST_SCORE */ t2 = INT_MIN; /* Not used unless skipstate is true */ if (ssid[2] == -1) s2 = t1 = WORST_SCORE; else { s2 = hmm_score(hmm, 2) + mpx_senscr(2); if (s2 < WORST_SCORE) s2 = WORST_SCORE; t1 = s2 + hmm_tprob_3st(2, 3); } if (ssid[1] == -1) s1 = WORST_SCORE; else { s1 = hmm_score(hmm, 1) + mpx_senscr(1); if (s1 < WORST_SCORE) s1 = WORST_SCORE; t2 = s1 + hmm_tprob_3st(1, 3); } if (t1 > t2) { s3 = t1; hmm_out_history(hmm) = hmm_history(hmm, 2); } else { s3 = t2; hmm_out_history(hmm) = hmm_history(hmm, 1); } if (s3 < WORST_SCORE) s3 = WORST_SCORE; hmm_out_score(hmm) = s3; bestScore = s3; /* State 0 is always active */ s0 = hmm_in_score(hmm) + mpx_senscr(0); if (s0 < WORST_SCORE) s0 = WORST_SCORE; /* Don't propagate WORST_SCORE */ t0 = t1 = WORST_SCORE; if (s2 != WORST_SCORE) t0 = s2 + hmm_tprob_3st(2, 2); if (s1 != WORST_SCORE) t1 = s1 + hmm_tprob_3st(1, 2); if (hmm_tprob_3st(0,2) > WORST_SCORE) t2 = s0 + hmm_tprob_3st(0, 2); if (t0 > t1) { if (t2 > t0) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); ssid[2] = ssid[0]; } else s2 = t0; } else { if (t2 > t1) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); ssid[2] = ssid[0]; } else { s2 = t1; hmm_history(hmm, 2) = hmm_history(hmm, 1); ssid[2] = ssid[1]; } } if (s2 < WORST_SCORE) s2 = WORST_SCORE; if (s2 > bestScore) bestScore = s2; hmm_score(hmm, 2) = s2; /* Don't propagate WORST_SCORE */ t0 = WORST_SCORE; if (s1 != WORST_SCORE) t0 = s1 + hmm_tprob_3st(1, 1); t1 = s0 + hmm_tprob_3st(0, 1); if (t0 > t1) { s1 = t0; } else { s1 = t1; hmm_history(hmm, 1) = hmm_in_history(hmm); ssid[1] = ssid[0]; } if (s1 < WORST_SCORE) s1 = WORST_SCORE; if (s1 > bestScore) bestScore = s1; hmm_score(hmm, 1) = s1; /* State 0 is always active */ s0 += hmm_tprob_3st(0, 0); if (s0 < WORST_SCORE) s0 = WORST_SCORE; if (s0 > bestScore) bestScore = s0; hmm_in_score(hmm) = s0; hmm_bestscore(hmm) = bestScore; return bestScore; }
static int32 hmm_vit_eval_3st_lr(hmm_t * hmm) { const int32 *senscore = hmm->ctx->senscore; const int32 *tp = hmm->ctx->tp[hmm->tmatid][0]; const s3senid_t *sseq = hmm->ctx->sseq[hmm_ssid(hmm, 0)]; int32 s3, s2, s1, s0, t2, t1, t0, bestScore; s2 = hmm_score(hmm, 2) + nonmpx_senscr(2); s1 = hmm_score(hmm, 1) + nonmpx_senscr(1); s0 = hmm_in_score(hmm) + nonmpx_senscr(0); /* It was the best of scores, it was the worst of scores. */ t0 = t1 = bestScore = WORST_SCORE; t2 = INT_MIN; /* Not used unless skipstate is true */ /* Transitions into non-emitting state 3 */ if (s2 > WORST_SCORE) { t1 = s2 + hmm_tprob_3st(2, 3); t0 = s2 + hmm_tprob_3st(2, 2); } if (s1 > WORST_SCORE && hmm_tprob_3st(1,3) > WORST_SCORE) t2 = s1 + hmm_tprob_3st(1, 3); if (t1 > t2) { s3 = t1; hmm_out_history(hmm) = hmm_history(hmm, 2); } else { s3 = t2; hmm_out_history(hmm) = hmm_history(hmm, 1); } if (s3 < WORST_SCORE) s3 = WORST_SCORE; hmm_out_score(hmm) = s3; bestScore = s3; /* All transitions into state 2 (state 0 is always active) */ t1 = t2 = WORST_SCORE; if (s1 > WORST_SCORE) t1 = s1 + hmm_tprob_3st(1, 2); if (hmm_tprob_3st(0, 2) > WORST_SCORE) t2 = s0 + hmm_tprob_3st(0, 2); if (t0 > t1) { if (t2 > t0) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); } else s2 = t0; } else { if (t2 > t1) { s2 = t2; hmm_history(hmm, 2) = hmm_in_history(hmm); } else { s2 = t1; hmm_history(hmm, 2) = hmm_history(hmm, 1); } } if (s2 < WORST_SCORE) s2 = WORST_SCORE; if (s2 > bestScore) bestScore = s2; hmm_score(hmm, 2) = s2; /* All transitions into state 1 */ t0 = t1 = WORST_SCORE; if (s1 > WORST_SCORE) t0 = s1 + hmm_tprob_3st(1, 1); if (s0 > WORST_SCORE) t1 = s0 + hmm_tprob_3st(0, 1); if (t0 > t1) { s1 = t0; } else { s1 = t1; hmm_history(hmm, 1) = hmm_in_history(hmm); } if (s1 < WORST_SCORE) s1 = WORST_SCORE; if (s1 > bestScore) bestScore = s1; hmm_score(hmm, 1) = s1; /* All transitions into state 0 */ s0 = s0 + hmm_tprob_3st(0, 0); if (s0 < WORST_SCORE) s0 = WORST_SCORE; if (s0 > bestScore) bestScore = s0; hmm_in_score(hmm) = s0; hmm_bestscore(hmm) = bestScore; return bestScore; }