/* UpdateWeights: use acc values to calc new estimate of mix weights */ void UpdateWeights(HLink hmm) { int i,s,m,M=0,N; float x,occi; WALink wa; StateElem *se; StreamElem *ste; MLink q; q=FindMacroStruct(&hset,'h',hmm); N = hmm->numStates; se = hmm->svec+2; for (i=2; i<N; i++,se++){ ste = se->info->pdf+1; for (s=1;s<=nStreams; s++,ste++){ wa = (WALink)ste->hook; if (wa != NULL) { switch(hsKind){ case TIEDHS: M = hset.tmRecs[s].nMix; break; case DISCRETEHS: M = ste->nMix; break; } occi = wa->occ; if (occi>0) { for (m=1; m<=M; m++){ x = wa->c[m]/occi; if (x>1.0){ if (x>1.001) HError(-2490,"UpdateWeights: Model [%s]: mix too big in %d.%d.%d",q->id->name,i,s,m); x = 1.0; } switch (hsKind){ case TIEDHS: ste->spdf.tpdf[m] = (x>MINMIX) ? x : 0; break; case DISCRETEHS: ste->spdf.dpdf[m] = (x>MINMIX) ? DProb2Short(x) :DLOGZERO; break; } } if (mixWeightFloor>0.0){ switch (hsKind){ case DISCRETEHS: FloorDProbs(ste->spdf.dpdf,M,mixWeightFloor); break; case TIEDHS: FloorTMMixes(ste->spdf.tpdf,M,mixWeightFloor); break; } } }else HError(-2427,"UpdateWeights: Model [%s]: no use of mixtures in %d.%d",q->id->name,i,s); ste->hook = NULL; } } } }
char *HMMPhysName(HMMSet *hset,HLink hmm) { MLink ml; if ((ml=FindMacroStruct(hset,'h',hmm))==NULL) HError(7270,"HMMPhysName: Cannot find hmm definition"); return(ml->id->name); }
void PrintModPath (DecoderInst *dec, ModendHyp *m) { MLink ml; char *s, *t=NULL; for (; m; m = m->prev) { s = "?"; switch (m->ln->type) { case LN_WORDEND: t = "WE"; s = dec->net->pronlist[m->ln->data.pron]->outSym->name; break; case LN_CON: t = "CON"; s = ""; break; case LN_MODEL: t = "MOD"; ml = FindMacroStruct (dec->hset, 'h', (Ptr) m->ln->data.hmm); if (ml) s = ml->id->name; } printf ("(%d %s %s) ", m->frame, t, s); } printf ("\n"); }
LAlign *LAlignFromAltModpath (DecoderInst *dec, MemHeap *heap, ModendHyp *modpath, ModendHyp *mainModpath, int wordStart, short *nLAlign) { ModendHyp *m, *nextM; LAlign *lalign; MLink ml; int n; int startFrame = 0; /* check for WE in main modpath */ n = 0; for (m = mainModpath; m; m = m->prev) if (m->ln->type == LN_WORDEND) break; else { if (m->ln->type == LN_MODEL) ++n; } /* if there are no WE models in main modpath then we are looking at the </s> link and should just call the normal LAlignFromModpath() */ if (!m) return LAlignFromModpath (dec, heap, modpath, wordStart, nLAlign); /* take the n first model entries from the main modpaths (upto the WE node) and then switch to the alt modpath */ for (m = modpath; m; m = m->prev) if (m->ln->type == LN_MODEL) ++n; lalign = New (heap, n * sizeof(LAlign)); *nLAlign = n; for (m = mainModpath; m; m = nextM) { nextM = m->prev; if (m->ln->type == LN_MODEL) { startFrame = (m->prev ? m->prev->frame : wordStart); ml = FindMacroStruct (dec->hset, 'h', (Ptr) m->ln->data.hmm); if (!ml) HError (9999, "LAlignFromModpath: model not found!"); assert (m->frame >= startFrame); --n; assert (n >= 0); lalign[n].state = -1; lalign[n].like = 0.0; lalign[n].dur = (m->frame - startFrame) * dec->frameDur; lalign[n].label = ml->id; } else if (m->ln->type == LN_WORDEND) nextM = modpath; } assert (n == 0); return (lalign); }
/* Debug_DumpNet */ void Debug_DumpNet (LexNet *net) { int i, j, k, N; LexNode *ln; LexNodeInst *inst; TokenSet *ts; RelToken *rtok; FILE *debugFile; Boolean isPipe; static char *debug_net_fn = "net.dump"; debugFile = FOpen (debug_net_fn, NoOFilter, &isPipe); if (!debugFile) { printf ("fopen failed\n"); return; } fprintf (debugFile, "(LexNet *) %p\n", net); fprintf (debugFile, "nNodes %d\n", net->nNodes); for (i = 0; i < net->nNodes; ++i) { ln = &net->node[i]; inst = ln->inst; if (inst) { fprintf (debugFile, "node %d (LexNode *) %p", i, ln); fprintf (debugFile, " type %d nfoll %d", ln->type, ln->nfoll); if (ln->type == LN_MODEL) fprintf (debugFile, " name %s", FindMacroStruct (net->hset, 'h', ln->data.hmm)->id->name); fprintf (debugFile, "\n"); assert (inst->node == ln); fprintf (debugFile, " (LexNodeInst *) %p", inst); fprintf (debugFile, " best %f\n", inst->best); N = (ln->type == LN_MODEL) ? ln->data.hmm->numStates : 1; for (j = 0; j < N; ++j) { ts = &inst->ts[j]; if (ts->n > 0) { fprintf (debugFile, " state %d (TokenSet *) %p", j+1, ts); fprintf (debugFile, " score %f\n", ts->score); for (k = 0; k < ts->n; ++k) { rtok = &ts->relTok[k]; fprintf (debugFile, " (RelToken *) %p", rtok); fprintf (debugFile, " delta %f lmstate %p lmscore %f\n", rtok->delta, rtok->lmState, rtok->lmscore); } } } } } FClose (debugFile, isPipe); }
void InitPhonePost (DecoderInst *dec) { HMMScanState hss; HLink hmm; MLink m; char buf[100]; LabId phoneId; NewHMMScan (dec->hset, &hss); do { hmm = hss.hmm; assert (!hmm->hook); m = FindMacroStruct (dec->hset, 'h', hmm); assert (strlen (m->id->name) < 100); strcpy (buf, m->id->name); TriStrip (buf); phoneId = GetLabId (buf, TRUE); phoneId->aux = (Ptr) 0; hmm->hook = (Ptr) phoneId; } while(GoNextHMM(&hss)); EndHMMScan(&hss); dec->nPhone = 0; /* count monophones -- #### make this more efficent! */ NewHMMScan (dec->hset, &hss); do { hmm = hss.hmm; phoneId = (LabId) hmm->hook; if (!phoneId->aux) { ++dec->nPhone; phoneId->aux = (Ptr) dec->nPhone; assert (dec->nPhone < 100); dec->monoPhone[dec->nPhone] = phoneId; } } while(GoNextHMM(&hss)); EndHMMScan(&hss); printf ("found %d monophones\n", dec->nPhone); dec->phonePost = (LogDouble *) New (&gcheap, (dec->nPhone+1) * sizeof (LogDouble)); dec->phoneFreq = (int *) New (&gcheap, (dec->nPhone+1) * sizeof (int)); }
/* UpdateTrans: use acc values to calc new estimate for transP */ void UpdateTrans(HLink hmm) { int i,j,N; float x,occi; TrAcc *ta; MLink q; q=FindMacroStruct(&hset,'h',hmm); ta = (TrAcc *) GetHook(hmm->transP); if (ta==NULL) return; /* already done */ N = hmm->numStates; for (i=1;i<N;i++) { occi = ta->occ[i]; if (occi > 0.0) for (j=2;j<=N;j++) { x = ta->tran[i][j]/occi; hmm->transP[i][j] = (x>MINLARG)?log(x):LZERO; } else HError(-2424,"UpdateTrans: Model [%s]: no transitions out of state %d",q->id->name,i); } SetHook(hmm->transP,NULL); }
LAlign *LAlignFromModpath (DecoderInst *dec, MemHeap *heap, ModendHyp *modpath, int wordStart, short *nLAlign) { ModendHyp *m; LAlign *lalign; MLink ml; int n; int startFrame = 0; n = 0; for (m = modpath; m; m = m->prev) if (m->ln->type == LN_MODEL) ++n; lalign = New (heap, n * sizeof(LAlign)); *nLAlign = n; for (m = modpath; m; m = m->prev) { if (m->ln->type == LN_MODEL) { startFrame = (m->prev ? m->prev->frame : wordStart); ml = FindMacroStruct (dec->hset, 'h', (Ptr) m->ln->data.hmm); if (!ml) HError (9999, "LAlignFromModpath: model not found!"); assert (m->frame >= startFrame); --n; lalign[n].state = -1; lalign[n].like = 0.0; lalign[n].dur = (m->frame - startFrame) * dec->frameDur; lalign[n].label = ml->id; } } assert (n == 0); return (lalign); }
/* InitStats: Create and init all necessary global accumulators */ void InitStats(char *listFn) { int h,p,l; MLink q,hm; HLink hmm; HMMSet *hset; CreateHeap(&tmpHeap,"TempHeap",MSTAK,1,1.0,8000,80000); CreateHeap(&statHeap,"StatHeap",MSTAK,1,1.0,8000,240000); hset=(HMMSet*)New(&tmpHeap,sizeof(HMMSet)); CreateHMMSet(hset,&tmpHeap,FALSE); if(MakeHMMSet(hset,listFn)<SUCCESS) HError(1328,"Initstats: MakeHMMSet failed"); /* Make sure we have entries for ENTER / EXIT labels */ if (FindMacroName(hset,'l',enterId)==NULL) { hmm=(HMMDef*)New(&tmpHeap,sizeof(HMMDef)); NewMacro(hset,0,'l',enterId,hmm); NewMacro(hset,0,'h',enterId,hmm); } if (FindMacroName(hset,'l',exitId)==NULL) { hmm=(HMMDef*)New(&tmpHeap,sizeof(HMMDef)); NewMacro(hset,0,'l',exitId,hmm); NewMacro(hset,0,'h',exitId,hmm); } pSize=hset->numPhyHMM; pTab=(Cntr*)New(&statHeap,(pSize+1)*sizeof(Cntr)); p=1; pTab[0].name=nullId; for (h=0; h<MACHASHSIZE; h++) for (q=hset->mtab[h]; q!=NULL; q=q->next) { if (q->type=='h') { hmm=(HLink) q->structure; hmm->hook=(Ptr)p; pTab[p].name=q->id; pTab[p].count=0; p++; } } lSize=hset->numLogHMM; lTab=(WordInfo*)New(&statHeap,(lSize+1)*sizeof(WordInfo)); l=1; InitWordInfo(lTab,nullId,pTab); for (h=0; h<MACHASHSIZE; h++) for (q=hset->mtab[h]; q!=NULL; q=q->next) if (q->type=='l') { hmm=(HLink) q->structure; hm=FindMacroStruct(hset,'h',q->structure); if (hm==NULL || hmm->hook==0) HError(1390,"InitStats: No physical name found for %s", q->id->name); InitWordInfo(lTab+l,q->id,pTab+(int)hmm->hook); l++; } qsort(lTab+1,lSize,sizeof(WordInfo),wd_cmp); for (l=1; l<=lSize; l++) lTab[l].name->aux=(Ptr)l; Dispose(&tmpHeap,hset); if (doBigram) { /* create aetab */ aetabsize=hashsizes[hSize]; aetab=(AEntry**)New(&statHeap,aetabsize*sizeof(AEntry*)); for (l=0;l<aetabsize;l++) aetab[l]=NULL; } if (trace&T_BAS) { PrintSettings(); printf("\n\nRead Label list - %d/%d labels\n",lSize,pSize); } }
// 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); } }
// Recognise a single observation Boolean ARec::RecObservation() { APacket pkt; AStringData *sd; AObsData *od; PacketKind kind; Boolean stopDetected = FALSE; if (runmode&STOP_IMMED) // stop immediately return TRUE; while (in->NumPackets()>0){ pkt = in->GetPacket(); kind = pkt.GetKind(); if (kind==StringPacket) { // check if stop marker sd = (AStringData *)pkt.GetData(); if ((runmode&STOP_ATMARK) && (sd->data.find("STOP") != string::npos)) stopDetected = TRUE; StoreMarker(pkt); } if (kind != StringPacket || stopDetected){ if (stTime<0) { // just entered runmode stTime = pkt.GetStartTime(); enTime = stTime; score = -1e6; trbak = ""; trbakCount = 0; if (runmode&RESULT_ALL) OutPacket(Start_PT, "", fname, 0,0,0.0,0.0,0.0,-1.0,0.0,stTime,stTime); } if (stopDetected) return TRUE; if (kind==ObservationPacket){ od = (AObsData *)pkt.GetData(); if ((runmode&STOP_ATSIL) && !od->data.vq[0]) // stop if silence return TRUE; if (trace&T_OBS) PrintObservation(frameCount,&(od->data),13); // recognise observation ProcessObservation(pri,&(od->data),-1,hset->curXForm); if (trace & T_FRS) { char *p; MLink m; NetNode *node = pri->genMaxNode; printf("Frame %-4d ",pri->frame); if ( node == NULL){ printf("null\n"); }else{ char *qm="?"; p = (node->wordset==NULL)?qm:node->wordset->name; m=FindMacroStruct(hset,'h',node->info.hmm); printf("HMM: %s (%s) %d %5.3f\n",m->id->name,p, pri->nact,pri->genMaxTok.like/pri->frame); } } ++frameCount; tact+=pri->nact; enTime += sampPeriod; if ((showRD || (runmode&(RESULT_IMMED|RESULT_ASAP))) && (++trbakCount == trbakFreq)) { TraceBackRecogniser(); trbakCount = 0; } } } } return FALSE; }
/* ProcessFile: process given file. If fn=NULL then direct audio */ Boolean ProcessFile(char *fn, Network *net, int utterNum, LogDouble currGenBeam, Boolean restartable) { FILE *file; ParmBuf pbuf; BufferInfo pbinfo; NetNode *d; Lattice *lat; LArc *arc,*cur; LNode *node; Transcription *trans; MLink m; LogFloat lmlk,aclk; int s,j,tact,nFrames; LatFormat form; char *p,lfn[255],buf1[80],buf2[80],thisFN[MAXSTRLEN]; Boolean enableOutput = TRUE, isPipe; if (fn!=NULL) strcpy(thisFN,fn); else if (fn==NULL && saveAudioOut) CounterFN(roPrefix,roSuffix,++roCounter,4,thisFN); else enableOutput = FALSE; if((pbuf = OpenBuffer(&bufHeap,fn,50,dfmt,TRI_UNDEF,TRI_UNDEF))==NULL) HError(3250,"ProcessFile: Config parameters invalid"); /* Check pbuf same as hset */ GetBufferInfo(pbuf,&pbinfo); if (pbinfo.tgtPK!=hset.pkind) HError(3231,"ProcessFile: Incompatible sample kind %s vs %s", ParmKind2Str(pbinfo.tgtPK,buf1), ParmKind2Str(hset.pkind,buf2)); if (pbinfo.a != NULL && replay) AttachReplayBuf(pbinfo.a, (int) (3*(1.0E+07/pbinfo.srcSampRate))); StartRecognition(vri,net,lmScale,wordPen,prScale); SetPruningLevels(vri,maxActive,currGenBeam,wordBeam,nBeam,tmBeam); tact=0;nFrames=0; StartBuffer(pbuf); while(BufferStatus(pbuf)!=PB_CLEARED) { ReadAsBuffer(pbuf,&obs); if (trace&T_OBS) PrintObservation(nFrames,&obs,13); if (hset.hsKind==DISCRETEHS){ for (s=1; s<=hset.swidth[0]; s++){ if( (obs.vq[s] < 1) || (obs.vq[s] > maxMixInS[s])) HError(3250,"ProcessFile: Discrete data value [ %d ] out of range in stream [ %d ] in file %s",obs.vq[s],s,fn); } } ProcessObservation(vri,&obs,-1,xfInfo.inXForm); if (trace & T_FRS) { for (d=vri->genMaxNode,j=0;j<30;d=d->links[0].node,j++) if (d->type==n_word) break; if (d->type==n_word){ if (d->info.pron==NULL) p=":bound:"; else p=d->info.pron->word->wordName->name; } else p=":external:"; m=FindMacroStruct(&hset,'h',vri->genMaxNode->info.hmm); printf("Optimum @%-4d HMM: %s (%s) %d %5.3f\n", vri->frame,m->id->name,p, vri->nact,vri->genMaxTok.like/vri->frame); fflush(stdout); } nFrames++; tact+=vri->nact; } lat=CompleteRecognition(vri,pbinfo.tgtSampRate/10000000.0,&ansHeap); if (lat==NULL) { if ((trace & T_TOP) && fn != NULL){ if (restartable) printf("No tokens survived to final node of network at beam %.1f\n", currGenBeam); else printf("No tokens survived to final node of network\n"); fflush(stdout); } else if (fn==NULL){ printf("Sorry [%d frames]?\n",nFrames);fflush(stdout); } if (pbinfo.a != NULL && replay) ReplayAudio(pbinfo); CloseBuffer(pbuf); return FALSE; } if (vri->noTokenSurvived && restartable) return FALSE; if (vri->noTokenSurvived && trace & T_TOP) { printf("No tokens survived to final node of network\n"); printf(" Output most likely partial hypothesis within network\n"); fflush(stdout); } lat->utterance=thisFN; lat->net=wdNetFn; lat->vocab=dictFn; if (trace & T_TOP || fn==NULL) { node=NULL; for (j=0;j<lat->nn;j++) { node=lat->lnodes+j; if (node->pred==NULL) break; node=NULL; } aclk=lmlk=0.0; while(node!=NULL) { for (arc=NULL,cur=node->foll;cur!=NULL;cur=cur->farc) arc=cur; if (arc==NULL) break; if (arc->end->word!=NULL) printf("%s ",arc->end->word->wordName->name); aclk+=arc->aclike+arc->prlike*lat->prscale; lmlk+=arc->lmlike*lat->lmscale+lat->wdpenalty; node=arc->end; } printf(" == [%d frames] %.4f [Ac=%.1f LM=%.1f] (Act=%.1f)\n",nFrames, (aclk+lmlk)/nFrames, aclk,lmlk,(float)tact/nFrames); fflush(stdout); } if (pbinfo.a != NULL && replay) ReplayAudio(pbinfo); /* accumulate stats for online unsupervised adaptation only if a token survived */ if ((lat != NULL) && (!vri->noTokenSurvived) && ((update > 0) || (xfInfo.useOutXForm))) DoOnlineAdaptation(lat, pbuf, nFrames); if (enableOutput){ if (nToks>1 && latExt!=NULL) { MakeFN(thisFN,labDir,latExt,lfn); if ((file=FOpen(lfn,NetOFilter,&isPipe))==NULL) HError(3211,"ProcessFile: Could not open file %s for lattice output",lfn); if (latForm==NULL) form=HLAT_DEFAULT; else { for (p=latForm,form=0;*p!=0;p++) { switch (*p) { case 'A': form|=HLAT_ALABS; break; case 'B': form|=HLAT_LBIN; break; case 't': form|=HLAT_TIMES; break; case 'v': form|=HLAT_PRON; break; case 'a': form|=HLAT_ACLIKE; break; case 'l': form|=HLAT_LMLIKE; break; case 'd': form|=HLAT_ALIGN; break; case 'm': form|=HLAT_ALDUR; break; case 'n': form|=HLAT_ALLIKE; break; case 'r': form|=HLAT_PRLIKE; break; } } } if(WriteLattice(lat,file,form)<SUCCESS) HError(3214,"ProcessFile: WriteLattice failed"); FClose(file,isPipe); } /* only output 1-best transcription if generating lattices */ if (nTrans > 1 && latExt != NULL) trans=TranscriptionFromLattice(&ansHeap,lat,1); /* output N-best transcriptions as usual */ else trans=TranscriptionFromLattice(&ansHeap,lat,nTrans); if (labForm!=NULL) FormatTranscription(trans,pbinfo.tgtSampRate,states,models, strchr(labForm,'X')!=NULL, strchr(labForm,'N')!=NULL,strchr(labForm,'S')!=NULL, strchr(labForm,'C')!=NULL,strchr(labForm,'T')!=NULL, strchr(labForm,'W')!=NULL,strchr(labForm,'M')!=NULL); MakeFN(thisFN,labDir,labExt,lfn); /* if(LSave(lfn,trans,ofmt)<SUCCESS) HError(3214,"ProcessFile: Cannot save file %s", lfn); */ LSave(lfn,trans,ofmt); Dispose(&ansHeap,trans); } Dispose(&ansHeap,lat); CloseBuffer(pbuf); if (trace & T_MMU){ printf("Memory State after utter %d\n",utterNum); PrintAllHeapStats(); } return !vri->noTokenSurvived; }