📄 hnet.c
字号:
/* ----------------------------------------------------------- *//* *//* ___ *//* |_| | |_/ SPEECH *//* | | | | \ RECOGNITION *//* ========= SOFTWARE */ /* *//* *//* ----------------------------------------------------------- *//* developed at: *//* *//* Speech Vision and Robotics group *//* Cambridge University Engineering Department *//* http://svr-www.eng.cam.ac.uk/ *//* *//* Entropic Cambridge Research Laboratory *//* (now part of Microsoft) *//* *//* ----------------------------------------------------------- *//* Copyright: Microsoft Corporation *//* 1995-2000 Redmond, Washington USA *//* http://www.microsoft.com *//* *//* 2001-2004 Cambridge University *//* Engineering Department *//* *//* 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: HNet.c Network and Lattice Functions *//* ----------------------------------------------------------- */char *hnet_version = "!HVER!HNet: 3.3 [CUED 28/04/05]";char *hnet_vc_id = "$Id: HNet.c,v 1.2 2005/05/12 15:51:24 jal58 Exp $";#include "HShell.h"#include "HMem.h"#include "HMath.h"#include "HWave.h"#include "HAudio.h"#include "HParm.h"#include "HLabel.h"#include "HModel.h"#include "HUtil.h"#include "HDict.h"#include "HNet.h"/* ----------------------------- Trace Flags ------------------------- */#define T_CXT 0001 /* Trace context definitions */#define T_CST 0002 /* Trace network construction */#define T_MOD 0004 /* Show models making up each word */#define T_ALL 0010 /* Show whole network */static int trace=0;static ConfParam *cParm[MAXGLOBS]; /* config parameters */static int nParm = 0;/* --------------------------- Global Flags -------------------------- */Boolean forceCxtExp=FALSE;/* force triphone context exp to get model names ie. don't use model names direct from dict without expansion (is overridden by allowCxtExp)*/Boolean forceLeftBiphones=FALSE;Boolean forceRightBiphones=FALSE;/* force biphone context exp to get model names ie. don't try triphone names*/Boolean allowCxtExp=TRUE;/* allow context exp to get model names #*/Boolean allowXWrdExp=FALSE;/* allow context exp across words*/Boolean cfWordBoundary=TRUE;/* In word internal systems treat context free phones as word boundaries.*/Boolean factorLM=FALSE;/* factor lm likelihoods throughout words*/char *frcSil=NULL,frcSilBuf[MAXSTRLEN];/* Automagically add these sil models to the end of words.*/Boolean remDupPron=TRUE;/* Remove duplicate pronunciations*/Boolean sublatmarkers=FALSE;/* Add sublatstart and sublatend markers to the lattice*/char *subLatStart="!SUBLAT_(",subLatStartBuf[MAXSTRLEN];char *subLatEnd="!)_SUBLAT",subLatEndBuf[MAXSTRLEN];/* Set these strings as the start and end sublattice markers *//* --------------------------- Initialisation ---------------------- *//* EXPORT->InitNet: register module & set configuration parameters */void InitNet(void){ Boolean b; int i; Register(hnet_version,hnet_vc_id); nParm = GetConfig("HNET", TRUE, cParm, MAXGLOBS); if (nParm>0){ if (GetConfBool(cParm,nParm,"FORCECXTEXP",&b)) forceCxtExp = b; if (GetConfBool(cParm,nParm,"FORCELEFTBI",&b)) forceLeftBiphones = b; if (GetConfBool(cParm,nParm,"FORCERIGHTBI",&b)) forceRightBiphones = b; if (GetConfBool(cParm,nParm,"ALLOWCXTEXP",&b)) allowCxtExp = b; if (GetConfBool(cParm,nParm,"ALLOWXWRDEXP",&b)) allowXWrdExp = b; if (GetConfBool(cParm,nParm,"CFWORDBOUNDARY",&b)) cfWordBoundary = b; if (GetConfBool(cParm,nParm,"FACTORLM",&b)) factorLM = b; if (GetConfStr(cParm,nParm,"ADDSILPHONES",frcSilBuf)) frcSil=frcSilBuf; if (GetConfStr(cParm,nParm,"STARTSUBLAT",subLatStartBuf)) subLatStart=subLatStartBuf; if (GetConfStr(cParm,nParm,"ENDSUBLAT",subLatEndBuf)) subLatEnd=subLatEndBuf; if (GetConfBool(cParm,nParm,"REMDUPPRON",&b)) remDupPron = b; if (GetConfBool(cParm,nParm,"MARKSUBLAT",&b)) sublatmarkers = b; if (GetConfInt(cParm,nParm,"TRACE",&i)) trace = i; }}/* ------------------------ Lattice Creation ------------------------- */#define SafeCopyString(heap,str) ((str)==NULL?NULL:CopyString((heap),(str)))/* EXPORT->NewLattice: Allocate and initialise a new lattice structure */Lattice *NewLattice(MemHeap *heap,int nn,int na){ Lattice *lat; LNode *ln; LArc *la; int i; lat=(Lattice *) New(heap,sizeof(Lattice)); lat->heap=heap; lat->nn=nn; lat->na=na; lat->format=0; lat->utterance=lat->vocab=NULL; lat->net=lat->hmms=NULL; lat->acscale=1.0; lat->lmscale=1.0; lat->wdpenalty=0.0; lat->prscale=0.0; lat->framedur=0.0; lat->logbase = 1.0; lat->tscale = 1.0; lat->subList = NULL; lat->refList = NULL; lat->subLatId = NULL; lat->chain = NULL; if (nn>0) lat->lnodes=(LNode *) New(heap, sizeof(LNode)*nn); else lat->lnodes=NULL; if (na>0) lat->larcs=(LArc *) New(heap, sizeof(LArc)*na); else lat->larcs=NULL; for(i=0,ln=lat->lnodes;i<nn;i++,ln++) { ln->time=0.0;ln->word=NULL;ln->tag=NULL; ln->score=0.0; ln->foll=ln->pred=NARC; ln->hook=NULL; ln->sublat=NULL; } for(i=0,la=lat->larcs;i<na;i++,la++) { la->aclike=la->lmlike=la->prlike=0.0; la->start=la->end=NNODE; la->farc=la->parc=NARC; la->nAlign=0;la->lAlign=NULL; } return(lat);}/* EXPORT->NewILattice: Allocate and initialise a new lattice structure */Lattice *NewILattice(MemHeap *heap,int nn,int na,Lattice *info){ Lattice *lat; LNode *ln,*in; LArc *la,*ia; int i,j; lat=(Lattice *) New(heap,sizeof(Lattice)); lat->heap=heap; lat->nn=nn; lat->na=na; lat->format = info->format; lat->voc = info->voc; lat->subLatId = info->subLatId; lat->subList=NULL; lat->refList=NULL; lat->chain=NULL; lat->utterance = SafeCopyString(heap,info->utterance); lat->vocab = SafeCopyString(heap,info->vocab); lat->hmms = SafeCopyString(heap,info->hmms); lat->net = SafeCopyString(heap,info->net); lat->acscale = info->acscale; lat->lmscale = info->lmscale; lat->wdpenalty = info->wdpenalty; lat->prscale = info->prscale; lat->framedur = info->framedur; lat->logbase = info->logbase; lat->tscale = info->tscale; if (nn==-1) { lat->lnodes=(LNode *) New(heap, sizeof(LNode)*info->nn); lat->nn=info->nn; } else if (nn>0) { lat->lnodes=(LNode *) New(heap, sizeof(LNode)*nn); lat->nn=nn; } else { lat->lnodes=NULL; lat->nn=0; } if (info->format&HLAT_SHARC) i=sizeof(LArc_S); else i=sizeof(LArc); if (na==-1) { lat->larcs=(LArc *) New(heap, i*info->na); lat->na=info->na; } else if (na>0) { lat->larcs=(LArc *) New(heap, i*na); lat->na=na; } else { lat->larcs=NULL; lat->na=0; } if (nn==-1) for(i=0,ln=lat->lnodes,in=info->lnodes;i<lat->nn;i++,ln++,in++) { *ln=*in; if (in->word==lat->voc->subLatWord){ ln->sublat=AdjSubList(lat,in->sublat->lat->subLatId, in->sublat->lat,+1); if(ln->sublat==NULL){ HError(8253, "NewILattice: AdjSubList failed"); } } if (in->foll!=NULL) ln->foll=NumbLArc(lat,LArcNumb(in->foll,info)); if (in->pred!=NULL) ln->pred=NumbLArc(lat,LArcNumb(in->pred,info)); } else for(i=0,ln=lat->lnodes;i<lat->nn;i++,ln++) { ln->time=0.0;ln->word=NULL;ln->tag=NULL; ln->score=0.0; ln->foll=ln->pred=NARC; ln->hook=NULL; ln->sublat=NULL; } if (na==-1) for(i=0;i<lat->na;i++) { la=NumbLArc(lat,i); ia=NumbLArc(info,i); if (info->format&HLAT_SHARC) *(LArc_S*)la=*(LArc_S*)ia; else *la=*ia; la->start=ia->start-info->lnodes+lat->lnodes; la->end=ia->end-info->lnodes+lat->lnodes; if (ia->farc!=NULL) la->farc=NumbLArc(lat,LArcNumb(ia->farc,info)); if (ia->parc!=NULL) la->parc=NumbLArc(lat,LArcNumb(ia->parc,info)); if (!(info->format&HLAT_SHARC) && ia->nAlign>0 && ia->lAlign!=NULL) { la->lAlign=(LAlign *) New(heap,ia->nAlign*sizeof(LAlign)); for (j=0;j<ia->nAlign;j++) la->lAlign[j]=ia->lAlign[j]; } } else for(i=0;i<lat->na;i++) { la=NumbLArc(lat,i); la->lmlike=0.0; la->start=la->end=NNODE; la->farc=la->parc=NARC; if (!(info->format&HLAT_SHARC)) la->aclike=0.0,la->nAlign=0,la->lAlign=NULL; } return(lat);}/* EXPORT->FreeLattice: free memory used by a lattice structure */void FreeLattice(Lattice *lat){ Dispose(lat->heap,lat);}/* ------------------------ Lattice Output ------------------------- */#define SUBLATHASHSIZE 101/* Search hash table for lattice matching subLatId. If subLat!=NULL *//* add (if not found) or check (if found) the new subLat definition. */static Lattice *GetSubLat(LabId subLatId,Lattice *subLat){ int h; Lattice *cur,*nxt; static Lattice **subLatHashTab = NULL; if (subLatHashTab==NULL) { /* Need to allocate and initialise table */ subLatHashTab=(Lattice **) New(&gcheap,SUBLATHASHSIZE*sizeof(Lattice *)); for (h=0;h<SUBLATHASHSIZE;h++) subLatHashTab[h]=NULL; } if (subLatId==NULL) { for (h=0;h<SUBLATHASHSIZE;h++) for (cur=subLatHashTab[h];cur!=NULL;cur=nxt) { nxt=cur->chain; cur->chain=NULL; } Dispose(&gcheap,subLatHashTab); subLatHashTab=NULL; return(NULL); } h=(((unsigned) subLatId)%SUBLATHASHSIZE); for (cur=subLatHashTab[h];cur!=NULL;cur=cur->chain) if (cur->subLatId==subLatId) break; if (subLat!=NULL) { if (cur==NULL) { /* Add this to table */ cur=subLat; cur->chain=subLatHashTab[h]; subLatHashTab[h]=cur; } if (cur!=subLat) HError(8253,"GetSubLat: All sublats must have unique names"); } return(cur);}/* Search list of sublats for current lattice for a match *//* When add>0 either add new sublat or increase usage of match *//* when add<0 either decrease usage of match and possibly remove *//* If adding new sublat get actual lattice definition from hash *//* table containing all loaded so far unless supplied *//* When add>0 if can't find sublat returns NULL - error condition */SubLatDef *AdjSubList(Lattice *lat,LabId subLatId,Lattice *subLat,int adj){ SubLatDef *p,*q,*r,*s; /* Inefficient linear search may be good enough */ for (p=lat->subList,q=NULL;p!=NULL;q=p,p=p->next) if (p->lat->subLatId==subLatId) break; if (adj<0) { if (p==NULL) HError(8253,"AdjSubList: Decreasing non-existent sublat", subLatId->name); p->usage+=adj; if (p->usage<=0) { /* First remove from refList */ for (r=p->lat->refList,s=NULL;r!=NULL;s=r,r=r->chain) if (r==p) break; if (r!=p || r==NULL) HError(8253,"AdjSubList: Could not find SubLatDef in refList"); if (s==NULL) p->lat->refList=p->chain; else s->chain=r->chain; /* Then remove from subList */ if (q==NULL) lat->subList=p->next; else q->next=p->next; p=NULL; } } else if (adj>0) { if (p==NULL) { p=(SubLatDef *) New(lat->heap,sizeof(SubLatDef)); /* p->subLatId=subLatId; */ if (subLat!=NULL) p->lat=subLat; else if ((p->lat=GetSubLat(subLatId,NULL))==NULL){ HRError(8253,"AdjSubList: SUBLAT %s not found",subLatId->name); return NULL; } p->next=lat->subList; lat->subList=p; if (p->lat==lat){ HRError(8253,"AdjSubList: Circular subLat reference to %s", subLatId->name); return NULL; } p->chain=p->lat->refList; p->lat->refList=p; p->usage=0; } p->usage+=adj; } return(p);}#define MAXLATDEPTH 32Lattice *SubLatList(Lattice *lat, Lattice *tail, int depth){ SubLatDef *sub; if (depth>MAXLATDEPTH) HError(8253,"SubLatList: Nesting too deep (%d == recursive ?)",depth); for (sub=lat->subList;sub!=NULL;sub=sub->next) { if (tail==NULL) sub->lat->chain=NULL; if (sub->lat->chain==NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -