graphout.c

来自「julius version 4.12.about sound recognit」· C语言 代码 · 共 2,136 行 · 第 1/5 页

C
2,136
字号
  if (r->config->graph.graph_merge_neighbor_range < 0) {    if (verbose_flag) jlog("STAT: graphout: step 4: SKIP (merge the same words with same boundary to the most likely one\n");    return;  }  if (verbose_flag) jlog("STAT: graphout: step 4: merge same words with same boundary to the most likely one\n");  count = 0;  for(wg=*rootp;wg;wg=wg->next) {    count++;    if (wg->mark == TRUE) continue;    for(we=wg->next;we;we=we->next) {      if (we->mark == TRUE) continue;      /* find same words at same position */      if (wg->wid == we->wid &&	  wg->lefttime == we->lefttime &&	  wg->righttime == we->righttime) {	/* merge contexts */	merge_contexts(wg, we);	/* swap contexts of left / right contexts */	for(i=0;i<we->leftwordnum;i++) {	  swap_rightword(we->leftword[i], we, wg, we->left_lscore[i]);	}	for(i=0;i<we->rightwordnum;i++) {	  swap_leftword(we->rightword[i], we, wg, we->right_lscore[i]);	}	/* keep the max score */	if (wg->fscore_head < we->fscore_head) {	  wg->headphone = we->headphone;	  wg->tailphone = we->tailphone;	  wg->fscore_head = we->fscore_head;	  wg->fscore_tail = we->fscore_tail;	  wg->gscore_head = we->gscore_head;	  wg->gscore_tail = we->gscore_tail;	  wg->lscore_tmp = we->lscore_tmp;#ifdef CM_SEARCH	  wg->cmscore = we->cmscore;#endif	  wg->amavg = we->amavg;	}	we->mark = TRUE;      }    }  }  erased = wordgraph_exec_erase(rootp);  if (verbose_flag) jlog("STAT: graphout: %d words merged, %d words left in lattice\n", erased, count-erased);  for(wg=*rootp;wg;wg=wg->next) {    uniq_leftword(wg);    uniq_rightword(wg);  }}/**  * <JA> * @brief  グラフ稿借妄その5¨帽胳の芦ね∈夺说惰粗∷ *  * 击た帽胳董肠箕癸を积つ票じ帽胳どうしを办つに芦ねる. 钓すずれの升は * graph_merge_neighbor_range で涂え·これが 0 か砷である眷圭は悸乖されない.  *  * @param rootp [i/o] 帽胳グラフのル〖トノ〖ドへのポインタ * @param r [i/o] 千急借妄インスタンス * </JA> * <EN> * @brief  Post-processing step 5: Bundle words (neighbor words) *  * This function bundles the same words which appears at similar place. * If the difference of both the left boundary and right right boundary * is under graph_merge_neighbor_range, it will be bundled. * If its value is lower than or equal to 0, this function does not take * effect. *  * @param rootp [i/o] pointer to root node of a word graph * @param r [i/o] recognition process instance * </EN> * * @callgraph * @callergraph *  */voidwordgraph_compaction_neighbor(WordGraph **rootp, RecogProcess *r){  WordGraph *wg, *we;  int i, count, erased;  if (r->config->graph.graph_merge_neighbor_range <= 0) {    if (verbose_flag) jlog("STAT: graphout: step 5: SKIP (merge the same words around)\n");    return;  }  if (verbose_flag) jlog("STAT: graphout: step 5: merge same words around, with %d frame margin\n", r->config->graph.graph_merge_neighbor_range);  count = 0;  for(wg=*rootp;wg;wg=wg->next) {    count++;    if (wg->mark == TRUE) continue;    for(we=wg->next;we;we=we->next) {      if (we->mark == TRUE) continue;      if (wg->wid == we->wid &&	  abs(wg->lefttime - we->lefttime) <= r->config->graph.graph_merge_neighbor_range &&	  abs(wg->righttime - we->righttime) <= r->config->graph.graph_merge_neighbor_range) {	/* merge contexts */	merge_contexts(wg, we);	/* swap contexts of left / right contexts */	for(i=0;i<we->leftwordnum;i++) {	  swap_rightword(we->leftword[i], we, wg, we->left_lscore[i]);	}	for(i=0;i<we->rightwordnum;i++) {	  swap_leftword(we->rightword[i], we, wg, we->right_lscore[i]);	}	/* keep the max score */	if (wg->fscore_head < we->fscore_head) {	  wg->headphone = we->headphone;	  wg->tailphone = we->tailphone;	  wg->fscore_head = we->fscore_head;	  wg->fscore_tail = we->fscore_tail;	  wg->gscore_head = we->gscore_head;	  wg->gscore_tail = we->gscore_tail;	  wg->lscore_tmp = we->lscore_tmp;#ifdef CM_SEARCH	  wg->cmscore = we->cmscore;#endif	  wg->amavg = we->amavg;	}	we->mark = TRUE;      }    }  }  erased = wordgraph_exec_erase(rootp);  if (verbose_flag) jlog("STAT: graphout: %d words merged, %d words left in lattice\n", erased, count-erased);  for(wg=*rootp;wg;wg=wg->next) {    uniq_leftword(wg);    uniq_rightword(wg);  } }/**************************************************************//* generation of graph word candidates while search *//**  * <JA> * 糠たな帽胳グラフ铬输を栏喇して手す. この箕爬ではまだ帽胳グラフ面には * 判峡されていない.  *  * @param wid [in] 帽胳ID * @param wid_left [in] word ID of left context for determining head phone  * @param wid_right [in] word ID of right context for determining tail phone  * @param leftframe [in] 幌眉箕癸(フレ〖ム) * @param rightframe [in] 姜眉箕癸(フレ〖ム) * @param fscore_head [in] 幌眉での婶尸矢スコア (g + h) * @param fscore_tail [in] 姜眉での婶尸矢スコア (g + h) * @param gscore_head [in] 黎片での掐蜗琐眉からのViterbiスコア (g) * @param gscore_tail [in] 琐萨での掐蜗琐眉からのViterbiスコア (g) * @param lscore [in] 咐胳スコア * @param cm [in] 慨完刨 * @param r [in] 千急借妄インスタンス *  * @return 糠たに栏喇されたグラフ帽胳铬输へのポインタ * </JA> * <EN> * Return a newly allocated graph word candidates.  The resulting word * is not registered to the word graph yet. *  * @param wid [in] word ID * @param wid_left [in] word ID of left context for determining head phone  * @param wid_right [in] word ID of right context for determining tail phone  * @param leftframe [in] beginning time in frames * @param rightframe [in] end time in frames * @param fscore_head [in] sentence score on search at word head (g + h) * @param fscore_tail [in] sentence score on search at word tail (g + h) * @param gscore_head [in] Viterbi score accumulated from input end at word head (g) * @param gscore_tail [in] Viterbi score accumulated from input end at word tail (g) * @param lscore [in] language score * @param cm [in] confidence score * @param r [in] recognition process instance *  * @return pointer to the newly created graph word candidate. * </EN> * * @callgraph * @callergraph *  */WordGraph *wordgraph_assign(WORD_ID wid, WORD_ID wid_left, WORD_ID wid_right, int leftframe, int rightframe, LOGPROB fscore_head, LOGPROB fscore_tail, LOGPROB gscore_head, LOGPROB gscore_tail, LOGPROB lscore, LOGPROB cm, RecogProcess *r){  WordGraph *newarc;  HMM_Logical *l, *ret, *head, *tail;  WORD_INFO *winfo;  winfo = r->lm->winfo;  /* find context dependent phones at head and tail */  l = winfo->wseq[wid][winfo->wlen[wid]-1];  if (wid_right != WORD_INVALID) {    ret = get_right_context_HMM(l, winfo->wseq[wid_right][0]->name, r->am->hmminfo);    if (ret != NULL) l = ret;  }  if (winfo->wlen[wid] > 1) {    tail = l;    l = winfo->wseq[wid][0];  }  if (wid_left != WORD_INVALID) {    ret = get_left_context_HMM(l, winfo->wseq[wid_left][winfo->wlen[wid_left]-1]->name, r->am->hmminfo);    if (ret != NULL) l = ret;  }  head = l;  if (winfo->wlen[wid] <= 1) {    tail = l;  }  /* generate a new graph word hypothesis */  newarc = wordgraph_new(wid, head, tail, leftframe, rightframe, fscore_head, fscore_tail, gscore_head, gscore_tail, lscore, cm);  //jlog("DEBUG:     [%d..%d] %d\n", leftframe, rightframe, wid);  return newarc;}/**  * <JA> * グラフ帽胳铬输を帽胳グラフの办婶として澄年する. 澄年されたグラフ帽胳には * saved に TRUE がセットされる.  *  * @param wg [i/o] 判峡するグラフ帽胳铬输 * @param right [i/o] @a wg の宝コンテキストとなる帽胳 * @param root [i/o] 澄年貉み帽胳グラフのル〖トノ〖ドへのポインタ * </JA> * <EN> * Register a graph word candidate to the word graph as a member. * The registered word will have the saved member to be set to TRUE. *  * @param wg [i/o] graph word candidate to be registered * @param right [i/o] right context graph word * @param root [i/o] pointer to root node of already registered word graph * </EN> * * @callgraph * @callergraph *  */voidwordgraph_save(WordGraph *wg, WordGraph *right, WordGraph **root){  if (wg != NULL) {    wg->next = *root;    *root = wg;    wg->saved = TRUE;    wordgraph_add_leftword(right, wg, wg->lscore_tmp);    wordgraph_add_rightword(wg, right, wg->lscore_tmp);  }}#ifdef GRAPHOUT_DYNAMIC/**  * <JA> * ある帽胳グラフ铬输について·贷に澄年したグラフ帽胳面に票じ疤弥に * 票じ帽胳があるかどうかを拇べる. もしあれば·帽胳グラフ铬输の * コンテキストをその澄年貉みグラフ帽胳にマ〖ジする.  * * GRAPHOUT_SEARCH年盗箕は·さらにここで玫瑚を面贿すべきかどうかも冉年する.  * すなわち·肌帽胳簿棱がそのグラフ帽胳の焊コンテキストとして贷に澄年した * グラフ帽胳面にあれば·それ笆惧の鸥倡は稍妥で玫瑚を面贿すべきと冉年する.  *  * @param now [i/o] 帽胳グラフ铬输 * @param root [i/o] 澄年貉み帽胳グラフのル〖トノ〖ドへのポインタ * @param next_wid [in] 肌帽胳簿棱 * @param merged_p [out] 玫瑚を面贿すべきなら TRUE·鲁乖してよければ * FALSE が呈羌される (GRAPHOUT_SEARCH 年盗箕) * @param jconf [in] 玫瑚脱肋年パラメ〖タ *  * @return 票じ疤弥に票じ帽胳があった眷圭·マ〖ジした黎の * 澄年貉みグラフ帽胳へのポインタを手す. もしなかった眷圭·NULL を手す.  * </JA> * <EN> * Check if a graph word with the same word ID and same position as the * given graph word candidate exists in the already registered word graph. * If such graph word is found, the word contexts of the given word * graph candidate will be merged to the found graph word in the registered * word graph. * * When GRAPHOUT_SEARCH is defined, whether to terminate the search at here * will be determined here.  That is, if the next word in search already * exists in the list of left context words of the merged graph word, * it is determined that the next path has already been expanded and thus * there is no need to proceed more on this hypothesis. *  * @param now [i/o] graph word candidate * @param root [i/o] pointer to root node of already registered word graph * @param next_wid [in] next word on search * @param merged_p [out] will be set to TRUE if search should be terminated, * or FALSE if search should be proceeded (when GRAPHOUT_SEARCH defined) * @param jconf [in] configuration parameters for this search *  * @return the pointer to the already registered graph word when the same * word was found on the same position, or NULL if such word not found in * already registered word graph. * </EN> * * @callgraph * @callergraph *  */WordGraph *wordgraph_check_merge(WordGraph *now, WordGraph **root, WORD_ID next_wid, boolean *merged_p, JCONF_SEARCH *jconf){  WordGraph *wg;  int i;#ifdef GDEBUG  WordGraph *w;#endif#ifdef GRAPHOUT_SEARCH  *merged_p = FALSE;#endif  if (now == NULL) return(NULL);#ifdef GDEBUG  jlog("DEBUG: check_merge: checking \"%s\"[%d..%d]\n", wchmm_local->winfo->woutput[now->wid], now->lefttime, now->righttime);  for(i=0;i<now->leftwordnum;i++) {    w = now->leftword[i];    jlog("DEBUG: \t left%d:  \"%15s\"[%d..%d]\n", i, wchmm_local->winfo->woutput[w->wid], w->lefttime, w->righttime);  }  for(i=0;i<now->rightwordnum;i++) {    w = now->rightword[i];    jlog("DEBUG: \tright%d:  \"%15s\"[%d..%d]\n", i, wchmm_local->winfo->woutput[w->wid], w->lefttime, w->righttime);  }#endif  for(wg=*root;wg;wg=wg->next) {    if (wg == now) continue;#ifdef GRAPHOUT_DYNAMIC    /* skip already merged word */    if (wg->purged) continue;#endif    if (jconf->graph.graph_merge_neighbor_range < 0) {      /* when no merging, words with different triphone context at word edge	 should be differenciated */      if (wg->headphone != now->headphone || wg->tailphone != now->tailphone) {	continue;      }    }    if (wg->wid == now->wid	&& wg->lefttime == now->lefttime	&& wg->righttime == now->righttime) {      /* same word on the same position is found in current word graph */#ifdef GDEBUG      jlog("DEBUG: check_merge: same word found: \"%s\"[%d..%d]\n", wchmm_local->winfo->woutput[wg->wid], wg->lefttime, wg->righttime);      for(i=0;i<wg->leftwordnum;i++) {	w = wg->leftword[i];	jlog("DEBUG: \t left%d:  \"%15s\"[%d..%d]\n", i, wchmm_local->winfo->woutput[w->wid], w->lefttime, w->righttime);      }      for(i=0;i<wg->rightwordnum;i++) {	w = wg->rightword[i];	jlog("DEBUG: \tright%d:  \"%15s\"[%d..%d]\n", i, wchmm_local->winfo->woutput[w->wid], w->lefttime, w->righttime);      }#endif      /* merge contexts */      merge_contexts(wg, now);      /* swap contexts of left / right contexts */      for(i=0;i<now->leftwordnum;i++) {	swap_rightword(now->leftword[i], now, wg, now->left_lscore[i]);	uniq_rightword(now->leftword[i]);      }      for(i=0;i<now->rightwordnum;i++) {	swap_leftword(now->rightword[i], now, wg, now->right_lscore[i]);	uniq_leftword(now->rightword[i]);      }#ifdef GRAPHOUT_SEARCH      /* if the left and right contexts of now are already included in wg,	 and wg already has left node of next word,	 it means that	 the current word and the last word context is	 already included in the existing word graph.	 So, in the case this partial path should be abandoned.      */      for(i=0;i<wg->leftwordnum;i++) {	if (wg->leftword[i]->wid == next_wid) break;      }      if (i < wg->leftwordnum) {	*merged_p = TRUE;      }#endif /* GRAPHOUT_SEARCH */#ifdef GRAPHOUT_OVERWRITE      /*  if current hypothesis score is higher than saved,	  overwrite the scores and not terminate */      if (#ifdef GRAPHOUT_OVERWRITE_GSCORE	  //wg->gscore_head < now->gscore_head	  wg->amavg < now->amavg;#else	  wg->fscore_head < now->fscore_head#endif	  ) {	  wg->headphone = now->headphone;	  wg->tailphone = now->tailphone;	  wg->fscore_head = now->fscore_head;	  wg->fscore_tail = now->fscore_tail;	  wg->gscore_head = now->gscore_head;	  wg->gscore_tail = now->gscore_tail;	  wg->lscore_tmp = now->lscore_tmp;#ifdef CM_SEARCH	  wg->cmscore = now->cmscore;#endif	  wg->amavg = now->amavg;#ifdef GRAPHOUT_SEARCH	  *merged_p = FALSE;#endif      }#endif /* GRAPHOUT_OVERWRITE */      /* the merged word should be discarded for later merging from	 another word, so disable this */      now->purged = TRUE;            /* return the found one */      return wg;    }  }  /* if the same word not found, return NULL */  return

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?