/* ViterbiAlign: align the segNum'th segment. For each frame k, store aligned state in states and mostly likely mix comp in mixes. Return logP. */ LogFloat ViterbiAlign(int segNum,int segLen, IntVec states, IntVec *mixes) { int currState,prevState,bestPrevState; int segIdx; LogFloat bestP,currP,tranP,prevP; Observation obs; if (trace & T_VIT) printf(" Aligning Segment Number %d\n",segNum); MakeTraceBack(segLen); /* From entry state 1: Column 1 */ obs = GetSegObs(segStore, segNum, 1); if (hset.hsKind == TIEDHS) PrecomputeTMix(&hset, &obs, 50.0, 0); for (currState=2;currState<nStates;currState++) { tranP = hmmLink->transP[1][currState]; if (tranP<LSMALL) lastP[currState] = LZERO; else lastP[currState] = tranP + OutP(&obs,hmmLink,currState); traceBack[1][currState] = 1; } if (trace & T_VIT) ShowP(1,lastP); /* Columns[2] -> Columns[segLen] -- this is the general case */ for (segIdx=2; segIdx<=segLen; segIdx++) { obs = GetSegObs(segStore, segNum, segIdx); if (hset.hsKind == TIEDHS) PrecomputeTMix(&hset, &obs, 50.0, 0); for (currState=2;currState<nStates;currState++) { bestPrevState=2; tranP = hmmLink->transP[2][currState]; prevP = lastP[2]; bestP = (tranP<LSMALL) ? LZERO : tranP+prevP; for (prevState=3;prevState<nStates;prevState++) { tranP = hmmLink->transP[prevState][currState]; prevP = lastP[prevState]; currP = (tranP<LSMALL) ? LZERO : tranP+prevP; if (currP > bestP) { bestPrevState=prevState; bestP=currP; } } if (bestP<LSMALL) currP = thisP[currState] = LZERO; else { currP = OutP(&obs,hmmLink,currState); thisP[currState] = bestP+currP; } if (trace&T_OBP) printf("OutP[s=%d,t=%d] = %f\n",currState,segIdx,currP); traceBack[segIdx][currState]=bestPrevState; } CopyVector(thisP,lastP); if (trace & T_VIT) ShowP(segIdx,lastP); } /* column[segLen]--> exit state(numStates) */ bestPrevState=2; tranP = hmmLink->transP[2][nStates]; prevP = lastP[2]; bestP=(tranP<LSMALL) ? LZERO : tranP+prevP; for (prevState=3;prevState<nStates;prevState++) { tranP = hmmLink->transP[prevState][nStates]; prevP = lastP[prevState]; currP = (tranP<LSMALL) ? LZERO : tranP+prevP; if (currP > bestP) { bestPrevState=prevState; bestP=currP; } } /* bestPrevState now gives last internal state along best state sequence */ if (bestP<LSMALL) HError(2126,"ViterbiAlign: No path found in %d'th segment",segNum); if (trace & T_VIT) { ShowTraceBack(segLen,traceBack); printf(" bestP = %12.5f via state %d\n",bestP,bestPrevState); fflush(stdout); } DoTraceBack(segLen,states,bestPrevState); if (mixes!=NULL) /* ie not DISCRETE */ FindBestMixes(segNum,segLen,states,mixes); ResetHeap( &traceBackStack ); return bestP; }
// Do traceback and if showRD then update display void ARec::TraceBackRecogniser() { int i,st,en; char *p,buf[10]; MLink m; Path *pp; float tnow,confidence,ac; int iscore; PartialPath pptb,ppcb; ppcb = CurrentBestPath(pri); // get the word that the current best path is within p=""; if (ppcb.node!=NULL && ppcb.node->wordset!=NULL) p = ppcb.node->wordset->name; // update time tnow = float((pri->frame*sampPeriod + stTime)/1e7); if (showRD){ HSetColour(win,BLACK); HSetGrey(win,PANELGREY2); HFillRectangle(win,x5-1,y4-1,x6+1,y5+1); HSetColour(win,BLACK); HPrintf(win,x5,y5,"%.1fs",tnow); } // update HMM, nactive, and score (but ignore silence) if (showRD){ m=FindMacroStruct(hset,'h',pri->genMaxNode->info.hmm); assert(m!=NULL); if (strcmp(m->id->name,"sil") != 0 && strcmp(m->id->name,"sp") != 0) { st = trbakFrame; en = pri->frame; ac = float(pri->genMaxTok.like - trbakAc); confidence = GetConfidence(pri,st+1,en,ac,""); //printf("CONFA %d->%d = %f [%f - %f = %f]\n",st,en,confidence,pri->genMaxTok.like,trbakAc,ac); trbakFrame = pri->frame; trbakAc = float(pri->genMaxTok.like); iscore = (int) (float(x7) + confidence*float(x8-x7)); if (iscore<=x7) { HSetColour(win,RED); HFillRectangle(win,x7,y4+4,x8,y5+1); }else if (iscore>=x8) { HSetColour(win,DARK_GREEN); HFillRectangle(win,x7,y4+4,x8,y5+1); }else { HSetColour(win,RED); HFillRectangle(win,iscore,y4+4,x8,y5+1); HSetColour(win,DARK_GREEN); HFillRectangle(win,x7,y4+4,iscore,y5+1); } } // update HMM HSetGrey(win,PANELGREY2); HFillRectangle(win,x10,y4-1,x11,y5+3); HSetColour(win,BLACK); HPrintf(win,x10,y5,"%s",m->id->name); // update nactive HSetGrey(win,PANELGREY2); HFillRectangle(win,x12,y4-1,x13,y5+1); HSetColour(win,BLACK); HPrintf(win,x12,y5,"%d", pri->nact); // update mode HSetGrey(win,PANELGREY2); HFillRectangle(win,x14,y4-1,x1,y5+1); HSetColour(win,BLACK); strcpy(buf," "); if (runmode&ONESHOT_MODE) buf[0] = '1'; if (runmode&CONTINUOUS_MODE) buf[0] = 'C'; if (runmode&RUN_IMMED) buf[1] = 'I'; if (runmode&FLUSH_TOMARK) buf[1] = 'M'; if (runmode&FLUSH_TOSPEECH) buf[1] = 'S'; if (runmode&STOP_IMMED) buf[2] = 'I'; if (runmode&STOP_ATMARK) buf[2] = 'M'; if (runmode&STOP_ATSIL) buf[2] = 'S'; if (runmode&RESULT_ATEND) buf[3] = 'E'; if (runmode&RESULT_IMMED) buf[3] = 'I'; if (runmode&RESULT_ASAP) buf[3] = 'A'; if ((runmode&RESULT_ALL) == RESULT_ALL) buf[3] = 'X'; HPrintf(win,x14,y5,"%s",buf); } // if showRD do full traceback if (showRD){ string s = p; char buf[256],*bp; for (pp = ppcb.path; pp!=NULL; pp=pp->prev){ if (pp->owner->node->info.pron != NULL) // it might be a !NULL tag s = string(pp->owner->node->info.pron->word->wordName->name) + string(" ") + s; } if (s != trbak){ int w = x1-x0-8,txtw; trbak = s; HSetGrey(win,PANELGREY1); strcpy(buf,s.c_str()); bp = buf; txtw = HTextWidth(win,bp); while (txtw>w) txtw = HTextWidth(win,++bp); HFillRectangle(win,x0+1,y6+2,x0+trbakLastWidth+5,y3-2); HSetColour(win,BLACK); HPrintf(win,x0+4,y3-4,"%s",bp); trbakLastWidth = txtw; } } // runmode is RESULT_ASAP, see if anything more can be disambiguated if (runmode&RESULT_ASAP){ pptb = DoTraceBack(pri); if (pptb.n>0){ if (trace&T_PAN) { printf(" traceback at frame %.1f\n",tnow); PrintPartialPath(pptb,FALSE); } for (i=1; i<=pptb.n; i++) OutPathElement(i,pptb); } } // runmode is RESULT_IMMED, output any new words regardless if ((runmode&RESULT_IMMED) && (ppcb.n>0)){ if (trace&T_IAN) { printf(" current best at frame %.1f\n",tnow); PrintPartialPath(ppcb,FALSE); } for (i=1; i<=ppcb.n; i++) OutPathElement(i,ppcb); } }