📄 hrec.c
字号:
if (res->n==0) {/*当前此处不被执行*/ if (cmp.tok.like>res->tok.like) res->tok=cmp.tok; } else TokSetMerge(res,&cmp.tok,cur); if (pri->models) {/*当前此处不被执行*/ align=NewNRefAlign(node,-1, res->tok.like-res->tok.lm*pri->scale, pri->frame,res->tok.align); res->tok.align=align; }}static Path *NewNRefPath(void)/*生成一个新路径,新生成的路径都放在pri->pNoRef路径链表的头部*/{ Path *path; path=(Path*) New(&pri->pathHeap,0); path->link=pri->pNoRef.link; path->knil=&pri->pNoRef; path->link->knil=path->knil->link=path; path->chain=NULL; path->used=FALSE; pri->npth++;#ifdef SANITY pri->pnlen++;#endif return(path);}static void MovePathYesRef(Path *path)/*将path从原来的路径链表(pri->pNoRef路径链表)中删除,将其移到pri->pYesRef路径链表的头部*/{/*path->link:Next path in list;path->knil:Pre path in list*/ path->link->knil=path->knil; path->knil->link=path->link; path->link=pri->pYesRef.link;/*pri->pYesRef:Head of PathYesRef linked list*/ path->knil=&pri->pYesRef; path->link->knil=path->knil->link=path;}static void RefPath(Path *path){ if (path->usage==0) { MovePathYesRef(path);#ifdef SANITY pri->pnlen--/*Number of PathNoRef list*/;pri->pylen++/*Number of PathYesRef list*/;/*此处可能被执行*/#endif } path->usage++;} static void DeRefPathPrev(Path *path)/*将path->prev的路径使用次数减1,若减到0则将其从pri->pYesRef链表中移动到pri->pNoRef的链表头部*/{ Path *pth; NxtPath tmp,*cur; tmp.prev=path->prev; tmp.chain=path->chain; for (cur=&tmp;cur!=NULL;cur=cur->chain) { if ((pth=cur->prev)!=NULL) {#ifdef SANITY if (pth->usage<=0) HError(8591,"DeRefPathPrev: Path not referenced");#endif pth->usage--; if (pth->usage==0) { pth->link->knil=pth->knil; pth->knil->link=pth->link; pth->link=pri->pNoRef.link; pth->knil=&pri->pNoRef; pth->link->knil=pth->knil->link=pth;#ifdef SANITY pri->pnlen++;pri->pylen--;#endif } } }} static void UnlinkPath(Path *path){ NxtPath *pth,*nth; path->link->knil=path->knil; path->knil->link=path->link; for (pth=path->chain;pth!=NULL;pth=nth) { nth=pth->chain; Dispose(&pri->rPthHeap,pth); }#ifdef SANITY path->link=path->knil=NULL; /* path->pron=NULL;*/ path->prev=0; path->usage=0;pri->pnlen--; path->chain=NULL; path->frame=-1;#endif Dispose(&pri->pathHeap,path); pri->npth--;}static void CollectPaths(void)/*将用过的路径从pri->pNoRef链表中移到pri->pYesRef,然后释放pri->pNoRef链表中中的数据*/{ NetInst *inst; TokenSet *cur; int i,k,n; Path *path,*plink; Align *align,*alink; for (inst=pri->head.link;inst!=NULL;inst=inst->link)/*pri->head为Head(oldest) of Inst linked list*/ if (inst->node!=NULL) { if (node_hmm(inst->node)) /*如果节点是一个HMM*/ n=inst->node->info.hmm->numStates-1; else n=1; for (i=1,cur=inst->state;i<=n;i++,cur++) {/*如果某个状态的路径使用过则将其移到pri->pYesRef链表中*/ path=cur->tok.path; if (path && !path->used) { if (path->usage!=0) MovePathYesRef(path); path->used=TRUE; }#ifdef SANITY if (path!=NULL && cur->n>0 && cur->tok.path!=cur->set[0].path) HError(8590,"CollectPaths: Top path mismatch in state %d",i);#endif for (k=1;k<cur->n;k++) { path=cur->set[k].path; if (path && !path->used) { if (path->usage!=0) MovePathYesRef(path); path->used=TRUE; } } align=cur->tok.align; if (align && !align->used) { if (align->usage!=0) MoveAlignYesRef(align); align->used=TRUE; } }/*for (i=1,cur=inst->state;i<=n;i++,cur++)结束*/ path=inst->exit->tok.path;/*得到该节点实例最后一个exit状态中似然度最大的tok中保留的路径*/ if (path && !path->used) { if (path->usage!=0) MovePathYesRef(path); path->used=TRUE; }#ifdef SANITY if (path!=0 && inst->exit->n>0 && inst->exit->tok.path!=inst->exit->set[0].path) HError(8590,"CollectPaths: Top path mismatch in state N");#endif for (k=1;k<inst->exit->n;k++) { path=inst->exit->set[k].path; if (path && !path->used) { if (path->usage!=0) MovePathYesRef(path); path->used=TRUE; } } align=inst->exit->tok.align; if (align && !align->used) { if (align->usage!=0) MoveAlignYesRef(align); align->used=TRUE; } } for (path=pri->pNoRef.link;path->link!=NULL;path=plink) {/*路径刚被创建时就被放入pri->pNoRef链表中*/ if (!path->used) { if (path->align!=NULL) DeRefAlign(path->align);/*当前此处不被执行*/ DeRefPathPrev(path);/*将path->prev的路径使用次数减1,若减到0则将其从pri->pYesRef链表中移动到pri->pNoRef的链表头部*/ plink=path->link; UnlinkPath(path);/*释放当前路径*//*printf("当前词为:%s\t",path->node->info.pron->word->wordName->name);*/ } else { path->used=FALSE; plink=path->link; } } for (path=pri->pYesRef.link;path->link!=NULL;path=path->link) {/*pri->pYesRef为Head of PathYesRef linked list*/ if (!path->used) break; path->used=FALSE; } pri->cpth=pri->npth;/*用当前的路径数更新路径收集后的路径数*//*pri->npth为Current number of path records,pri->cpth为Number of path records after last collection*/ for (align=pri->aNoRef.link;align->link!=NULL;align=alink) {/*识别时不执行此处*/ if (!align->used) { if (align->prev!=NULL) DeRefAlign(align->prev); alink=align->link; UnlinkAlign(align); } else { align->used=FALSE; alink=align->link; } } for (align=pri->aYesRef.link;align->link!=NULL;align=align->link) { if (!align->used) break; align->used=FALSE; }/*在识别时以上部分不被执行*/ pri->calign=pri->nalign;}static void StepWord1(NetNode *node) /* Just invalidate the tokens */{ node->inst->state->tok=null_token; node->inst->state->n=((pri->nToks>1)?1:0); node->inst->exit->tok=null_token; node->inst->exit->n=((pri->nToks>1)?1:0); node->inst->max=LZERO;}static void StepWord2(NetNode *node) /* Update the path - may be repeated *//*每经过一个词节点就创建一个新的路径,用新路径保存当前节点,如果旧路径没有移到pri->pYesRef路径链表中,则将其移到pri->pYesRef路径链表的头部*/{ NetInst *inst; Path *newpth,*oldpth; RelToken *cur; NxtPath *rth; int i,k; inst=node->inst; if (node->info.pron==NULL && node->tag==NULL) {/*初始化时(在startrecognition中)执行此处*//*有可能执行*/ inst->exit->tok=inst->state->tok;/*if(inst->state->tok) printf("\n执行\n");*//*exit->tok:TokenSet in exit state;state->tok:TokenSet[0..N-2]in state[1..N-1]for hmm*/ inst->exit->n=inst->state->n; for (k=0;k<inst->exit->n;k++) inst->exit->set[k]=inst->state->set[k]; } else {/*识别时执行此处*//*有可能执行*/ inst->exit->tok=inst->state->tok; if (node->info.pron!=NULL) { inst->exit->tok.like+=pri->wordpen;/*用私有识别信息的词插入惩罚属性更新节点输出状态似然度最大的tok的似然度*/ inst->exit->tok.like+=node->info.pron->prob*pri->pscale;/*用节点的发音概率及发音概率正规化因子更新节点输出状态似然度最大的tok的似然度*/ } newpth=NewNRefPath();/*每经过一个词节点都要新创建一个路径记录*/ newpth->node=node;/*新创建的路径记录保存当前节点*/ newpth->usage=0; newpth->frame=pri->frame; newpth->like=inst->exit->tok.like; newpth->lm=inst->exit->tok.lm; if ((newpth->align=inst->exit->tok.align)!=NULL)/*当前不执行此处*/ RefAlign(newpth->align); inst->exit->tok.path=newpth; inst->exit->tok.lm=0.0; inst->exit->tok.align=NULL; /*printf("\n当前node->info.pron->word->wordName->name=%s\n",node->info.pron->word->wordName->name);*/ oldpth=inst->state->tok.path; if ((newpth->prev=oldpth)!=NULL){/*此判断条件有可能为真*/ RefPath(oldpth);/*if(oldpth->node->info.pron->word->wordName->name!=node->info.pron->word->wordName->name) printf("\n旧词是%s\t新词是%s\n",oldpth->node->info.pron->word->wordName->name,node->info.pron->word->wordName->name);*//*如果旧路径没有移到pri->pYesRef路径链表中,则将其移到pri->pYesRef路径链表的头部*//*printf("\n现在oldpth->node->info.pron->word->wordName->name=%s\n",oldpth->node->info.pron->word->wordName->name);*/} /*当前pri->nToks=0*/ if (pri->nToks>1) {/*当前此处不被执行*/ inst->exit->n=1; inst->exit->set[0].path=newpth; cur=inst->state->set+1; if (inst->state->n>1) { rth=(NxtPath*) New(&pri->rPthHeap,0); newpth->chain=rth; rth->chain=NULL; rth->like=newpth->like+cur->like; rth->lm=cur->lm; if ((rth->prev=cur->path)!=NULL) RefPath(cur->path); for (i=2,cur++;i<inst->state->n;i++,cur++) { rth->chain=(NxtPath*) New(&pri->rPthHeap,0); rth=rth->chain; rth->chain=NULL; rth->like=newpth->like+cur->like; rth->lm=cur->lm; if ((rth->prev=cur->path)!=NULL) RefPath(cur->path); } } } else { inst->exit->n=0; newpth->chain=NULL; } }}static void MoveToRecent(NetInst *inst){ if (inst->node==NULL) return;/*当前不执行此处*/ /* If we are about to move the instance that is used to determine the */ /* next instance to be stepped (to the most recent end of the list) we */ /* must use the previous instance to determine the next one to step !! */ if (inst==pri->nxtInst) pri->nxtInst=inst->knil; inst->link->knil=inst->knil; inst->knil->link=inst->link; inst->link=&pri->tail; inst->knil=pri->tail.knil; inst->link->knil=inst; inst->knil->link=inst; inst->pxd=FALSE; inst->ooo=TRUE;#ifdef SANITY if (inst==pri->start_inst) HError(8521,"MoveToRecent: Loop resulted in circular move"); inst->ipos=pri->ipos++;#endif}static void ReOrderList(NetNode *node){ NetLink *dest; int i; if (node->inst!=NULL?!node->inst->ooo:TRUE) return;/*当前此处不被执行*/ node->inst->ooo=FALSE; for (i=0,dest=node->links;i<node->nlinks;i++,dest++) {/*printf("\n当前dest->node->type=%d,n_tr0=%d\n",dest->node->type,n_tr0);*/ if (!node_tr0(dest->node)){ /*执行此处时dest->node->type=3,n_tr0=4*//*printf("\n跳出时dest->node->type=%d,n_tr0=%d\n",dest->node->type,n_tr0);*/break;} if (dest->node->inst!=NULL) {MoveToRecent(dest->node->inst);/*将dest->node->inst移到pri的网络实例链表的最尾部*/} } for (i=0,dest=node->links;i<node->nlinks;i++,dest++) { if (!node_tr0(dest->node)) break; if (dest->node->inst!=NULL) ReOrderList(dest->node); }}static LogFloat LikeToWord(NetNode *node){ NetLink *dest; HMMDef *hmm; LogFloat like,best; int i,N; best=LZERO; for (i=0,dest=node->links;i<node->nlinks;i++,dest++) { if (!node_tr0(dest->node)) break; like=dest->like*pri->scale; if (like<=best) continue; if (node_word(dest->node)) { if (like>best) best=like; } else if (node_wd0(dest->node)) { /* Must be tee hmm */ if (dest->node->type!=(n_hmm+n_tr0+n_wd0)) HError(8521,"LikeToWord: Node should be hmm & tr0 & wd0 (%d)", node->type); hmm=dest->node->info.hmm; N=hmm->numStates; like+=hmm->transP[1][N]; like+=LikeToWord(dest->node); if (like>best) best=like; } } return(best);} static void AttachInst(NetNode *node){ TokenSet *cur; NetInst *inst; int i,n; inst=(NetInst*) New(&pri->instHeap,0); if (node_hmm(node))/*当前执行此处*/ n=node->info.hmm->numStates-1;/*当前n=4*/
else n=1;#ifdef SANITY if (pri->psi->stHeapIdx[n]<0) HError(8592,"AttachInst: State heap not created for %d states",n);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -