search_bestfirst_main.c

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

C
2,134
字号
/** * @file   search_bestfirst_main.c *  * <JA> * @brief  妈2パス¨スタックデコ〖ディング * * Julius の妈2パスであるスタックデコ〖ディングアルゴリズムが淡揭され * ています. 妈1パスの冯蔡の帽胳トレリス攫鼠を傅に·妈1パスとは嫡羹き * の right-to-left に玫瑚を乖います. 簿棱のスコアは、妈1パスのトレリ * スとそのスコアを踏玫瑚婶のヒュ〖リスティックとして儡鲁することで· * 矢链挛の簿棱スコアを雇胃しながら玫瑚を乖います.  * * 肌帽胳礁圭の艰评のために·帽胳N-gramでは ngram_decode.c 柒の簇眶が· * 矢恕では dfa_decode.c の簇眶が脱いられます.  *  * </JA> *  * <EN> * @brief  The second pass: stack decoding * * This file implements search algorithm based on best-first stack * decoding on the 2nd pass.  The search will be performed on backward * (i.e. right-to-left) direction, using the result of 1st pass (word * trellis) as heuristics of unreached area.  Hypothesis are stored * in a global stack, and the best one will be expanded according to * the survived words in the word trellis and language constraint. * * The expanding words will be given by ngram_decode.c for N-gram * based recognition, with their langugage probabilities, or by * dfa_decode.c for grammar-based recognition, with their emitting * DFA state information. * * </EN> *  * @author Akinobu Lee * @date   Thu Sep 08 11:51:12 2005 * * $Revision: 1.8 $ *  *//* * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology * All rights reserved */#include <julius/julius.h>/* declaration of local functions */static NODE *get_best_from_stack(NODE **start, int *stacknum);static int put_to_stack(NODE *new, NODE **start, NODE **bottom, int *stacknum, int stacksize);static void put_all_in_stack(NODE **start, int *stacknum, WORD_INFO *winfo);static void free_all_nodes(NODE *node);static void put_hypo_woutput(NODE *hypo, WORD_INFO *winfo);static void put_hypo_wname(NODE *hypo, WORD_INFO *winfo);/**********************************************************************//********** 肌帽胳呈羌挝拌の充り碰て          *************************//********** allocate memory for nextword data *************************//**********************************************************************//**  * <JA> * 肌帽胳の呈羌挝拌の充り碰て.  * 肌帽胳铬输を呈羌するための NEXTWORD 芹误にメモリを充り烧ける.  *  * @param maxlen [out] 呈羌材墙な帽胳眶 * @param root [out] 充り烧け挝拌の黎片へのポインタ * @param max [in] 充り烧ける挝拌のサイズ *  * @return 充り烧けられた肌帽胳芹误へのポインタを手す.  * </JA> * <EN> * Allocate memory for next word candidates. * Allocate NEXTWORD array for storing list of candidate next words. *  * @param maxlen [out] maximum number of words that can be stored * @param root [out] pointer to the top address of allocated data * @param max [in] number of elementes to be allocated *  * @return the newly allocated pointer of NEXTWORD array. * </EN> */static NEXTWORD **nw_malloc(int *maxlen, NEXTWORD **root, int max){  NEXTWORD *nwtmp;  NEXTWORD **nw;  int i;  nw = (NEXTWORD **)mymalloc(max * sizeof(NEXTWORD *));  nwtmp = (NEXTWORD *)mymalloc(max * sizeof(NEXTWORD));  for (i=0;i<max; i++) {    nw[i] = &(nwtmp[i]);  }  *maxlen = max;  *root = nwtmp;  return nw;}/**  * <JA> * 肌帽胳の呈羌挝拌の豺庶.  *  * @param nw [in] NEXTWORD芹误 * @param root [in] nw_malloc() で涂えられた挝拌黎片へのポインタ * </JA> * <EN> * Free next word candidate area. *  * @param nw [in] pointer to NEXTWORD structure to be free. * @param root [in] pointer to the top address of allocated data previously * returned by nw_malloc() * </EN> */static voidnw_free(NEXTWORD **nw, NEXTWORD *root){  free(root);  free(nw);}/**  * <JA> * @brief  肌帽胳铬输呈羌脱の NEXTWORD 芹误のメモリ挝拌を凯磨する.  * * この簇眶は玫瑚面に肌帽胳铬输礁圭が邦れた狠に钙ばれ·芹误により驴くの * 肌帽胳铬输を呈羌できるよう NEXTWORD の面咳を realloc() する.  * 悸狠には呵介に nw_malloc() で辑今の帽胳眶尸だけ挝拌を澄瘦しており· * 帽胳N-gram蝗脱箕は钙ばれることはない. 矢恕千急では·ショ〖トポ〖ズの * スキップ借妄により觉轮の佰なる铬输を票箕に鸥倡するので· * 肌帽胳眶が胳酌眶よりも络きいことが弹こりうる.  *  * @param nwold [i/o] NEXTWORD芹误 * @param maxlen [i/o] 呵络呈羌眶を呈羌するポインタ. 附哼の呵络呈羌眶を * 掐れて钙び·簇眶柒で糠たに澄瘦された眶に恃构される.  * @param root [i/o] 挝拌黎片へのポインタを呈羌するアドレス. 簇眶柒で * 今き垂えられる. * @param num [in] 凯墓する墓さ *  * @return 凯磨された糠たな肌帽胳芹误へのポインタを手す.  * </JA> * <EN> * @brief  expand data area of NEXTWORD. * * In DFA mode, the number of nextwords can exceed the vocabulary size when * more than one DFA states are expanded by short-pause skipping. * In such case, the nextword data area should expanded here. *  * @param nwold [i/o] NEXTWORD array * @param maxlen [i/o] pointer to the maximum number of words that can be * stored.  The current number should be stored before calling this function, * and the resulting new number will be stored within this function. * @param root [i/o] address to the pointer of the allocated data.  The * value will be updated by reallocation in this function. * @param num [in] size to expand *  * @return the newlly re-allocated pointer of NEXTWORD array. * </EN> */static NEXTWORD **nw_expand(NEXTWORD **nwold, int *maxlen, NEXTWORD **root, int num){  NEXTWORD *nwtmp;  NEXTWORD **nw;  int i;  int nwmaxlen;  nwmaxlen = *maxlen + num;  nwtmp = (NEXTWORD *)myrealloc(*root, nwmaxlen * sizeof(NEXTWORD));  nw = (NEXTWORD **)myrealloc(nwold, nwmaxlen * sizeof(NEXTWORD *));  nw[0] = nwtmp;  for (i=1;i<nwmaxlen; i++) {    nw[i] = &(nwtmp[i]);  }  *maxlen = nwmaxlen;  *root = nwtmp;  return nw;}/**********************************************************************//********** 簿棱スタックの拎侯         ********************************//********** Hypothesis stack operation ********************************//**********************************************************************//**  * <JA> * スタックトップの呵锑簿棱を艰り叫す.  *  * @param start [i/o] スタックの黎片ノ〖ドへのポインタ∈今垂えられる眷圭あり∷ * @param stacknum [i/o] 附哼のスタックサイズへのポインタ∈今き垂えあり∷ *  * @return 艰り叫した呵锑簿棱のポインタを手す.  * </JA> * <EN> * Pop the best hypothesis from stack. *  * @param start [i/o] pointer to stack top node (will be modified if necessary) * @param stacknum [i/o] pointer to the current stack size (will be modified * if necessary) *  * @return pointer to the popped hypothesis. * </EN> */static NODE *get_best_from_stack(NODE **start, int *stacknum){  NODE *tmp;  /* return top */  tmp=(*start);  if ((*start)!=NULL) {		/* delete it from stack */    (*start)=(*start)->next;    if ((*start)!=NULL) (*start)->prev=NULL;    (*stacknum)--;    return(tmp);  }  else {    return(NULL);  }}/**  * <JA> * ある簿棱がスタック柒に呈羌されるかどうかチェックする.  *  * @param new [in] チェックする簿棱 * @param bottom [in] スタックの撵ノ〖ドへのポインタ * @param stacknum [in] スタックに附哼呈羌されているノ〖ド眶へのポインタ * @param stacksize [in] スタックのノ〖ド眶の惧嘎 *  * @return スタックのサイズが惧嘎に茫していないか·スコアが撵ノ〖ドよりも * よければ呈羌されるとして 0 を·それ笆嘲であれば呈羌できないとして -1 を * 手す.  * </JA> * <EN> * Check whether a hypothesis will be stored in the stack. *  * @param new [in] hypothesis to be checked * @param bottom [in] pointer to stack bottom node * @param stacknum [in] pointer to current stack size * @param stacksize [in] pointer to maximum stack size limit *  * @return 0 if it will be stored in the stack (in case @a stacknum < * @a stacksize or the score of @a new is better than bottom.  Otherwise * returns -1, which means it can not be pushed to the stack. * </EN> */static intcan_put_to_stack(NODE *new, NODE **bottom, int *stacknum, int stacksize){  /* stack size check */  if ((*stacknum + 1) > stacksize && (*bottom)->score >= new->score) {    /* new node is below the bottom: discard it */    return(-1);  }  return(0);}/**  * <JA> * スタックに糠たな簿棱を呈羌する.  * スタック柒のスコア界を雇胃した疤弥に赁掐される.  * 呈羌できなかった眷圭·涂えられた簿棱は free_node() される.  *  * @param new [in] チェックする簿棱 * @param start [i/o] スタックのトップノ〖ドへのポインタ * @param bottom [i/o] スタックの撵ノ〖ドへのポインタ * @param stacknum [i/o] スタックに附哼呈羌されているノ〖ド眶へのポインタ * @param stacksize [in] スタックのノ〖ド眶の惧嘎 *  * @return 呈羌できれば 0 を·できなかった眷圭は -1 を手す.  * </JA> * <EN> * Push a new hypothesis into the stack, keeping score order. * If not succeeded, the given new hypothesis will be freed by free_node(). *  * @param new [in] hypothesis to be checked * @param start [i/o] pointer to stack top node * @param bottom [i/o] pointer to stack bottom node * @param stacknum [i/o] pointer to current stack size * @param stacksize [in] pointer to maximum stack size limit *  * @return 0 if succeded, or -1 if failed to push because of number * limitation or too low score. * </EN> */static intput_to_stack(NODE *new, NODE **start, NODE **bottom, int *stacknum, int stacksize){  NODE *tmp;  /* stack size is going to increase... */  (*stacknum)++;  /* stack size check */  if ((*stacknum)>stacksize) {    /* stack size overflow */    (*stacknum)--;    if ((*bottom)->score < new->score) {      /* new node will be inserted in the stack: free the bottom */      tmp=(*bottom);      (*bottom)->prev->next=NULL;      (*bottom)=(*bottom)->prev;      free_node(tmp);    } else {      /* new node is below the bottom: discard it */      free_node(new);      return(-1);    }  }  /* insert new node on edge */  if ((*start)==NULL) {		/* no node in stack */    /* new node is the only node */    (*start)=new;    (*bottom)=new;    new->next=NULL;    new->prev=NULL;    return(0);  }  if ((*start)->score <= new->score) {    /* insert on the top */    new->next = (*start);    new->next->prev = new;    (*start)=new;    new->prev=NULL;    return(0);  }  if ((*bottom)->score >= new->score) {    /* insert on the bottom */    new->prev = (*bottom);    new->prev->next = new;    (*bottom)=new;    new->next=NULL;    return(0);  }      /* now the new node is between (*start) and (*bottom) */  if (((*start)->score + (*bottom)->score) / 2 > new->score) {    /* search from bottom */    tmp=(*bottom);    while(tmp->score < new->score) tmp=tmp->prev;    new->prev=tmp;    new->next=tmp->next;    tmp->next->prev=new;    tmp->next=new;  } else {    /* search from start */    tmp=(*start);    while(tmp->score > new->score) tmp=tmp->next;    new->next=tmp;    new->prev=tmp->prev;    tmp->prev->next=new;    tmp->prev=new;  }  return(0);}/**  * <JA> * スタックの面咳を链て叫蜗する. スタックの面咳は己われる. (デバッグ脱) *  * @param start [i/o] スタックのトップノ〖ドへのポインタ * @param stacknum [i/o] スタックに附哼呈羌されているノ〖ド眶へのポインタ * @param winfo [in] 帽胳辑今 * </JA> * <EN> * Output all nodes in the stack. All nodes will be lost (for debug). *  * @param start [i/o] pointer to stack top node * @param stacknum [i/o] pointer to current stack size * @param winfo [in] word dictionary * </EN> */static voidput_all_in_stack(NODE **start, int *stacknum, WORD_INFO *winfo){  NODE *ntmp;    jlog("DEBUG: hypotheses remained in global stack\n");  while ((ntmp = get_best_from_stack(start, stacknum)) != NULL) {    jlog("DEBUG: %3d: s=%f",*stacknum, ntmp->score);    put_hypo_woutput(ntmp, winfo);    free_node(ntmp);  }}/**  * <JA> * スタック柒の链簿棱を豺庶する.  *  * @param start [i/o] スタックのトップノ〖ド * </JA> * <EN> * Free all nodes in a stack. *  * @param start [i/o] stack top node * </EN> */static voidfree_all_nodes(NODE *start){  NODE *tmp;  NODE *next;  tmp=start;  while(tmp) {    next=tmp->next;    free_node(tmp);    tmp=next;  }}#ifdef CONFIDENCE_MEASURE/**********************************************************************//********** 帽胳慨完刨の纷换 ******************************************//********** Confidence scoring ****************************************//**********************************************************************/#ifdef CM_SEARCH/**************************************************************/

⌨️ 快捷键说明

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