?? hutil.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 *//* *//* 2002 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: HUtil.c HMM utility routines *//* ----------------------------------------------------------- */char *hutil_version = "!HVER!HUtil: 3.2 [CUED 09/12/02]";char *hutil_vc_id = "$Id: HUtil.c,v 1.9 2002/12/19 16:37:11 ge204 Exp $";#include "HShell.h"#include "HMem.h"#include "HMath.h"#include "HSigP.h"#include "HAudio.h"#include "HWave.h"#include "HVQ.h"#include "HParm.h"#include "HLabel.h"#include "HModel.h"#include "HUtil.h"/* --------------------------- Trace Flags ------------------------- */#define T_TOP 0001 /* Top Level tracing */#define T_ITM 0002 /* Item List tracing */#define T_OCC 0004 /* Occupancy statistics tracing */static int trace = 0;static MemHeap setHeap;static MemHeap itemHeap;/* --------------------------- Initialisation ---------------------- */static ConfParam *cParm[MAXGLOBS]; /* config parameters */static int nParm = 0;/* EXPORT->InitUtil: initialise configuration parameters */void InitUtil(void){ int i; Register(hutil_version,hutil_vc_id); nParm = GetConfig("HUTIL", TRUE, cParm, MAXGLOBS); if (nParm>0){ if (GetConfInt(cParm,nParm,"TRACE",&i)) trace = i; } CreateHeap(&itemHeap,"HUtil: ItemList Heap",MHEAP,sizeof(ItemRec), 1.0,200,8000); CreateHeap(&setHeap,"HUtil: IntSet Heap",MSTAK,1,1.0,2000,16000);}/* -------------------- Clone Routines ------------------------ *//* CloneSVector: return a clone of given matrix */SVector CloneSVector(MemHeap *hmem, SVector s, Boolean sharing){ SVector t; /* the target */ if (s==NULL) return NULL; if (GetUse(s)>0 && sharing) { IncUse(s); return s; } t = CreateSVector(hmem,VectorSize(s)); CopyVector(s,t); return t;}/* CloneSMatrix: return a clone of given Matrix */SMatrix CloneSMatrix(MemHeap *hmem, SMatrix s, Boolean sharing){ SMatrix t; /* the target */ if (s==NULL) return NULL; if (GetUse(s)>0 && sharing) { IncUse(s); return s; } t = CreateSMatrix(hmem,NumRows(s),NumCols(s)); CopyMatrix(s,t); return t;}/* CloneSTriMat: return a clone of given TriMat */STriMat CloneSTriMat(MemHeap *hmem, STriMat s, Boolean sharing){ STriMat t; /* the target */ if (s==NULL) return NULL; if (GetUse(s)>0 && sharing) { IncUse(s); return s; } t = CreateSTriMat(hmem,TriMatSize(s)); CopyTriMat(s,t); return t;}/* CloneMixPDF: return a clone of given MixPDF */MixPDF *CloneMixPDF(HMMSet *hset, MixPDF *s, Boolean sharing){ MixPDF *t; if (s->nUse>0 && sharing) { ++s->nUse; return s; } t = (MixPDF*)New(hset->hmem,sizeof(MixPDF)); t->nUse = 0; t->hook = NULL; t->gConst = s->gConst; t->mean = CloneSVector(hset->hmem,s->mean,sharing); t->ckind = s->ckind; switch(s->ckind) { case DIAGC: case INVDIAGC: t->cov.var = CloneSVector(hset->hmem,s->cov.var,sharing); break; case FULLC: case LLTC: t->cov.inv = CloneSTriMat(hset->hmem,s->cov.inv,sharing); break; case XFORMC: t->cov.xform = CloneSMatrix(hset->hmem,s->cov.xform,sharing); break; } return t;}/* CloneStream: return a clone of given stream */MixtureVector CloneStream(HMMSet *hset, StreamElem *ste, Boolean sharing){ int m,M; MixtureElem *sme,*tme; MixtureVector mv; M = ste->nMix; if (hset->hsKind == PLAINHS || hset->hsKind == SHAREDHS){ tme = (MixtureElem *)New(hset->hmem,M*sizeof(MixtureElem)); mv.cpdf = tme-1; sme = ste->spdf.cpdf + 1; for (m=1; m<=M; m++,sme++,tme++){ tme->weight = sme->weight; tme->mpdf = (tme->weight>MINMIX)?CloneMixPDF(hset,sme->mpdf,sharing):NULL; } } else if (hset->hsKind == TIEDHS) { mv.tpdf = CreateVector(hset->hmem,M); CopyVector(ste->spdf.tpdf,mv.tpdf); } else { mv.dpdf = CreateShortVec(hset->hmem,M); CopyShortVec(ste->spdf.dpdf,mv.dpdf); } return mv;}/* CloneState: return a clone of given State */StateInfo *CloneState(HMMSet *hset, StateInfo *ssi, Boolean sharing){ StateInfo *tsi; /* the target */ StreamElem *tste,*sste; int s,S; if (ssi->nUse>0 && sharing) { ++ssi->nUse; return ssi; } S = hset->swidth[0]; tsi = (StateInfo *)New(hset->hmem,sizeof(StateInfo)); tsi->nUse = 0; tsi->hook = NULL; tste = (StreamElem *)New(hset->hmem,S*sizeof(StreamElem)); tsi->pdf = tste-1; sste = ssi->pdf + 1; for (s=1; s<=S; s++,tste++,sste++){ tste->nMix = sste->nMix; tste->hook = NULL; tste->spdf = CloneStream(hset,sste,sharing); } tsi->dur = CloneSVector(hset->hmem,ssi->dur,sharing); tsi->weights = CloneSVector(hset->hmem,ssi->weights,sharing); return tsi;}/* EXPORT->CloneHMM: copy src HMM into tgt. If sharing, then macros are shared */void CloneHMM(HLink src, HLink tgt, Boolean sharing){ StateElem *s,*t; int i; HMMSet *hset = src->owner; tgt->owner = src->owner; tgt->numStates = src->numStates; tgt->dur = CloneSVector(hset->hmem,src->dur,sharing); tgt->transP = CloneSMatrix(hset->hmem,src->transP,sharing); t = (StateElem *)New(hset->hmem,(tgt->numStates-2)*sizeof(StateElem)); tgt->svec = t-2; s = src->svec+2; for (i=2; i<tgt->numStates; i++,s++,t++) t->info = CloneState(hset,s->info,sharing); tgt->hook = NULL; tgt->nUse = 0;}/* -------------------- Mapping Routines ------------------------ *//* EXPORT->NewHMMScan: create new HMM scan record */void NewHMMScan(HMMSet *hset, HMMScanState *hss){ hss->hset = hset; hss->S = hset->swidth[0]; hss->isCont = (hset->hsKind == PLAINHS) || (hset->hsKind == SHAREDHS); hss->h = -1; hss->mac=NULL; if (!GoNextHMM(hss)) HError(7220,"NewHMMScan: cannot find any physical HMMs to scan");}/* EXPORT->EndHMMScan: terminate scan and restore nUse flags */void EndHMMScan(HMMScanState *hss){ ClearSeenFlags(hss->hset,CLR_ALL); hss->hmm = NULL; hss->se = NULL; hss->ste = NULL; hss->me = NULL;}/* EXPORT->GoNextHMM: Move to next unseen HMM in HMM set */Boolean GoNextHMM(HMMScanState *hss){ int M; MLink mac; mac = hss->mac ? hss->mac->next : NULL; if (mac==NULL) hss->h++; for (;hss->h<MACHASHSIZE;hss->h++) for (mac=((mac==NULL)?hss->hset->mtab[hss->h]:mac); mac!=NULL;mac=mac->next) { if (mac->type == 'h') { hss->mac = mac; hss->hmm = (HLink)mac->structure; hss->N = hss->hmm->numStates; hss->se = hss->hmm->svec+2; hss->i=2; hss->si = hss->se->info; hss->ste = hss->si->pdf+1; hss->s=1; M = hss->ste->nMix; hss->M = (M<0)?-M:M; hss->m=1; if (hss->isCont){ hss->me = hss->ste->spdf.cpdf+1; hss->mp = hss->me->mpdf; } return TRUE; } } hss->hmm = NULL; return FALSE;}/* EXPORT->GoNextState: move to next unseen state */Boolean GoNextState(HMMScanState *hss, Boolean noSkip){ Boolean stepping = FALSE, ok = TRUE; int M; while (IsSeen(hss->si->nUse) && ok){ if (hss->i < hss->N-1) { ++hss->i; ++hss->se; stepping = TRUE; hss->si = hss->se->info; } else if (noSkip) return FALSE; else{ stepping = FALSE; ok = GoNextHMM(hss); } } if (ok) { Touch(&hss->si->nUse); if (stepping){ hss->ste = hss->si->pdf+1; hss->s=1; M = hss->ste->nMix; hss->M = (M<0)?-M:M; hss->m=1; if (hss->isCont){ hss->me = hss->ste->spdf.cpdf+1; hss->mp = hss->me->mpdf; } } return TRUE; } hss->se = NULL; return FALSE;}/* EXPORT->GoNextStream: move to next unseen stream */Boolean GoNextStream(HMMScanState *hss, Boolean noSkip){ Boolean stepping = FALSE, ok = TRUE; int M; while (IsSeen(hss->ste->nMix) && ok){ if (hss->s < hss->S) { ++hss->s; ++hss->ste; stepping = TRUE; } else if (noSkip) return FALSE; else{ stepping = FALSE; ok = GoNextState(hss,FALSE); } } if (ok) { Touch(&hss->ste->nMix); if (stepping) { M = hss->ste->nMix; hss->M = (M<0)?-M:M; hss->m=1; if (hss->isCont){ hss->me = hss->ste->spdf.cpdf+1; hss->mp = hss->me->mpdf; } } return TRUE; } hss->ste = NULL; return FALSE;}/* EXPORT->GoNextMix: move to next unseen mixture component */Boolean GoNextMix(HMMScanState *hss, Boolean noSkip){ Boolean ok = TRUE; if (hss->isCont){ while (IsSeen(hss->mp->nUse) && ok){ if (hss->m < hss->M) { ++hss->m; ++hss->me; hss->mp = hss->me->mpdf; } else if (noSkip) return FALSE; else ok = GoNextStream(hss,FALSE); } if (ok) { Touch(&hss->mp->nUse); return TRUE; } } else { if (hss->m < hss->M) { ++hss->m; } else if (noSkip) return FALSE; else ok = GoNextStream(hss,FALSE); if (ok) return TRUE; } hss->me = NULL; return FALSE;}/* ----------------------- DiagC conversions ----------------------------- *//* minimum and max values used in conversions */#define MINVAR 1E-30#define MAXVAR 1E+30/* EXPORT->ConvDiagC Convert Diagonal Covariance Kind Converts all the HMMs in hset to INVDIAGC from DIAGC or vice versa. If convData is TRUE then each variance element is replaced by its reciprocal - otherwise only the CovKind in each HMM is changed and no data conversions are performed. */void ConvDiagC(HMMSet *hset, Boolean convData){ HMMScanState hss; SVector v; int k; if (hset->hsKind == DISCRETEHS || hset->hsKind == TIEDHS) return; NewHMMScan(hset, &hss); while (GoNextMix(&hss,FALSE)) { if (hss.mp->ckind == DIAGC || hss.mp->ckind == INVDIAGC){ hss.mp->ckind = (hss.mp->ckind == DIAGC)?INVDIAGC:DIAGC; if (convData){ v = hss.mp->cov.var; if (! IsSeenV(v)) { for (k=1; k<=hset->swidth[hss.s]; k++) { if (v[k] > MAXVAR) v[k] = MAXVAR; if (v[k] < MINVAR) v[k] = MINVAR; v[k] = 1/v[k]; } TouchV(v); } } } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -