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 + -
显示快捷键?