Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions src/state_align_search.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,12 @@ prune_hmms(state_align_search_t *sas, int frame_idx)
hmm_t *hmm = sas->hmms + i;
if (hmm_frame(hmm) < frame_idx)
continue;
/* Enforce alignment constraint: due to non-emitting states,
* previous phone's HMM remains active in first frame of its
* successor. */
if (nf > sas->ef[i])
/* ef[i] is the exclusive end frame (= start + duration).
* Once nf reaches ef[i] the phone has used its full window;
* stop advancing so it is not scored in the next frame.
* phone_transition is allowed to fire at this last active
* frame via the complementary check in phone_transition. */
if (nf >= sas->ef[i])
continue;
hmm_frame(hmm) = nf;
}
Expand All @@ -114,18 +116,30 @@ phone_transition(state_align_search_t *sas, int frame_idx)
int32 newphone_score;

hmm = sas->hmms + i;
if (hmm_frame(hmm) != nf)
/* Allow transition from phones that were active this frame,
* whether they were advanced to nf (normal case) or left at
* frame_idx by prune_hmms because they hit their ef boundary.
* The original check (hmm_frame != nf) silently blocked
* cross-word transitions when the phone was evaluated at
* exactly its last allowed frame. */
if (hmm_frame(hmm) < frame_idx)
continue;
/* Enforce alignment constraint for initial state of each phone. */
if (nf < sas->sf[i + 1])
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)) {
if (hmm_frame(nhmm) < frame_idx) {
/* Successor is inactive: enter it fresh with the new frame. */
hmm_enter(nhmm, newphone_score, hmm_out_history(hmm), nf);
continue;
}
/* Successor is already active: update score/history only (Viterbi
* competition), never bump its hmm_frame to a later value. */
if (newphone_score BETTER_THAN hmm_in_score(nhmm)) {
hmm_in_score(nhmm) = newphone_score;
hmm_in_history(nhmm) = hmm_out_history(hmm);
}
}
}
Expand Down Expand Up @@ -243,7 +257,7 @@ state_align_search_finish(ps_search_t *search)
ent = ps_alignment_iter_get(itor);
ent->start = cur_frame + 1;
ent->duration = last_frame - ent->start;
ent->score = last.score - cur.score;
ent->score = last.score - cur.score;
E_DEBUG("state %d start %d end %d\n", last.id,
ent->start, last_frame);
last = cur;
Expand Down Expand Up @@ -458,7 +472,7 @@ state_align_search_init(const char *name,
++i, itor = ps_alignment_iter_next(itor)) {
ps_alignment_entry_t *ent = ps_alignment_iter_get(itor);
int min_nframes;

hmm_init(sas->hmmctx, &sas->hmms[i], FALSE,
ent->id.pid.ssid, ent->id.pid.tmatid);
/* Can't align less than the number of frames in an HMM! */
Expand Down
Loading