📄 hmodel.c
字号:
/* Run-length encoding for verbose external form uses the notation w*n to mean that w is repeated n times. For binary form, all weights are stored as unsigned shorts. The msb is set to indicate that a repeat count follows. Repeat counts are stored as unsigned chars.*//* GetTiedWeights: parse src and get compact mixture weight def */ReturnStatus GetTiedWeights(Source *src, Token *tok, int M, Vector tpdf){ float weight=0.0; short repCount=0; /* repeat counter for weights */ int c,m; if (trace&T_PAR) printf("HModel: GetTiedWeights: M=%d\n",M); for (m=1; m<=M; m++) { if (repCount>0) /* get mixture weight */ --repCount; else { if (tok->binForm) { if (!ReadFloat(src,&weight,1,TRUE)){ HMError(src,"Tied Weight expected"); return(FAIL); } if (weight<0.0) { repCount=GetCh(src); --repCount; weight = weight+2.0; } } else { if (!ReadFloat(src,&weight,1,FALSE)){ HMError(src,"Discrete Weight expected"); return(FAIL); } c=GetCh(src); if (c == '*') { if (!ReadShort(src,&repCount,1,FALSE)){ HMError(src,"Discrete Repeat Count expected"); return(FAIL); } --repCount; } else UnGetCh(c,src); } } tpdf[m] = weight; /* set it */ } if(GetToken(src,tok)<SUCCESS){ HMError(src,"GetToken failed"); return(FAIL); } return(SUCCESS);}/* GetDiscreteWeights: parse src and get compact mixture weight def */ReturnStatus GetDiscreteWeights(Source *src, Token *tok, int M, ShortVec dpdf){ short weight=0; short repCount=0; /* repeat counter for weights */ int c,m; if (trace&T_PAR) printf("HModel: GetDiscreteWeights: M=%d\n",M); for (m=1; m<=M; m++) { if (repCount>0) /* get mixture weight */ --repCount; else { if (tok->binForm) { if (!ReadShort(src,&weight,1,TRUE)){ HMError(src,"Discrete Weight expected"); return(FAIL); } if (weight<0) { repCount=GetCh(src); --repCount; weight &= 077777; } } else { if (!ReadShort(src,&weight,1,FALSE)){ HMError(src,"Discrete Weight expected"); return(FAIL); } c=GetCh(src); if (c == '*') { if (!ReadShort(src,&repCount,1,FALSE)){ HMError(src,"Discrete Repeat Count expected"); return(SUCCESS); } --repCount; } else UnGetCh(c,src); } } dpdf[m] = weight; /* set it */ } if(GetToken(src,tok)<SUCCESS){ HMError(src,"GetToken failed"); return(FAIL); } return(SUCCESS);}/* InitTMixRecs: create all TMixRecs in given hset */void InitTMixRecs(HMMSet *hset, int s, int M){ TMixRec *p; MixPDF **mpp; TMProb *tm; p = hset->tmRecs+s; p->mixId = NULL; p->nMix = M; mpp = (MixPDF **)New(hset->hmem,sizeof(MixPDF *) * M); p->mixes = mpp-1; tm = (TMProb *)New(hset->hmem,sizeof(TMProb)*M); p->probs = tm-1;}/* GetTiedMixtures: parse src and get compact tied mixture def */ReturnStatus GetTiedMixtures(HMMSet *hset, Source *src, Token *tok, int M, int s, Vector tpdf){ char tmName[MAXSTRLEN],macName[2*MAXSTRLEN],intstr[20]; LabId id,mid; Boolean isNew; int m; MLink q; if (trace&T_PAR) printf("HModel: GetTiedMixtures\n"); if (!ReadString(src,tmName)){ /* read generic ~m macro name */ HMError(src,"Tied Mix macro name expected"); return(FAIL); } id = GetLabId(tmName,TRUE); isNew = hset->tmRecs[s].mixId == NULL; if (isNew) { InitTMixRecs(hset,s,M); hset->tmRecs[s].mixId = id; for (m=1; m<=M; m++){ sprintf(intstr,"%d",m); strcpy(macName,tmName); strcat(macName,intstr); if((mid = GetLabId(macName,FALSE)) == NULL){ HRError(7035,"GetTiedMixtures: Unknown tied mix macro name %s",macName); return(FAIL); } if ((q = FindMacroName(hset,'m',mid))==NULL){ HRError(7035,"GetTiedMixtures: no macro %s in this set",macName); return(FAIL); } hset->tmRecs[s].mixes[m] = (MixPDF *)q->structure; } }else { if (hset->tmRecs[s].mixId != id){ HMError(src,"Bad Generic ~m Macro Name in TMix"); return(FAIL); } if (hset->tmRecs[s].nMix != M){ HMError(src,"Inconsistent Num Mixtures in TMix"); return(FAIL); } } if(GetTiedWeights(src,tok,M,tpdf)<SUCCESS){ HMError(src, "GetTiedWeights failed"); return(FAIL); } return(SUCCESS);}/* ------------ Standard Macro Definition Input Routines ----------------- *//* GetOptions: read a global options macro, return numStates if set */static ReturnStatus GetOptions(HMMSet *hset, Source *src, Token *tok, int *nState){ int p=0; *nState=0; if (trace&T_PAR) printf("HModel: GetOptions\n"); if(GetToken(src,tok)<SUCCESS){ HMError(src,"GetOptions: GetToken failed"); return(FAIL); } while (tok->sym == PARMKIND || tok->sym == INVDIAGCOV || tok->sym == HMMSETID || tok->sym == INPUTXFORM || (tok->sym >= NUMSTATES && tok->sym <= XFORMCOV)){ if(GetOption(hset,src,tok,&p)<SUCCESS){ HMError(src,"GetOptions: GetOption failed"); return(FAIL); } if (p>*nState) *nState = p; } FreezeOptions(hset); return(SUCCESS);}/* GetStructure: next input token is a string containing macro name, a pointer to corresponding structure is returned */static Ptr GetStructure(HMMSet *hset, Source *src, char type){ char buf[MAXSTRLEN]; LabId id; MLink m; if (!ReadString(src,buf)){ HRError(7013,"GetStructure: cannot read macro name"); return(NULL); } id = GetLabId(buf,FALSE); if (id==NULL){ HRError(7035,"GetStructure: undef macro name %s, type %c",buf,type); return(NULL); } m = FindMacroName(hset,type,id); if (m==NULL){ HRError(7035,"GetStructure: no macro %s, type %c exists",buf,type); return(NULL); } if (trace&T_MAC) printf("HModel: getting structure ~%c %s -> %p\n", type,buf,m->structure); return m->structure;}static ReturnStatus CheckBaseClass(HMMSet *hset, BaseClass *bclass){ int b,ncomp=0; ILink i; MixPDF *mp; /* ensure that each component is assigned to a base class */ for (b=1;b<=bclass->numClasses;b++) { for (i=bclass->ilist[b]; i!=NULL; i=i->next) { mp = ((MixtureElem *)i->item)->mpdf; if (mp->mIdx>0) { mp->mIdx = -mp->mIdx; ncomp++; } else { /* item appears in list multiple times */ HRError(999,"Component specified multiple times"); return(FAIL); } } } /* have all the components been seen? */ if (ncomp != hset->numMix) { HRError(999,"Components missing from Base Class list (%d %d)",ncomp,hset->numMix); return(FAIL); } /* mIdx is used in HRec, so reset */ for (b=1;b<=bclass->numClasses;b++) { for (i=bclass->ilist[b]; i!=NULL; i=i->next) { mp = ((MixtureElem *)i->item)->mpdf; if (mp->mIdx<0) mp->mIdx = -mp->mIdx; else HError(999,"CompressItemList: corrupted item list"); } } return(SUCCESS);}/* AddXFormItem: create an ItemRec holding x and prepend it to list Owner is not used in these lists.*/static void AddXFormItem(MemHeap *x, Ptr item, Ptr owner, ILink *list){ ILink p; p=(ILink) New(x,sizeof(ItemRec)); p->item=item; p->owner=owner; p->next=*list; *list=p;}static void CompressItemList(MemHeap *x, ILink ilist, ILink *bilist){ ILink i,p; MixPDF *mp; MixtureElem *me; int ncomp=0,ndel=0; p = NULL; /* the first component can't have already been seen! */ for (i=ilist; i!=NULL; i=i->next) { me = (MixtureElem *)i->item; mp = me->mpdf; if (mp->mIdx>0) { mp->mIdx = -mp->mIdx; AddXFormItem(x,me,i->owner,bilist); ncomp++; } else { /* delete item from list */ ndel++; } } /* mIdx is used in HRec, so reset */ for (i=*bilist; i!=NULL; i=i->next) { mp = ((MixtureElem *)i->item)->mpdf; if (mp->mIdx<0) mp->mIdx = -mp->mIdx; else HError(999,"CompressItemList: corrupted item list"); } if ((ndel>0) && (trace&T_XFD)) printf(" CompressItemList: kept %d components, deleted %d components\n",ncomp,ndel);}static BaseClass* GetBaseClass(HMMSet *hset,Source *src, Token *tok){ BaseClass *bclass; char buf[MAXSTRLEN]; char type = 'm'; /* type of items to tie */ int nbases, i, b; ILink ilist; void SetIndexes(HMMSet *hset); if (trace&T_PAR) printf("HModel: GetBaseClass\n"); if (tok->sym == MMFIDMASK) { bclass = (BaseClass *)New(hset->hmem,sizeof(BaseClass)); bclass->fname = CopyString(hset->hmem,src->name); if (!ReadString(src,buf)){ HRError(7013,"GetBaseClass: cannot read MMFIDMASK"); return(NULL); } if(GetToken(src,tok)<SUCCESS){ HMError(src,"GetToken failed"); return(NULL); } bclass->mmfIdMask = CopyString(hset->hmem,buf); if (tok->sym == PARAMETERS) { if (!ReadString(src,buf)){ HMError(src,"<PARAMETERS> symbol expected in GetBaseClass"); return(NULL); } } bclass->bkind = Str2BaseClassKind(buf); if(GetToken(src,tok)<SUCCESS){ HMError(src,"GetToken failed"); return(NULL); } if (tok->sym == STREAMINFO) { bclass->swidth = CreateIntVec(hset->hmem,SMAX); if (!ReadInt(src,bclass->swidth,1,tok->binForm)){ HMError(src,"Num Streams Expected"); return(NULL); } if (bclass->swidth[0] >= SMAX){ HMError(src,"Stream limit exceeded"); return(NULL); } if (!ReadInt(src,bclass->swidth+1,bclass->swidth[0],tok->binForm)){ HMError(src,"Stream Widths Expected"); return(NULL); } /* Now check that things match the HMMSet */ for (i=1;i<=bclass->swidth[0];i++) if (bclass->swidth[i] != hset->swidth[i]) { HError(999,"Stream width %d [%d] does not match model set [%d]",i,bclass->swidth[i],hset->swidth[i]); return(NULL); } if(GetToken(src,tok)<SUCCESS){ HMError(src,"GetToken failed"); return(NULL); } } else { if (hset->swidth[0] != 1) HError(999,"<STREAMINFO> must be specified in multiple stream base classes"); bclass->swidth = NULL; /* indicates a single stream - don't care */ } if (tok->sym == NUMCLASSES) { if (!ReadInt(src,&nbases,1,tok->binForm)){ HMError(src,"Number of baseclasses for regression base class expected"); return(NULL); } } else { HMError(src,"<NUMCLASSES> symbol expected in GetBaseClass"); return(NULL); } if(GetToken(src,tok)<SUCCESS){ HMError(src,"GetToken failed"); return(NULL); } bclass->numClasses = nbases; bclass->ilist = (ILink *)New(hset->hmem,sizeof(ILink)*(nbases+1)); /* Set the indexes for the models - just in case being loaded from a macro */ if (!indexSet) SetIndexes(hset); /* BaseClasses Can only refer to physical HMMs for wild cards */ SetParsePhysicalHMM(TRUE); for (i=1;i<=nbases;i++) { if (tok->sym != CLASS) { HMError(src,"<CLASS> symbol expected in GetBaseClass"); return(NULL); } if (!ReadInt(src,&b,1,tok->binForm)){ HMError(src,"Number of class expected"); return(NULL); } if (b!=i) HError(999,"Error reading classes in BaseClass"); ilist= NULL; bclass->ilist[i] = NULL; PItemList(&ilist,&type,hset,src,(trace&T_PAR)); CompressItemList(hset->hmem,ilist,bclass->ilist+i); ResetUtilItemList(); /* multiple examples of the same component may be specified */ if(GetToken(src,tok)<SUCCESS){ HMError(src,"GetToken failed"); return(NULL); } } SetParsePhysicalHMM(FALSE); if (CheckBaseClass(hset,bclass)<SUCCESS) HError(999,"BaseClass check failed"); bclass->nUse = 0; } else if (tok->sym==MACRO && tok->macroType=='b'){ if((bclass=(BaseClass *)GetStructure(hset,src,'b'))==NULL){ HMError(src,"GetStructure Failed"); return(NULL); } if(GetToken(src,tok)<SUCCESS){ HMError(src,"GetToken failed"); return(NULL); } } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -