/* Export number of frames, mean, var to a given directory */ void ExportNMV(SpkrAccListItem *sal, char *OutDirName, char *tgtPKStr) { FILE *oFile; Boolean isPipe; char oFileName[MAXSTRLEN]; char pathBuffer1[MAXSTRLEN]; char pathBuffer2[MAXSTRLEN]; SpkrAccListItem *p; int i; p = sal; while(p != NULL){ /* create output file name for current spkr index */ if ( pathPattern[0] != '\0'){ if ( MaskMatch(pathPattern,pathBuffer1,p->sa->SpkrName) != TRUE ){ HError(2039,"HCompV: ExportNMV: path pattern matching failure on speaker: %s\n",p->sa->SpkrName); } MakeFN(pathBuffer1,OutDirName,NULL,pathBuffer2); MakeFN(p->sa->SpkrName,pathBuffer2,NULL,oFileName); } else MakeFN(p->sa->SpkrName,OutDirName,NULL,oFileName); /* open and write */ oFile = FOpen(oFileName,NoOFilter,&isPipe); if (oFile == NULL){ HError(2011,"HCompV: ExportNMV: output file creation error %s",oFileName); } /* write header */ fprintf(oFile,"<CEPSNORM> <%s>",tgtPKStr); /* write number frames */ if (strchr(oflags,'n')){ fprintf(oFile,"\n<NFRAMES> %d",p->sa->NumFrame); } /* write mean */ if (strchr(oflags,'m')){ fprintf(oFile,"\n<MEAN> %d\n",vSize); for (i=1;i<=vSize;i++){ fprintf(oFile," %e",(p->sa->meanSum[i])); } } /* write variance */ if (strchr(oflags,'v')){ fprintf(oFile,"\n<VARIANCE> %d\n",vSize); for (i=1;i<=vSize;i++){ fprintf(oFile," %e",(p->sa->squareSum[i])); } } fprintf(oFile,"\n"); FClose(oFile,isPipe); p = p->nextSpkr; } }
/* PutVFloor: output variance floor vectors */ void PutVFloor(void) { int i,s; char outfn[MAXSTRLEN],vName[32],num[10]; FILE *f; Vector v; MakeFN("vFloors",outDir,NULL,outfn); if ((f = fopen(outfn,"w")) == NULL) HError(2011,"PutVFloor: cannot create %s",outfn); for (s=1; s <= hset.swidth[0]; s++) { v = CreateVector(&gstack,hset.swidth[s]); sprintf(num,"%d",s); strcpy(vName,"varFloor"); strcat(vName,num); fprintf(f,"~v %s\n",vName); if (fullcNeeded[s]) TriDiag2Vector(accs[s].squareSum.inv,v); else CopyVector(accs[s].fixed.var,v); for (i=1; i<=hset.swidth[s]; i++) v[i] *= vFloorScale; fprintf(f,"<Variance> %d\n",hset.swidth[s]); WriteVector(f,v,FALSE); FreeVector(&gstack,v); } fclose(f); if (trace&T_TOP) printf("Var floor macros output to file %s\n",outfn); }
/* LoadMgeTrnHmmFile: */ static void LoadMgeTrnHmmFile(int nIter) { char hext[15], hmmFile[255]; ResetHeap(&hmmStack); CreateHeap(&hmmStack, "Model Stack", MSTAK, 1, 1.0, 80000, 400000); sprintf(hext, "mmf%d", nIter); MakeFN(mmfFn, outDir, hext, hmmFile); CreateHMMSet(&hset, &hmmStack, TRUE); AddMMF(&hset, hmmFile); if (trace & T_TOP) printf("Loading MGE-trained HMM in iteration %d ... ... \n", nIter); if (MakeHMMSet(&hset, hmmListFn) < SUCCESS) HError(2321, "Initialise: MakeHMMSet failed"); if (LoadHMMSet(&hset, hmmDir, hmmExt) < SUCCESS) HError(2321, "Initialise: LoadHMMSet failed"); SetParmHMMSet(&hset); /* variance inversion, MGE training only support INVDIAGC case */ ConvDiagC(&hset, TRUE); if (funcType == MGE_TRAIN) AttachAccToModel(); }
/* LoadFile: load whole file or segments and accumulate variance */ static void LoadFile(char *fn) { ParmBuf pbuf; BufferInfo info; char labfn[80]; Transcription *trans; long segStIdx,segEnIdx; int i,j,ncas,nObs; LLink p; if (segId == NULL) { /* load whole parameter file */ if((pbuf=OpenBuffer(&iStack, fn, 0, dff, FALSE_dup, FALSE_dup))==NULL) HError(2050,"LoadFile: Config parameters invalid"); GetBufferInfo(pbuf,&info); CheckData(fn,info); nObs = ObsInBuffer(pbuf); for (i=0; i<nObs; i++){ ReadAsTable(pbuf,i,&obs); AccVar(obs); } if (trace&T_LOAD) { printf(" %d observations loaded from %s\n",nObs,fn); fflush(stdout); } CloseBuffer(pbuf); } else { /* load segment of parameter file */ MakeFN(fn,labDir,labExt,labfn); trans = LOpen(&iStack,labfn,lff); ncas = NumCases(trans->head,segId); if ( ncas > 0) { if((pbuf=OpenBuffer(&iStack, fn, 0, dff, FALSE_dup, FALSE_dup))==NULL) HError(2050,"LoadFile: Config parameters invalid"); GetBufferInfo(pbuf,&info); CheckData(fn,info); for (i=1,nObs=0; i<=ncas; i++) { p = GetCase(trans->head,segId,i); segStIdx= (long) (p->start/info.tgtSampRate); segEnIdx = (long) (p->end/info.tgtSampRate); if (trace&T_SEGS) printf(" loading seg %s [%ld->%ld]\n", segId->name,segStIdx,segEnIdx); if (segEnIdx >= ObsInBuffer(pbuf)) segEnIdx = ObsInBuffer(pbuf)-1; if (segEnIdx >= segStIdx) { for (j=segStIdx;j<=segEnIdx;j++) { ReadAsTable(pbuf,j,&obs); AccVar(obs); ++nObs; } } } CloseBuffer(pbuf); if (trace&T_LOAD) printf(" %d observations loaded from %s\n",nObs,fn); } } ResetHeap(&iStack); }
/* CheckGenSetUp: Check & setup GenInfo structure */ static void CheckGenSetUp(void) { int d, p, r, s, stream; PdfStream *pst = NULL; /* # of PdfStreams */ genInfo->nPdfStream[0] = (nPdfStr == NULL) ? hset.swidth[0] : IntVecSize(nPdfStr); if (genInfo->nPdfStream[0] > hset.swidth[0]) HError(6604, "CheckGenSetUp: # of PdfStreams (%d) is too large (should be less than %d)", genInfo->nPdfStream[0], hset.swidth[0]); /* size of each PdfStreams */ r = hset.swidth[0]; for (p = stream = 1; p <= genInfo->nPdfStream[0]; stream += genInfo->nPdfStream[p++]) { pst = &(genInfo->pst[p]); /* # of streams in this PdfStream */ genInfo->nPdfStream[p] = (nPdfStr == NULL) ? 1 : nPdfStr[p]; r -= genInfo->nPdfStream[p]; /* calculate vector size for this PdfStream */ for (s = stream, pst->vSize = 0; s < stream + genInfo->nPdfStream[p]; s++) pst->vSize += hset.swidth[s]; /* order (vecSize of static feature vector) of this PdfStream */ pst->order = (pdfStrOrder == NULL) ? 1 : pdfStrOrder[p]; if (pst->order < 1 || pst->order > pst->vSize) HError(6604, "CheckGenSetUp: Order of PdfStream %d should be within 1--%d", p, pst->vSize); /* window coefficients */ if (winFn[p] == NULL) HError(6604, "CheckGenSetUp: window file names are not specified"); pst->win.num = (int) winFn[p][0][0]; if (pst->win.num > MAXWINNUM) HError(6604, "CheckGenSetUp: # of window out of range"); if (pst->win.num * pst->order != pst->vSize) HError(6604, "CheckGenSetUp: # of window (%d) times order (%d) should be equal to vSize (%d)", pst->win.num, pst->order, pst->vSize); for (d = 0; d < pst->win.num; d++) MakeFN(winFn[p][d + 1], winDir, winExt, pst->win.fn[d]); } if (r != 0) HError(6604, "CheckGenSetUp: # of streams in HMMSet (%d) and PdfStreams (%d) are inconsistent", hset.swidth[0], genInfo->nPdfStream[0]); /* output trace information */ if (trace & T_TOP) { for (p = 1; p <= genInfo->nPdfStream[0]; p++) { printf("PdfStream [%d]:\n", p); printf(" #streams: %d (vSize=%d)\n", genInfo->nPdfStream[p], genInfo->pst[p].vSize); printf(" #order: %d\n", genInfo->pst[p].order); printf(" file ext: %s\n", genInfo->pst[p].ext); for (d = 0; d < genInfo->pst[p].win.num; d++) printf(" %d-th window: %s\n", d, genInfo->pst[p].win.fn[d]); } printf("\n"); fflush(stdout); } }
/* SaveLabs: save trans t to label file corresponding to tgt */ void SaveLabs(char *tgt, Transcription *t) { MakeFN(tgt,outLabDir,labExt,labFile); if(trace & T_SEGMENT) printf("Saving label file %s\n",labFile); if (CountLabs(trans->head) == 0) HError(-1031,"SaveLabs: No labels in transcription %s", labFile); if(LSave(labFile,t,tgtLabFF)<SUCCESS) HError(1014,"SaveLabs: Could not save label file %s", labFile); }
/* LoadTransLabs: Load transcription from file */ Transcription *LoadTransLabs(char *src) { Transcription *t; MakeFN(src,labDir,labExt,labFile); if(trace & T_SEGMENT) printf("Loading label file %s\n",labFile); t = LOpen(&lStack,labFile,srcLabFF); if(chopF && ! stenSet) SetLabSeg(t); return t; }
/* OutputIntmdXForm: Output intermedia HMM files */ static void OutputIntmdXForm(int nIter) { char hext[16], fname[MAXSTRLEN]; if (trace & T_TOP) { fprintf(stdout, "\nSaving XForm to %s ... \n", outDir); fflush(stdout); } sprintf(hext, ".%d", nIter); MakeFN(xformfn, outDir, NULL, fname); strcat(fname, hext); SaveOneXForm(&hset, hset.curXForm, fname, FALSE); }
/* OneIterMgeEval: */ static int OneIterMgeEval(int nIter) { char *datafn, labfn[256], basefn[255]; int nSent, nAdjNum, p, nTotalAdj; if (nIter > 1) nMaxBALen = 1; /* set all stat info to zero */ ResetAllStatInfo(nIter); nTotalAdj = 0; /* process all data */ for (nSent = 0; nSent < g_nDataFileNum; nSent++) { datafn = g_pDataFileList[nSent]->datafn; /* after first boundary adjustment, use the adjusted label files */ if (nIter >= 1 && bBoundAdj && outLabDir != NULL) MakeFN(datafn, outLabDir, labExt, labfn); else MakeFN(datafn, labDir, labExt, labfn); NameOf(datafn, basefn); if (bBoundAdj) { nAdjNum = OneSentBoundAdjust(mtInfo, labfn, datafn, outLabDir, nMaxBAIter, nMaxBALen, FALSE); if (trace & T_PROC) { fprintf(stdout, "Total BA Number: %d\n", nAdjNum); fflush(stdout); } nTotalAdj += nAdjNum; } /* accumulation of generation error only */ OneSentGenErrAcc(mtInfo, labfn, datafn); for (p = 1; p <= genInfo->nPdfStream[0]; p++) { total_T[p] += genInfo->pst[p].T; } } return nSent; }
/* DoGeneration: Generate parameter sequences from HMMs */ void DoGeneration(char *labfn) { char labFn[MAXFNAMELEN], buf[MAXSTRLEN]; int t; Boolean eSep; Transcription *tr; if (trace & T_TOP) { printf(" Generating Label %s\n", NameOf(labfn, buf)); fflush(stdout); } /* load a given input label file */ ResetHeap(&utt->transStack); MakeFN(labfn, labDir, labExt, labFn); tr = LOpen(&genStack, labFn, lff); /* compose a sentence HMM corresponding to the input label */ InitialiseGenInfo(genInfo, tr, FALSE); /* set utterance informations for forward-backward algorithm */ SetStreamWidths(hmset.pkind, hmset.vecSize, hmset.swidth, &eSep); utt->tr = tr; utt->Q = genInfo->labseqlen; utt->T = genInfo->tframe; utt->twoDataFiles = FALSE; utt->o = (Observation *) New(&gstack, utt->T * sizeof(Observation)); utt->o--; for (t = 1; t <= utt->T; t++) utt->o[t] = MakeObservation(&gstack, hmset.swidth, hmset.pkind, FALSE, eSep); /* parameter generation */ ParamGen(genInfo, utt, fbInfo, type); /* output state durations and generated parameter sequences */ if (!stateAlign) WriteStateDurations(labfn, genInfo); WriteParms(labfn, genInfo); /* free memory */ Dispose(&gstack, ++utt->o); ResetGenInfo(genInfo); /* increment total number of generated frames */ totalT += utt->T; totalPr += utt->pr; return; }
/* Initialise: initialise global data structures */ void Initialise(void) { int i; char path[256]; CreateHeap(&langHeap,"LModel mem",MSTAK,1,0.5,1000,20000); if (wlistFN!=NULL) { tgtVoc = &wlist; CreateWordList(wlistFN,tgtVoc,10); } if (processText) { /* init empty buffer */ CreateWordMap(NULL,&wmap,newWords); wmap.hasCnts = TRUE; wmap.name = defMapName; wmap.htkEsc = htkEscape; ++wmap.seqno; mapUpdated = FALSE; if (tgtVoc!=NULL) { /* add words from word list to the map */ pruneWords = TRUE; for (i=0; i<tgtVoc->used; i++) { AddWordToMap(&wmap,tgtVoc->id[i]); } SortWordMap(&wmap); unkId = GetLabId(unkStr,FALSE); } /* init ngram buffer */ MakeFN(rootFN,dbsDir,NULL,path); stdBuf.used = 0; stdBuf.ng[nSize] = 1; /* count = 1 */ stdBuf.ngb = CreateNGBuffer(&langHeap,nSize,ngbSize,path,&wmap); } else { CreateWordMap(omapFN,&wmap,1); } CreateInputSet(&gstack,&wmap,&inSet); binfo.wmap = &wmap; binfo.inSet = &inSet; binfo.nSize = nSize; }
/* LoadFile: load whole file or segments and accumulate variance */ void LoadFile(char *fn) { ParmBuf pbuf; BufferInfo info; char labfn[80]; Transcription *trans; long segStIdx,segEnIdx; int i,s,j,ncas,nObs=0; LLink p; if (segId == NULL) { /* load whole parameter file */ if((pbuf=OpenBuffer(&iStack, fn, 0, dff, FALSE_dup, FALSE_dup))==NULL) HError(2550,"LoadFile: Config parameters invalid"); GetBufferInfo(pbuf,&info); CheckData(fn,info); nObs = ObsInBuffer(pbuf); for (i=0; i<nObs; i++) { for(s=1;s<=swidth[0];s++) obs.fv[s] = CreateVector(&dStack,swidth[s]); ReadAsTable(pbuf,i,&obs); for(s=1;s<=swidth[0];s++) StoreItem(dSeq[s],(Ptr)obs.fv[s]); } CloseBuffer(pbuf); } else { /* load segment of parameter file */ MakeFN(fn,labDir,labExt,labfn); trans = LOpen(&iStack,labfn,lff); ncas = NumCases(trans->head,segId); if ( ncas > 0) { if((pbuf=OpenBuffer(&iStack, fn, 0, dff, FALSE_dup, FALSE_dup))==NULL) HError(2550,"LoadFile: Config parameters invalid"); GetBufferInfo(pbuf,&info); CheckData(fn,info); for (i=1,nObs=0; i<=ncas; i++) { p = GetCase(trans->head,segId,i); segStIdx= (long) (p->start/info.tgtSampRate); segEnIdx = (long) (p->end/info.tgtSampRate); if (trace&T_SEGS) printf(" loading seg %s [%ld->%ld]\n", segId->name,segStIdx,segEnIdx); if (segEnIdx >= ObsInBuffer(pbuf)) segEnIdx = ObsInBuffer(pbuf)-1; if (segEnIdx >= segStIdx) { for (j=segStIdx;j<=segEnIdx;j++) { /* SJY: The HInit code I copied this from had no */ /* SJY: CreateVector call here -- a bug? */ for(s=1;s<=swidth[0];s++) obs.fv[s] = CreateVector(&dStack,swidth[s]); ReadAsTable(pbuf,j,&obs); for(s=1;s<=swidth[0];s++) StoreItem(dSeq[s],(Ptr)obs.fv[s]); ++nObs; } } } CloseBuffer(pbuf); } } ResetHeap(&iStack); if (trace&T_LOAD) { printf(" %5d obs loaded from %s, streams: ",nObs,fn); for(s=1;s<=swidth[0];s++) printf("[%d]" ,swidth[s]); printf("\n"); fflush(stdout); } }
/* SetConfParms: set conf parms relevant to HCompV */ void SetConfParms(void) { int i; Boolean b; double f; char buf[MAXSTRLEN]; nParm = GetConfig("HEREST", TRUE, cParm, MAXGLOBS); if (nParm>0) { if (GetConfInt(cParm,nParm,"TRACE",&i)) trace = i; if (GetConfFlt(cParm,nParm,"VARFLOORPERCENTILE",&f)) varFloorPercent = f; if (GetConfBool(cParm,nParm,"SAVEBINARY",&b)) saveBinary = b; if (GetConfBool(cParm,nParm,"BINARYACCFORMAT",&b)) ldBinary = b; /* 2-model reestimation alignment model set */ if (GetConfStr(cParm,nParm,"ALIGNMODELMMF",buf)) { strcpy(al_hmmMMF,buf); al_hmmUsed = TRUE; } if (GetConfStr(cParm,nParm,"ALIGNHMMLIST",buf)) { strcpy(al_hmmLst,buf); al_hmmUsed = TRUE; } /* allow multiple individual model files */ if (GetConfStr(cParm,nParm,"ALIGNMODELDIR",buf)) { strcpy(al_hmmDir,buf); al_hmmUsed = TRUE; } if (GetConfStr(cParm,nParm,"ALIGNMODELEXT",buf)) { strcpy(al_hmmExt,buf); al_hmmUsed = TRUE; } if (GetConfStr(cParm,nParm,"ALIGNXFORMEXT",buf)) { xfInfo.alXFormExt = CopyString(&hmmStack,buf); } if (GetConfStr(cParm,nParm,"ALIGNXFORMDIR",buf)) { xfInfo.alXFormDir = CopyString(&hmmStack,buf); } if (GetConfStr(cParm,nParm,"INXFORMMASK",buf)) { xfInfo.inSpkrPat = CopyString(&hmmStack,buf); } if (GetConfStr(cParm,nParm,"PAXFORMMASK",buf)) { xfInfo.paSpkrPat = CopyString(&hmmStack,buf); } if (GetConfStr(cParm,nParm,"LABFILEMASK",buf)) { labFileMask = (char*)malloc(strlen(buf)+1); strcpy(labFileMask, buf); } if (GetConfStr(cParm,nParm,"UPDATEMODE",buf)) { if (!strcmp (buf, "DUMP")) updateMode = UPMODE_DUMP; else if (!strcmp (buf, "UPDATE")) updateMode = UPMODE_UPDATE; else if (!strcmp (buf, "BOTH")) updateMode = UPMODE_BOTH; else HError(2319, "Unknown UPDATEMODE specified (must be DUMP, UPDATE or BOTH)"); } } } void ReportUsage(void) { printf("\nUSAGE: HERest [options] hmmList dataFiles...\n\n"); printf(" Option Default\n\n"); printf(" -a Use an input linear transform off\n"); printf(" -c f Mixture pruning threshold 10.0\n"); printf(" -d s dir to find hmm definitions current\n"); printf(" -h s set output speaker name pattern *.%%%%%%\n"); printf(" to s, optionally set input and parent patterns\n"); printf(" -l N set max files per speaker off\n"); printf(" -m N set min examples needed per model 3\n"); printf(" -o s extension for new hmm files as src\n"); printf(" -p N set parallel mode to N off\n"); printf(" -r Enable Single Pass Training... \n"); printf(" ...using two parameterisations off\n"); printf(" -s s print statistics to file s off\n"); printf(" -t f [i l] set pruning to f [inc limit] inf\n"); printf(" -u tmvwap update t)rans m)eans v)ars w)ghts tmvw\n"); printf(" a)daptation xform p)rior used \n"); printf(" s)semi-tied xform \n"); printf(" -v f set minimum variance to f 0.0\n"); printf(" -w f set mix weight floor to f*MINMIX 0.0\n"); printf(" -x s extension for hmm files none\n"); printf(" -z s Save all xforms to TMF file s TMF\n"); PrintStdOpts("BEFGHIJKLMSTX"); printf("\n\n"); } void SetuFlags(void) { char *s; s=GetStrArg(); uFlags=(UPDSet) 0; while (*s != '\0') switch (*s++) { case 't': uFlags = (UPDSet) (uFlags+UPTRANS); break; case 'm': uFlags = (UPDSet) (uFlags+UPMEANS); break; case 'v': uFlags = (UPDSet) (uFlags+UPVARS); break; case 'w': uFlags = (UPDSet) (uFlags+UPMIXES); break; case 's': uFlags = (UPDSet) (uFlags+UPSEMIT); break; case 'a': uFlags = (UPDSet) (uFlags+UPXFORM); break; case 'p': uFlags = (UPDSet) (uFlags+UPMAP); break; default: HError(2320,"SetuFlags: Unknown update flag %c",*s); break; } } /* ScriptWord: return next word from script */ char *ScriptWord(FILE *script, char *scriptBuf) { int ch,qch,i; i=0; ch=' '; while (isspace(ch)) ch = fgetc(script); if (ch==EOF) { scriptBuf=NULL; return NULL; } if (ch=='\'' || ch=='"'){ qch = ch; ch = fgetc(script); while (ch != qch && ch != EOF) { scriptBuf[i++] = ch; ch = fgetc(script); } if (ch==EOF) HError(5051,"ScriptWord: Closing quote missing in script file"); } else { do { scriptBuf[i++] = ch; ch = fgetc(script); }while (!isspace(ch) && ch != EOF); } scriptBuf[i] = '\0'; return scriptBuf; } void CheckUpdateSetUp() { AdaptXForm *xf;
/* main: */ int main(int argc, char *argv[]) { char *s; char fname[MAXSTRLEN]; InitShell(argc, argv, hmgetool_version, hmgetool_vc_id); InitMem(); InitMath(); InitSigP(); InitWave(); InitLabel(); InitModel(); InitTrain(); InitParm(); InitUtil(); InitFB(); InitGen(); InitAdapt(&xfInfo, NULL); InitMTrain(); /* process argument */ if (NumArgs() == 0) ReportUsage(); CreateHeap(&hmmStack, "Model Stack", MSTAK, 1, 1.0, 80000, 4000000); CreateHeap(&orighmmStack, "Model Stack", MSTAK, 1, 1.0, 80000, 4000000); CreateHeap(&accStack, "Acc Stack", MSTAK, 1, 1.0, 80000, 400000); CreateHeap(&genStack, "Gen Stack", MSTAK, 1, 1.0, 80000, 400000); CreateHeap(&mgeStack, "MGE Train Stack", MSTAK, 1, 1.0, 80000, 400000); SetConfParms(); CreateHMMSet(&hset, &hmmStack, TRUE); CreateHMMSet(&orighset, &orighmmStack, TRUE); statInfo = (MTStatInfo *) New(&gstack, sizeof(MTStatInfo)); memset(statInfo, 0, sizeof(MTStatInfo)); genInfo = (GenInfo *) New(&genStack, sizeof(GenInfo)); memset(genInfo, 0, sizeof(GenInfo)); genInfo->hset = &hset; genInfo->genMem = &genStack; mtInfo = (MgeTrnInfo *) New(&mgeStack, sizeof(MgeTrnInfo)); memset(mtInfo, 0, sizeof(MgeTrnInfo)); mtInfo->genInfo = genInfo; mtInfo->statInfo = statInfo; mtInfo->hset = &hset; mtInfo->orighset = &orighset; mtInfo->mgeMem = &mgeStack; while (NextArg() == SWITCHARG) { s = GetSwtArg(); if (strlen(s) != 1) HError(6601, "HMgeTool: Bad switch %s; must be single letter", s); switch (s[0]) { case 'a': nMaxBAIter = GetChkedInt(1, 1000, s); nMaxBALen = GetChkedInt(1, 1000, s); break; case 'b': mtInfo->bBoundAdj = TRUE; nBAEndIter = GetChkedInt(0, 1000, s); nBoundAdjWin = GetChkedInt(1, 1000, s); break; case 'c': outProcData = TRUE; break; case 'd': if (NextArg() != STRINGARG) HError(6601, "HMgeTool: HMM definition directory expected"); hmmDir = GetStrArg(); break; case 'e': mtInfo->bStepLimit = TRUE; break; case 'f': frameRate = (HTime) GetChkedFlt(0.0, 10000000.0, s); break; case 'g': mtInfo->bMVar = TRUE; break; case 'i': startIter = GetChkedInt(0, 1000, s); endIter = GetChkedInt(startIter, 1000, s); break; case 'j': funcType = GetChkedInt(0, 2, s); mtInfo->funcType = funcType; break; case 'l': if (NextArg() != STRINGARG) HError(6601, "HMgeTool: Label file output directory expected"); outLabDir = GetStrArg(); break; case 'o': if (NextArg() != STRINGARG) HError(6601, "HMgeTool: HMM file extension expected"); outExt = GetStrArg(); break; case 'p': A_STEP = GetChkedFlt(0.0, 10000000.0, s); B_STEP = GetChkedFlt(0.0, 10000000.0, s); break; case 'r': mtInfo->bOrigHmmRef = TRUE; if (NextArg() != STRINGARG) HError(6601, "HMgeTool: HMM macro file name expected"); s = GetStrArg(); AddMMF(&orighset, s); break; case 's': /* updating scale file */ scalefn = GetStrArg(); break; case 'u': SetuFlags(); break; case 'v': MSDthresh = GetChkedFlt(0.0, 1.0, s); break; case 'w': fGVDistWght = GetChkedFlt(0.0, 1000.0, s); break; case 'x': if (NextArg() != STRINGARG) HError(6601, "HMgeTool: HMM file extension expected"); hmmExt = GetStrArg(); break; case 'B': inBinary = TRUE; break; case 'G': mtInfo->nGainStreamIndex = GetChkedInt(1, SMAX, s); mtInfo->nGainDimIndex = GetChkedInt(1, 1000, s); if (NextArg() == FLOATARG || NextArg() == INTARG) mtInfo->fGainWghtComp = GetChkedFlt(-10000.0, 1000000.0, s); break; case 'H': if (NextArg() != STRINGARG) HError(6601, "HMgeTool: HMM macro file name expected"); mmfFn = GetStrArg(); AddMMF(&hset, mmfFn); break; case 'I': if (NextArg() != STRINGARG) HError(6601, "HMgeTool: MLF file name expected"); LoadMasterFile(GetStrArg()); break; case 'J': /* regression class and tree */ if (NextArg() != STRINGARG) HError(6601, "HMgeTool: HMM regression class/tree file name expected"); s = GetStrArg(); AddMMF(&hset, s); AddMMF(&orighset, s); break; case 'K': if (NextArg() != STRINGARG) HError(6601, "HMgeTool: HMM transform file name expected"); xformfn = GetStrArg(); break; case 'L': if (NextArg() != STRINGARG) HError(6601, "HMgeTool: Label file directory expected"); labDir = GetStrArg(); break; case 'M': if (NextArg() != STRINGARG) HError(6601, "HMgeTool: Output macro file directory expected"); outDir = GetStrArg(); break; case 'T': trace = GetChkedInt(0, 0100000, s); break; case 'X': if (NextArg() != STRINGARG) HError(2319, "HMGenS: Label file extension expected"); labExt = GetStrArg(); break; default: HError(6601, "HMgeTool: Unknown switch %s", s); } } if (NextArg() != STRINGARG) HError(6601, "HMgeTool: file name of model list expected"); hmmListFn = GetStrArg(); Initialise(); if (funcType == MGE_EVAL) { PerformMgeEval(); } else if (funcType == MGE_TRAIN) { PerformMgeTrain(); if (endIter > 0 && bMgeUpdate) { /* output HMM files */ ConvDiagC(&hset, TRUE); SaveHMMSet(&hset, outDir, outExt, NULL, inBinary); } } else if (funcType == MGE_ADAPT) { PerformMgeAdapt(); if (endIter > 0 && bMgeUpdate) { MakeFN(xformfn, outDir, NULL, fname); SaveOneXForm(&hset, hset.curXForm, fname, FALSE); } } ResetHeap(&hmmStack); ResetHeap(&orighmmStack); ResetHeap(&accStack); ResetHeap(&genStack); ResetHeap(&mgeStack); return 0; }
/* WriteStateDurations: output state duration to file */ void WriteStateDurations(char *labfn, GenInfo * genInfo) { char fn[MAXFNAMELEN]; int i, j, k, s, cnt, nState, modeldur; float modelMean; Label *label; FILE *durfp; Vector mean = NULL; Boolean isPipe; /* open file pointer for saving state durations */ MakeFN(labfn, genDir, durExt, fn); if ((durfp = FOpen(fn, NoOFilter, &isPipe)) == NULL) HError(9911, "WriteStateDurations: Cannot create output file %s", fn); /* prepare mean vector */ mean = CreateVector(genInfo->genMem, genInfo->maxStates); for (i = 1; i <= genInfo->labseqlen; i++) { label = GetLabN(genInfo->labseq->head, i); nState = genInfo->hmm[i]->numStates - 2; /* compose mean vector of the i-th state duration model */ for (s = cnt = 1; s <= genInfo->dset->swidth[0]; s++) { for (k = 1; k <= genInfo->dset->swidth[s]; k++, cnt++) mean[cnt] = genInfo->dm[i]->svec[2].info->pdf[s].info->spdf.cpdf[1].mpdf->mean[k]; } modeldur = 0; modelMean = 0.0; for (j = 1; genInfo->sindex[i][j] != 0; j++) { /* output state duration */ fprintf(durfp, "%s.state[%d]: duration=%d (frame), mean=%e\n", label->labid->name, genInfo->sindex[i][j], genInfo->durations[i][j], mean[genInfo->sindex[i][j] - 1]); fflush(durfp); if (trace & T_DUR) { printf("%s.state[%d]: duration=%d (frame), mean=%e\n", label->labid->name, genInfo->sindex[i][j], genInfo->durations[i][j], mean[genInfo->sindex[i][j] - 1]); fflush(stdout); } modeldur += genInfo->durations[i][j]; modelMean += mean[genInfo->sindex[i][j] - 1]; } fprintf(durfp, "%s: duration=%d (frame), mean=%e\n", label->labid->name, modeldur, modelMean); fflush(durfp); if (trace & T_DUR) { printf("%s: duration=%d (frame), mean=%e\n", label->labid->name, modeldur, modelMean); fflush(stdout); } } /* dispose mean vector */ FreeVector(genInfo->genMem, mean); /* close file pointer for saving state durations */ FClose(durfp, isPipe); return; }
/* OneIterMgeAdapt: */ static int OneIterMgeAdapt(int nIter) { char *datafn, labfn[256], basefn[255]; int nSent, nAdjNum, p, nTotalAdj; float stepSize; if (nIter > 1) nMaxBALen = 1; /* set all stat info to zero */ ResetAllStatInfo(nIter); stepSize = 1 / (A_STEP + B_STEP * nSamples); nAdjNum = 0; nTotalAdj = 0; /* process all data */ for (nSent = 0; nSent < g_nDataFileNum; nSent++) { datafn = g_pDataFileList[nSent]->datafn; /* after first boundary adjustment, use the adjusted label files */ if (nIter > 1 && bBoundAdj && outLabDir != NULL) MakeFN(datafn, outLabDir, labExt, labfn); else MakeFN(datafn, labDir, labExt, labfn); NameOf(datafn, basefn); if (trace & T_TOP) { fprintf(stdout, "Prcessing %4d %s ... \n", nSent, basefn); fflush(stdout); } /* apply transform to related models */ if (hset.curXForm != NULL) OneSentTransform(mtInfo, labfn, datafn); /* accumulation of generation error only */ if (nIter == 0) { OneSentGenErrAcc(mtInfo, labfn, datafn); } else { if (bBoundAdj) { nAdjNum = OneSentBoundAdjust(mtInfo, labfn, datafn, outLabDir, nMaxBAIter, nMaxBALen, !bMgeUpdate); if (trace & T_TOP) { fprintf(stdout, "BA Number: %d\n", nAdjNum); fflush(stdout); } nTotalAdj += nAdjNum; } if (bMgeUpdate) { OneSentMgeAdapt(mtInfo, labfn, datafn, stepSize); nSamples++; } } for (p = 1; p <= genInfo->nPdfStream[0]; p++) { total_T[p] += genInfo->pst[p].T; } /* update step size */ stepSize = 1 / (A_STEP + B_STEP * nSamples); /* fix variance floor */ if ((uFlags & UPVARS) && nSent % 100 == 0) ApplyVFloor(&hset); } if (nIter > 0 && bBoundAdj) { if (trace & T_TOP) { fprintf(stdout, "Bound Adjust Number: %d\n", nTotalAdj); fflush(stdout); } } return nSent; }
/* OneIterMgeTrain: */ static int OneIterMgeTrain(int nIter) { char *datafn, labfn[256], basefn[255]; int nSent, nAdjNum, p, nTotalAdj; float stepSize; /* set all stat info to zero */ ResetAllStatInfo(nIter); /* zero all acc info for batch mode updating */ ZeroAccsParallel(&hset, uFlags, 1); stepSize = 1 / (A_STEP + B_STEP * nSamples); nAdjNum = 0; nTotalAdj = 0; /* first refine the boundary for all data */ if (bBoundAdj && (nIter != 0 && nIter != startIter - 1)) { for (nSent = 0; nSent < g_nDataFileNum; nSent++) { datafn = g_pDataFileList[nSent]->datafn; /* after first boundary adjustment, use the adjusted label files */ if (nIter > 1 && bBoundAdj && outLabDir != NULL) MakeFN(datafn, outLabDir, labExt, labfn); else MakeFN(datafn, labDir, labExt, labfn); NameOf(datafn, basefn); if (trace & T_TOP) { fprintf(stdout, "Boundary refining %4d %s ... \n", nSent, basefn); fflush(stdout); } nAdjNum = OneSentBoundAdjust(mtInfo, labfn, datafn, outLabDir, nMaxBAIter, nMaxBALen, !bMgeUpdate); if (trace & T_TOP) { fprintf(stdout, "BA Number: %d\n", nAdjNum); fflush(stdout); } nTotalAdj += nAdjNum; } } /* process all data */ for (nSent = 0; nSent < g_nDataFileNum; nSent++) { datafn = g_pDataFileList[nSent]->datafn; /* after first boundary adjustment, use the adjusted label files */ if (nIter >= 1 && bBoundAdj && outLabDir != NULL) MakeFN(datafn, outLabDir, labExt, labfn); else MakeFN(datafn, labDir, labExt, labfn); NameOf(datafn, basefn); if (trace & T_TOP) { fprintf(stdout, "Prcessing %4d %s ... \n", nSent, basefn); fflush(stdout); } /* accumulation of generation error only */ if (nIter == 0 || nIter == startIter - 1) { OneSentGenErrAcc(mtInfo, labfn, datafn); } else if (bMgeUpdate) { OneSentMgeTrain(mtInfo, labfn, datafn, stepSize); nSamples++; } for (p = 1; p <= genInfo->nPdfStream[0]; p++) { total_T[p] += genInfo->pst[p].T; } /* update step size */ stepSize = 1 / (A_STEP + B_STEP * nSamples); /* fix variance floor */ if ((uFlags & UPVARS) && nSent % 100 == 0) ApplyVFloor(&hset); } if (nIter > 0 && bBoundAdj) { if (trace & T_TOP) { fprintf(stdout, "Bound Adjust Number: %d\n", nTotalAdj); fflush(stdout); } } if (nIter > 0 && bBoundAdj && (uFlags & UPMIXES)) UpdateAllMSDWeight(mtInfo); return nSent; }
/* DoAlignment: by creating network from transcriptions or lattices */ void DoAlignment(void) { FILE *nf; char lfn[MAXSTRLEN], buf[MAXSTRLEN]; Transcription *trans; Network *net; Boolean isPipe; int n=0; LogDouble currGenBeam; AdaptXForm *incXForm; if (trace&T_TOP) { if (loadNetworks) printf("New network will be used for each file\n"); else printf("Label file will be used to align each file\n"); fflush(stdout); } CreateHeap(&netHeap,"Net heap",MSTAK,1,0,8000,80000); while (NumArgs()>0) { if (NextArg() != STRINGARG) HError(3219,"DoAlignment: Data file name expected"); datFN = GetStrArg(); if (trace&T_TOP) { printf("Aligning File: %s\n",datFN); fflush(stdout); } if (labFileMask != NULL ) { /* support for rescoring lattice masks */ if (!MaskMatch(labFileMask,buf,datFN)) HError(2319,"DoAlignment: mask %s has no match with segemnt %s",labFileMask,datFN); MakeFN(buf,labInDir,labInExt,lfn); } else { MakeFN(datFN,labInDir,labInExt,lfn); } if (loadNetworks) { if ( (nf = FOpen(lfn,NetFilter,&isPipe)) == NULL) HError(3210,"DoAlignment: Cannot open Word Net file %s",lfn); if((wdNet = ReadLattice(nf,&netHeap,&vocab,TRUE,FALSE))==NULL) HError(3210,"DoAlignment: ReadLattice failed"); FClose(nf,isPipe); if (trace&T_TOP) { printf("Read lattice with %d nodes / %d arcs\n", wdNet->nn,wdNet->na); fflush(stdout); } } else { LabList *ll = NULL; trans=LOpen(&netHeap,lfn,ifmt); if (trans->numLists >= 1) ll = GetLabelList(trans,1); if (!ll && !bndId) HError(3233, "DoAlignment: cannot align empty transcription"); wdNet=LatticeFromLabels(ll, bndId, &vocab,&netHeap); if (trace&T_TOP) { printf("Created lattice with %d nodes / %d arcs from label file\n", wdNet->nn,wdNet->na); fflush(stdout); } } net=ExpandWordNet(&netHeap,wdNet,&vocab,&hset); ++n; currGenBeam = genBeam; /* This handles the initial input transform, parent transform setting and output transform creation */ if (UpdateSpkrStats(&hset, &xfInfo, datFN) && (!(xfInfo.useInXForm)) && (hset.semiTied == NULL)) { xfInfo.inXForm = NULL; } if (genBeamInc == 0.0) ProcessFile (datFN, net, n, currGenBeam, FALSE); else { Boolean completed; completed = ProcessFile (datFN, net, n, currGenBeam, TRUE); currGenBeam += genBeamInc; while (!completed && (currGenBeam <= genBeamLim - genBeamInc)) { completed = ProcessFile (datFN, net, n, currGenBeam, TRUE); currGenBeam += genBeamInc; } if (!completed) ProcessFile (datFN, net, n, currGenBeam, FALSE); } if (update > 0 && n%update == 0) { if (trace&T_TOP) { printf("Transforming model set\n"); fflush(stdout); } /* at every stage a new transform is created - fix?? Estimate transform and then set it up as the input XForm */ incXForm = CreateAdaptXForm(&hset,"inc"); TidyBaseAccs(); GenAdaptXForm(&hset,incXForm); xfInfo.inXForm = GetMLLRDiagCov(incXForm);; SetXForm(&hset,xfInfo.inXForm); ApplyHMMSetXForm(&hset,xfInfo.inXForm); } ResetHeap(&netHeap); } }
/* WriteParms: write generated parameter vector sequences */ void WriteParms(char *labfn, GenInfo * genInfo) { int p, t, v, k; char ext[MAXSTRLEN], fn[MAXFNAMELEN]; float ig; Vector igvec; TriMat igtm; FILE *parmfp = NULL, *pdffp = NULL; Boolean isPipe1, isPipe2; PdfStream *pst; /* get ignore value for MSD */ ig = ReturnIgnoreValue(); /* save generated parameters */ for (p = 1; p <= genInfo->nPdfStream[0]; p++) { /* p-th PdfStream */ pst = &(genInfo->pst[p]); /* create ignore value vector/triangular matrix */ igvec = CreateVector(&genStack, pst->vSize); igtm = CreateTriMat(&genStack, pst->vSize); for (v = 1; v <= pst->vSize; v++) { igvec[v] = ig; for (k = 1; k <= v; k++) igtm[v][k] = ig; } /* open file pointer for saving generated parameters */ MakeFN(labfn, genDir, pst->ext, fn); if ((parmfp = FOpen(fn, NoOFilter, &isPipe1)) == NULL) HError(9911, "WriteParms: Cannot create ouput file %s", fn); /* open file pointer for saving pdf parameters */ if (outPdf) { sprintf(ext, "%s_%s", pst->ext, pdfExt); MakeFN(labfn, genDir, ext, fn); if ((pdffp = FOpen(fn, NoOFilter, &isPipe2)) == NULL) HError(9911, "WriteParms: Cannot create output file %s", fn); } /* output generated parameter sequence */ for (t = pst->t = 1; t <= genInfo->tframe; t++) { if (pst->ContSpace[t]) { /* output generated parameters */ WriteVector(parmfp, pst->C[pst->t], inBinary); /* output pdfs */ if (outPdf) { WriteVector(pdffp, pst->mseq[pst->t], inBinary); if (pst->fullCov) WriteTriMat(pdffp, pst->vseq[pst->t].inv, inBinary); else WriteVector(pdffp, pst->vseq[pst->t].var, inBinary); } pst->t++; } else { /* output ignoreValue symbol for generated parameters */ WriteFloat(parmfp, &igvec[1], pst->order, inBinary); /* output ignoreValue symbol for pdfs */ if (outPdf) { WriteVector(pdffp, igvec, inBinary); if (pst->fullCov) WriteTriMat(pdffp, igtm, inBinary); else WriteVector(pdffp, igvec, inBinary); } } } /* close file pointer */ if (outPdf) FClose(pdffp, isPipe2); FClose(parmfp, isPipe1); /* free igvec */ FreeVector(&genStack, igvec); } return; }
/* LoadFile: load whole file or segments into segStore */ void LoadFile(char *fn) { BufferInfo info; char labfn[80]; Transcription *trans; long segStIdx,segEnIdx; static int segIdx=1; /* Between call handle on latest seg in segStore */ static int prevSegIdx=1; HTime tStart, tEnd; int i,k,s,ncas,nObs=0,segLen; LLink p; Observation obs; if((pbuf=OpenBuffer(&bufferStack, fn, 10, dff, FALSE_dup, FALSE_dup))==NULL) HError(2150,"LoadFile: Config parameters invalid"); GetBufferInfo(pbuf,&info); CheckData(fn,info); if (firstTime) InitSegStore(&info); if (segId == NULL) { /* load whole parameter file */ nObs = ObsInBuffer(pbuf); tStart = 0.0; tEnd = (info.tgtSampRate * nObs); LoadSegment(segStore, tStart, tEnd, pbuf); segIdx++; } else { /* load segment of parameter file */ MakeFN(fn,labDir,labExt,labfn); trans = LOpen(&transStack,labfn,lff); ncas = NumCases(trans->head,segId); if ( ncas > 0) { for (i=1,nObs=0; i<=ncas; i++) { p = GetCase(trans->head,segId,i); segStIdx = (long)(p->start/info.tgtSampRate); segEnIdx = (long)(p->end/info.tgtSampRate); if (segEnIdx >= ObsInBuffer(pbuf)) segEnIdx = ObsInBuffer(pbuf)-1; if (segEnIdx - segStIdx + 1 >= nStates-2) { LoadSegment(segStore, p->start, p->end, pbuf); if (trace&T_LD1) printf(" loading seg %s %f[%ld]->%f[%ld]\n",segId->name, p->start,segStIdx,p->end,segEnIdx); nObs += SegLength(segStore, segIdx); segIdx++; }else if (trace&T_LD1) printf(" seg %s %f->%f ignored\n",segId->name, p->start,p->end); } } } if (hset.hsKind == DISCRETEHS){ for (k=prevSegIdx; k<segIdx; k++){ segLen = SegLength(segStore, k); for (i=1; i<=segLen; i++){ obs = GetSegObs(segStore, k, i); for (s=1; s<=nStreams; s++){ if( (obs.vq[s] < 1) || (obs.vq[s] > maxMixInS[s])) HError(2150,"LoadFile: Discrete data value [ %d ] out of range in stream [ %d ] in file %s",obs.vq[s],s,fn); } } } prevSegIdx=segIdx; } if (trace&T_LD0) printf(" %d observations loaded from %s\n",nObs,fn); CloseBuffer(pbuf); ResetHeap(&transStack); }
/* 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; }