HTK模型扩展CreateWIModels函数

构建单词发音词内环境依赖音子,如果发音序列包含的音子数少于2,则为零。

也就是当nphones>=3时,才会触发这个操作,看for循环,只有当q>=2时,才执行循环体内。

void CreateWIModels(PronHolder *pInst,int p,int q, Network *net,HMMSetCxtInfo *hci)
{
   NetNode *node;
   HLink hmm;
   int j;
   
   for(j=q-1;j>p;j--) {
      hmm=GetHCIModel(hci,FindLContext(hci,pInst,j,0),
                      pInst->phones[j],
                      FindRContext(hci,pInst,j,0));
      if (hmm->transP[1][hmm->numStates]<LSMALL) pInst->tee=FALSE;
      
      nwi++;
      node=NewNode(net->heap,hmm,(pInst->chain==NULL?0:1));
      if (pInst->chain!=NULL) {
         nil++;
         node->links[0].node=pInst->chain;
         node->links[0].like=pInst->fct;
      }
      node->chain=pInst->chain;
      pInst->chain=node;
   }
}

比如word“STEVE”对应的pron为“s t iy v sp”,那么传到该函数的参数p=0,q=4。在for循环里,是从phone“v”开始构建节点,并逐次添加到pInst->chain后面,且节点之间也是通过各自的chain连接。但是每个发音pron的开始和结尾phone音子并没有处理,所以该函数在pInt的chain列表是t->iy->v。

再看接下来的一个函数

void CreateIEModels(Word thisWord,PronHolder *pInst,int p,int q, 
Network *net, HMMSetCxtInfo *hci)
{
   NetNode *node,*wordNode;
   HLink hmm;

   if (q==p) {
      /* One phone word */

      // 单音子单词的情况, 暂时不考虑
   }
   else {
      /* End */
      hmm=GetHCIModel(hci,FindLContext(hci,pInst,q,0),
                      pInst->phones[q],0);
      if (hmm->transP[1][hmm->numStates]<LSMALL) pInst->tee=FALSE;

      wordNode = FindWordNode(NULL,pInst->pron,pInst,n_word);
      
      nfi++; nil++;
      node=NewNode(net->heap,hmm,1);
      node->links[0].node=wordNode;
      node->links[0].like=pInst->fct;
      
      pInst->ends=node;
      pInst->nend=1;
      
      /* Start */
      hmm=GetHCIModel(hci,0,pInst->phones[p],
                      FindRContext(hci,pInst,p,0));
      if (hmm->transP[1][hmm->numStates]<LSMALL) pInst->tee=FALSE;
      
      nin++; nil++;
      node=NewNode(net->heap,hmm,1);
      node->links[0].node=(pInst->chain?pInst->chain:pInst->ends);
      node->links[0].like=pInst->fct;
      pInst->starts=node;
      pInst->nstart=1;
      
      /* Chain */
      if (pInst->chain!=NULL) {
         for (node=pInst->chain;node->chain!=NULL;
              node=node->chain);
         node->nlinks=1;
         nil++;
         node->links=(NetLink*) New(net->heap,
                                    sizeof(NetLink));
         node->links[0].node=pInst->ends;
         node->links[0].like=pInst->fct;
      }
   }
}

当q不等于p时(pron包含不止一个phone),走的是else分支。这里q为4,根据Steve单词的发音信息“s t iy v sp”,phone[4]为sp。

首先是构建(查找)单词的节点wordNode,系统把所有的单词安排在一个hash表中。然后为当前的hmm创建节点(sp),并且连接到所在单词wordNode。(这个hmm是sp,也就是词的结尾,它指向word节点。)并且pInst的ends指向该节点。看下面两行:

      node=NewNode(net->heap,hmm,1);  // hmm为sp的模型
      node->links[0].node=wordNode;   // sp节点指向wordNode
      node->links[0].like=pInst->fct;
      
      pInst->ends=node;    // 发音对象的结尾指向sp node
      pInst->nend=1;

再看下,它是如何处理pInst的开始节点的。

首先,传递给GetHCIModel的是phone是“s”(最开始的phone),获取“s”的hmm;然后利用hmm创建Node,并且把该node指向pInst的chain(它指向pron的第二个音子);并且把该节点赋给pInst的starts;预示着它作为单词发音序列的开始。

最后/* Chain */代码完成由“v”到“sp”的连接。这样整个pInst的chain模型就完整了。

      /* Chain */
      if (pInst->chain!=NULL) {
         for (node=pInst->chain;node->chain!=NULL; node=node->chain); 
             // 该行代码将node指向pInst的chain的结尾(sp之前的那个音子)
         node->nlinks=1;
         nil++;
         node->links=(NetLink*) New(net->heap, sizeof(NetLink)); // 创建一个连接
         node->links[0].node=pInst->ends;                  // 使得它指向pInst->ends(sp)
         node->links[0].like=pInst->fct; 
      }

到此为止,pInst对象内,从starts开始到ends结束,完成了lattice词格到phone网络的扩展(单音子方式)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值