📄 hresults.c
字号:
/* ----------------------------------------------------------- *//* *//* ___ *//* |_| | |_/ SPEECH *//* | | | | \ RECOGNITION *//* ========= SOFTWARE */ /* *//* *//* ----------------------------------------------------------- *//* Copyright: Microsoft Corporation *//* 1995-2000 Redmond, Washington USA *//* http://www.microsoft.com *//* *//* Use of this software is governed by a License Agreement *//* ** See the file License for the Conditions of Use ** *//* ** This banner notice must not be removed ** *//* *//* ----------------------------------------------------------- *//* File: HResults.c: gather statistics on results *//* ----------------------------------------------------------- */char *hresults_version = "!HVER!HResults: 3.3 [CUED 28/04/05]";char *hresults_vc_id = "$Id: HResults.c,v 1.2 2005/05/12 15:51:29 jal58 Exp $";#include "HShell.h"#include "HMem.h"#include "HMath.h"#include "HWave.h"#include "HLabel.h"/* This program reads in a set of HTK Label format files (output from a recognition tool) and compares them with the corresponding transcription files. The basic output is recognition statistics for the whole file set. When the -w option is set then the DP string matching above is replaced by the NIST word spotting algorithm.*//* -------------------------- Trace Flags & Vars ------------------------ */#define T_BAS 0001 /* basic progress reporting */#define T_EVN 0002 /* show error rate for each of n lists */#define T_SPK 0004 /* trace speaker matching */#define T_NKY 0010 /* warn about non-keywords found */#define T_SPT 0020 /* show detailed word spotting scores */#define T_MEM 0040 /* trace memory usage */static int trace = 0; /* trace level */static ConfParam *cParm[MAXGLOBS]; /* configuration parameters */static int nParm = 0; /* total num params *//* ----------------------- HResults configuration ----------------------- */static Boolean wSpot = FALSE; /* true if word spotting *//* General options */static int fileLimit = INT_MAX; /* max num of label files to process */static char * labDir = NULL; /* label file directory */static char * labExt = "lab"; /* label file extension */static FileFormat rff = UNDEFF; /* ff of reference transcription files */static FileFormat tff = UNDEFF; /* ff of test transcription files */static char * nulName = "???"; /* name of null class */static LabId nulClass; /* Id of NULCLASS phone label */static Boolean ignoreCase = FALSE; /* true converts labels to upper case */static Boolean stripContexts = FALSE; /* strip triphone contexts *//* Word spotting only options */static HTime totalDur = 0.0; /* total duration of test input */static float faTimeUnit = 1.0; /* unit for measuring false alarms *//* default is 1 hour and this gives NIST std of measuring over 0 to 10 FA/hr *//* Rec only options */static Boolean fullResults = FALSE; /* enable full Results */static Boolean outTrans = FALSE; /* enable transcription output */static Boolean outPStats = FALSE; /* enable phoneme statistics */static Boolean nistAlign = FALSE; /* use NIST alignment & penalties */static Boolean nistFormat = FALSE; /* use NIST formatting */static int maxNDepth=1; /* find best of 1..max lists */static char * spkrMask = NULL; /* non-null report on per spkr basis */static char * phraseStr = "SENT"; /* label for phrase level stats */static char * phoneStr = "WORD"; /* label for phone level stats *//* ---------------------- Global Variables ----------------------- */MemHeap tempHeap; /* Stores data valid only for file */MemHeap permHeap; /* Stores global stats */static char *recfn; /* rec file name (test) */static char labfn[255]; /* lab file name (reference) */static int rlev=0; /* Label level to be used as ref */static int tlev=0; /* Label level to be scored */static LabList *ref,*test; /* the labels being compared */static Transcription *ans; /* the full set of answers */static char * refid=NULL; /* identifiers for reference material */static char recid[5][255]; /* upto 5 identifiers for */static int recidUsed = 0; /* number of test identifiers set *//* ------------------ Process Command Line ------------------------- *//* SetConfParms: set conf parms relevant to this tool */void SetConfParms(void){ char s[MAXSTRLEN]; Boolean b; int i; nParm = GetConfig("HRESULTS", TRUE, cParm, MAXGLOBS); if (nParm>0){ if (GetConfInt(cParm,nParm,"TRACE",&i)) trace = i; if (GetConfInt(cParm,nParm,"REFLEVEL",&i)) rlev = i; if (GetConfInt(cParm,nParm,"TESTLEVEL",&i)) tlev = i; if (GetConfBool(cParm,nParm,"STRIPCONTEXT",&b)) stripContexts = b; if (GetConfBool(cParm,nParm,"IGNORECASE",&b)) ignoreCase = b; if (GetConfBool(cParm,nParm,"NISTSCORE",&b)) nistFormat = nistAlign = b; if (GetConfStr(cParm,nParm,"PHRASELABEL",s)) phraseStr=CopyString(&permHeap,s); if (GetConfStr(cParm,nParm,"PHONELABEL",s)) phoneStr=CopyString(&permHeap,s); if (GetConfStr(cParm,nParm,"SPEAKERMASK",s)) spkrMask=CopyString(&permHeap,s); }}void ReportUsage(void){ printf("\nUSAGE: HResults [options] labelList recFiles...\n\n"); printf(" Option Default\n\n"); printf(" -a s Redefine string level label SENT\n"); printf(" -b s Redefine unitlevel label WORD\n"); printf(" -c Ignore case differences off\n"); printf(" -d N Find best of N levels 1\n"); printf(" -e s t Label t is equivalent to s\n"); printf(" -f Enable full results off\n"); printf(" -g fmt Set test label format to fmt HTK\n"); printf(" -h Enable NIST style formatting off\n"); printf(" -k s Results per spkr using mask s off\n"); printf(" -m N Process only the first N rec files all\n"); printf(" -n Use NIST alignment procedure off\n"); printf(" -p Output phoneme statistics off\n"); printf(" -s Strip triphone contexts off\n"); printf(" -t Output time aligned transcriptions off\n"); printf(" -u f False alarm time units (hours) 1.0\n"); printf(" -w Enable word spotting analysis off\n"); printf(" -z s Redefine null class name to s ???\n"); PrintStdOpts("GILX"); printf("\n\n");}int main(int argc, char *argv[]){ char *s,*e,*c; int fidx,count=0; MLFEntry *me; Boolean tffSet = FALSE; /* indicates rff set at command line */ void Initialise(char * listfn); void MatchFiles(void); void OutputStats(void); void AddEquiv(char * cl, char * eq); if(InitShell(argc,argv,hresults_version,hresults_vc_id)<SUCCESS) HError(3300,"HResults: InitShell failed"); InitMem(); InitMath(); InitWave(); InitLabel(); if (!InfoPrinted() && NumArgs() == 0) ReportUsage(); if (NumArgs() == 0) Exit(0); SetConfParms(); CreateHeap(&permHeap, "permHeap", MSTAK, 1, 1.0, 4000, 20000); while (NextArg() == SWITCHARG) { s = GetSwtArg(); if (strlen(s)!=1) HError(3319,"HResults: Bad switch %s; must be single letter",s); switch(s[0]){ case 'a': if (NextArg() != STRINGARG) HError(3319,"HResults: New PHRASE name expected"); phraseStr = GetStrArg(); break; case 'b': if (NextArg() != STRINGARG) HError(3319,"HResults: New PHONE name expected"); phoneStr = GetStrArg(); break; case 'c': ignoreCase = TRUE; break; case 'd': maxNDepth = GetChkedInt(1,INT_MAX,s); break; case 'e': if (NextArg() != STRINGARG) HError(3319,"HResults: Eq Class Name Expected"); c = GetStrArg(); if (NextArg() != STRINGARG) HError(3319,"HResults: Eq Label Name Expected"); e = GetStrArg(); AddEquiv(c,e); break; case 'f': fullResults = TRUE; break; case 'g': if (NextArg() != STRINGARG) HError(3319,"HResults: Label File format expected"); if((tff = Str2Format(GetStrArg())) == ALIEN) HError(-3389,"HResults: Warning ALIEN Label file format set"); tffSet = TRUE; break; case 'h': nistFormat = TRUE; break; case 'j': fileLimit = GetChkedInt(1,INT_MAX,s); break; case 'k': if (NextArg() != STRINGARG) HError(3319,"HResults: Speaker mask expected"); spkrMask = GetStrArg(); if (strchr(spkrMask,'%')==NULL) HError(3319,"HResults: Speaker mask missing speaker"); break; case 'm': fileLimit = GetChkedInt(1,INT_MAX,s); break; case 'n': nistAlign = TRUE; break; case 'p': outPStats = TRUE; break; case 's': stripContexts = TRUE; break; case 't': outTrans = TRUE; break; case 'u': faTimeUnit = GetChkedFlt(0.001, 100.0, s); break; case 'w': wSpot = TRUE; break; case 'z': if (NextArg() != STRINGARG) HError(3319,"HResults: New Null Class Name Expected"); nulName = GetStrArg(); break; case 'G': if (NextArg() != STRINGARG) HError(3319,"HResults: Label File format expected"); if((rff = Str2Format(GetStrArg())) == ALIEN) HError(-3389,"HResults: Warning ALIEN Label file format set"); if (!tffSet) tff = rff; break; case 'I': if (NextArg() != STRINGARG) HError(3319,"HResults: MLF file name expected"); refid = GetStrArg(); LoadMasterFile(refid); break; case 'L': if (NextArg()!=STRINGARG) HError(3319,"HResults: Label file directory expected"); labDir = GetStrArg(); break; case 'T': trace = GetChkedInt(0,077,s); break; case 'X': if (NextArg()!=STRINGARG) HError(3319,"HResults: Label file extension expected"); labExt = GetStrArg(); break; default: HError(3319,"HResults: Unknown switch %s",s); } } if (wSpot && (outPStats || nistAlign || nistFormat || outTrans || spkrMask != NULL)) HError(-3319,"HResults: Trying to use rec options in word spotting mode"); if (NextArg() != STRINGARG) HError(3319,"HResults: Label Id List File expected"); if (refid==NULL) refid = labDir; Initialise(GetStrArg()); if (trace&T_MEM) PrintAllHeapStats(); while (NumArgs()>0 && count<fileLimit){ if (NextArg()!=STRINGARG) HError(3319,"HResults: recognition output file name expected"); recfn = GetStrArg(); if (recidUsed<5) strcpy(recid[recidUsed++],recfn); if (IsMLFFile(recfn)){ fidx = NumMLFFiles(); if ((me=GetMLFTable()) != NULL) { while(me->next != NULL) me=me->next; LoadMasterFile(recfn); me=me->next; } else{ LoadMasterFile(recfn); me=GetMLFTable(); } while (me != NULL) { if (me->type == MLF_IMMEDIATE && me->def.immed.fidx == fidx) { recfn = me->pattern; MatchFiles(); ++count; if (count>=fileLimit) break; } me = me->next; } } else { MatchFiles(); ++count; } } if (count>=fileLimit) printf("\n** HResults terminated after %d files **\n\n",count); if (trace&T_MEM) PrintAllHeapStats(); if (count>0) OutputStats(); else printf("No transcriptions found\n"); Exit(0); return (0); /* never reached -- make compiler happy */}/* -------------------- Label Equivalences ----------------------- */typedef struct _Equiv Equiv; /* list of equivalent labels */struct _Equiv{ LabId classId; LabId equivId; Equiv *next;};static Equiv *eqlist=NULL; /* List of equivalent label ids *//* AddEquiv: Add the equivalent pair (cl,eq) to eqlist */void AddEquiv(char * cl, char * eq){ Equiv *p; p=(Equiv*)New(&permHeap,sizeof(Equiv)); p->classId = GetLabId(cl,TRUE); p->equivId = GetLabId(eq,TRUE); p->next = eqlist; eqlist = p;}/* NormaliseName: convert all equiv labels to class name and upper case if set */void NormaliseName(LabList *ll,int lev){ LabId cl,eq,id; LLink l; Equiv *p; int i,n,len; char buf[256],*ptr; n=CountAuxLabs(ll,lev); for (p=eqlist; p!=NULL; p=p->next) { cl = p->classId; eq = p->equivId; for (i=1;i<=n;i++) { l = GetAuxLabN(ll,i,lev); if (lev==0) { if (l->labid==eq) l->labid=cl; } else { if (l->auxLab[lev]==eq) l->auxLab[lev]=cl; } } } if (ignoreCase) for (i=1;i<=n;i++){ l = GetAuxLabN(ll,i,lev); id = ((lev==0) ? l->labid : l->auxLab[lev]); strcpy(buf,id->name); len = strlen(buf); for (ptr=buf;*ptr!=0;ptr++) if (islower((int) *ptr)) break; if (*ptr){ for (;*ptr!=0;ptr++) *ptr = toupper(*ptr); id = GetLabId(buf,TRUE); if (lev==0) l->labid=id; else l->auxLab[lev]=id; } }}/* ------------------ Statistics Recording --------------------- */typedef struct _Cell *CellPtr;enum _Direction{DIAG,VERT,HOR,NIL};typedef enum _Direction Direction;typedef struct _Cell{ /* used in DP routines below */ int ins,del,sub,hit; int score; Direction dir;} Cell;typedef struct _Spkr{ /* list of spkr records */ int ins,del,sub,hit; int nsyms,nphr,phrcor; struct _Spkr *next; char *name;} Spkr;/* Global Stats */static long ins = 0; /* Total insertions */static long del = 0; /* Total deletions */static long sub = 0; /* Total substitutions */static long hits = 0; /* Total hits */static long nsyms = 0; /* Total symbols */static long nphr = 0; /* Total phrases */static long phrcor= 0; /* Phrase correct */static Spkr *spkrHead = NULL;static int numSpkrs = 0;static int htkWidth = 66; /* width of output banners */static int spkrFails = 0; /* num time spkr pattern fails to match *//* SRMatch: recursively match s against pattern p, minplen is the min length string that can match p and numstars is the number of *'s in p spkr is next character of the spkr name */static Boolean SpRMatch(char *s,char *p,char *spkr, int slen,int minplen,int numstars){ Boolean match; if (slen==0 && minplen==0) match=TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -