Julius 4.2
|
00001 00053 /* 00054 * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University 00055 * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology 00056 * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology 00057 * All rights reserved 00058 */ 00059 00060 00061 #include <julius/julius.h> 00062 00064 #define MDEBUG 00065 00088 static boolean 00089 multigram_rebuild_wchmm(RecogProcess *r) 00090 { 00091 boolean ret; 00092 00093 /* re-build wchmm */ 00094 if (r->wchmm != NULL) { 00095 wchmm_free(r->wchmm); 00096 } 00097 r->wchmm = wchmm_new(); 00098 r->wchmm->lmtype = r->lmtype; 00099 r->wchmm->lmvar = r->lmvar; 00100 r->wchmm->ccd_flag = r->ccd_flag; 00101 r->wchmm->category_tree = TRUE; 00102 r->wchmm->hmmwrk = &(r->am->hmmwrk); 00103 /* assign models */ 00104 r->wchmm->dfa = r->lm->dfa; 00105 r->wchmm->winfo = r->lm->winfo; 00106 r->wchmm->hmminfo = r->am->hmminfo; 00107 if (r->wchmm->category_tree) { 00108 if (r->config->pass1.old_tree_function_flag) { 00109 ret = build_wchmm(r->wchmm, r->lm->config); 00110 } else { 00111 ret = build_wchmm2(r->wchmm, r->lm->config); 00112 } 00113 } else { 00114 ret = build_wchmm2(r->wchmm, r->lm->config); 00115 } 00116 00117 /* 起動時 -check でチェックモードへ */ 00118 if (r->config->sw.wchmm_check_flag) { 00119 wchmm_check_interactive(r->wchmm); 00120 } 00121 00122 if (ret == FALSE) { 00123 jlog("ERROR: multi-gram: failed to build (global) lexicon tree for recognition\n"); 00124 return FALSE; 00125 } 00126 00127 /* guess beam width from models, when not specified */ 00128 r->trellis_beam_width = set_beam_width(r->wchmm, r->config->pass1.specified_trellis_beam_width); 00129 switch(r->config->pass1.specified_trellis_beam_width) { 00130 case 0: 00131 jlog("STAT: multi-gram: beam width set to %d (full) by lexicon change\n", r->trellis_beam_width); 00132 break; 00133 case -1: 00134 jlog("STAT: multi-gram: beam width set to %d (guess) by lexicon change\n", r->trellis_beam_width); 00135 } 00136 00137 /* re-allocate factoring cache for the tree lexicon*/ 00138 /* for n-gram only?? */ 00139 //max_successor_cache_free(recog->wchmm); 00140 //max_successor_cache_init(recog->wchmm); 00141 00142 /* finished! */ 00143 00144 return TRUE; 00145 } 00146 00172 boolean 00173 multigram_build(RecogProcess *r) 00174 { 00175 if (r->lm->winfo != NULL) { 00176 /* re-build tree lexicon for recognition process */ 00177 if (multigram_rebuild_wchmm(r) == FALSE) { 00178 jlog("ERROR: multi-gram: failed to re-build tree lexicon\n"); 00179 return FALSE; 00180 } 00181 #ifdef MDEBUG 00182 jlog("STAT: wchmm (re)build completed\n"); 00183 #endif 00184 } 00185 return(TRUE); 00186 } 00187 00210 static boolean 00211 multigram_append_to_global(DFA_INFO *gdfa, WORD_INFO *gwinfo, MULTIGRAM *m) 00212 { 00213 /* the new grammar 'm' will be appended to the last of gdfa and gwinfo */ 00214 m->state_begin = gdfa->state_num; /* initial state ID */ 00215 m->cate_begin = gdfa->term_num; /* initial terminal ID */ 00216 m->word_begin = gwinfo->num; /* initial word ID */ 00217 00218 /* append category ID and node number of src DFA */ 00219 /* Julius allow multiple initial states: connect each initial node 00220 is not necesarry. */ 00221 dfa_append(gdfa, m->dfa, m->state_begin, m->cate_begin); 00222 /* append words of src vocabulary to global winfo */ 00223 if (voca_append(gwinfo, m->winfo, m->cate_begin, m->word_begin) == FALSE) { 00224 return FALSE; 00225 } 00226 /* append category->word mapping table */ 00227 terminfo_append(&(gdfa->term), &(m->dfa->term), m->cate_begin, m->word_begin); 00228 /* append catergory-pair information */ 00229 /* pause has already been considered on m->dfa, so just append here */ 00230 if (cpair_append(gdfa, m->dfa, m->cate_begin) == FALSE) { 00231 return FALSE; 00232 } 00233 /* re-set noise entry by merging */ 00234 if (dfa_pause_word_append(gdfa, m->dfa, m->cate_begin) == FALSE) { 00235 return FALSE; 00236 } 00237 00238 jlog("STAT: Gram #%d %s: installed\n", m->id, m->name); 00239 00240 return TRUE; 00241 } 00242 00276 int 00277 multigram_add(DFA_INFO *dfa, WORD_INFO *winfo, char *name, PROCESS_LM *lm) 00278 { 00279 MULTIGRAM *new; 00280 00281 /* allocate new gram */ 00282 new = (MULTIGRAM *)mymalloc(sizeof(MULTIGRAM)); 00283 if (name != NULL) { 00284 strncpy(new->name, name, MAXGRAMNAMELEN); 00285 } else { 00286 strncpy(new->name, "(no name)", MAXGRAMNAMELEN); 00287 } 00288 00289 new->id = lm->gram_maxid; 00290 new->dfa = dfa; 00291 new->winfo = winfo; 00292 /* will be setup and activated after multigram_update() is called once */ 00293 new->hook = MULTIGRAM_DEFAULT | MULTIGRAM_ACTIVATE; 00294 new->newbie = TRUE; /* need to setup */ 00295 new->active = FALSE; /* default: inactive */ 00296 00297 /* the new grammar is now added to gramlist */ 00298 new->next = lm->grammars; 00299 lm->grammars = new; 00300 00301 jlog("STAT: Gram #%d %s registered\n", new->id, new->name); 00302 lm->gram_maxid++; 00303 00304 return new->id; 00305 } 00306 00332 boolean 00333 multigram_delete(int delid, PROCESS_LM *lm) 00334 { 00335 MULTIGRAM *m; 00336 for(m=lm->grammars;m;m=m->next) { 00337 if (m->id == delid) { 00338 m->hook |= MULTIGRAM_DELETE; 00339 jlog("STAT: Gram #%d %s: marked delete\n", m->id, m->name); 00340 break; 00341 } 00342 } 00343 if (! m) { 00344 jlog("STAT: Gram #%d: not found\n", delid); 00345 return FALSE; 00346 } 00347 return TRUE; 00348 } 00349 00365 void 00366 multigram_delete_all(PROCESS_LM *lm) 00367 { 00368 MULTIGRAM *m; 00369 for(m=lm->grammars;m;m=m->next) { 00370 m->hook |= MULTIGRAM_DELETE; 00371 } 00372 } 00373 00390 static boolean 00391 multigram_exec_delete(PROCESS_LM *lm) 00392 { 00393 MULTIGRAM *m, *mtmp, *mprev; 00394 boolean ret_flag = FALSE; 00395 00396 /* exec delete */ 00397 mprev = NULL; 00398 m = lm->grammars; 00399 while(m) { 00400 mtmp = m->next; 00401 if (m->hook & MULTIGRAM_DELETE) { 00402 /* if any grammar is deleted, we need to rebuild lexicons etc. */ 00403 /* so tell it to the caller */ 00404 if (! m->newbie) ret_flag = TRUE; 00405 if (m->dfa) dfa_info_free(m->dfa); 00406 word_info_free(m->winfo); 00407 jlog("STAT: Gram #%d %s: purged\n", m->id, m->name); 00408 free(m); 00409 if (mprev != NULL) { 00410 mprev->next = mtmp; 00411 } else { 00412 lm->grammars = mtmp; 00413 } 00414 } else { 00415 mprev = m; 00416 } 00417 m = mtmp; 00418 } 00419 00420 return(ret_flag); 00421 } 00422 00445 int 00446 multigram_activate(int gid, PROCESS_LM *lm) /* only mark */ 00447 { 00448 MULTIGRAM *m; 00449 int ret; 00450 00451 for(m=lm->grammars;m;m=m->next) { 00452 if (m->id == gid) { 00453 if (m->hook & MULTIGRAM_DEACTIVATE) { 00454 ret = 0; 00455 m->hook &= ~(MULTIGRAM_DEACTIVATE); 00456 m->hook |= MULTIGRAM_ACTIVATE; 00457 jlog("STAT: Gram #%d %s: marked active, superceding deactivate\n", m->id, m->name); 00458 } else { 00459 if (m->hook & MULTIGRAM_ACTIVATE) { 00460 jlog("STAT: Gram #%d %s: already marked active\n", m->id, m->name); 00461 ret = 1; 00462 } else { 00463 ret = 0; 00464 m->hook |= MULTIGRAM_ACTIVATE; 00465 jlog("STAT: Gram #%d %s: marked activate\n", m->id, m->name); 00466 } 00467 } 00468 break; 00469 } 00470 } 00471 if (! m) { 00472 jlog("WARNING: Gram #%d: not found, activation ignored\n", gid); 00473 ret = -1; 00474 } 00475 00476 return(ret); 00477 } 00478 00507 int 00508 multigram_deactivate(int gid, PROCESS_LM *lm) /* only mark */ 00509 { 00510 MULTIGRAM *m; 00511 int ret; 00512 00513 for(m=lm->grammars;m;m=m->next) { 00514 if (m->id == gid) { 00515 if (m->hook & MULTIGRAM_ACTIVATE) { 00516 ret = 0; 00517 m->hook &= ~(MULTIGRAM_ACTIVATE); 00518 m->hook |= MULTIGRAM_DEACTIVATE; 00519 jlog("STAT: Gram #%d %s: marked deactivate, superceding activate\n", m->id, m->name); 00520 } else { 00521 if (m->hook & MULTIGRAM_DEACTIVATE) { 00522 jlog("STAT: Gram #%d %s: already marked deactivate\n", m->id, m->name); 00523 ret = 1; 00524 } else { 00525 ret = 0; 00526 m->hook |= MULTIGRAM_DEACTIVATE; 00527 jlog("STAT: Gram #%d %s: marked deactivate\n", m->id, m->name); 00528 } 00529 } 00530 break; 00531 } 00532 } 00533 if (! m) { 00534 jlog("WARNING: - Gram #%d: not found, deactivation ignored\n", gid); 00535 ret = -1; 00536 } 00537 00538 return(ret); 00539 } 00540 00559 static boolean 00560 multigram_exec_activate(PROCESS_LM *lm) 00561 { 00562 MULTIGRAM *m; 00563 boolean modified; 00564 00565 modified = FALSE; 00566 for(m=lm->grammars;m;m=m->next) { 00567 if (m->hook & MULTIGRAM_ACTIVATE) { 00568 m->hook &= ~(MULTIGRAM_ACTIVATE); 00569 if (!m->active) { 00570 jlog("STAT: Gram #%d %s: turn on active\n", m->id, m->name); 00571 } 00572 m->active = TRUE; 00573 modified = TRUE; 00574 } else if (m->hook & MULTIGRAM_DEACTIVATE) { 00575 m->hook &= ~(MULTIGRAM_DEACTIVATE); 00576 if (m->active) { 00577 jlog("STAT: Gram #%d %s: turn off inactive\n", m->id, m->name); 00578 } 00579 m->active = FALSE; 00580 modified = TRUE; 00581 } 00582 } 00583 return(modified); 00584 } 00585 00619 boolean /* return FALSE if no gram */ 00620 multigram_update(PROCESS_LM *lm) 00621 { 00622 MULTIGRAM *m; 00623 boolean active_changed = FALSE; 00624 boolean rebuild_flag; 00625 00626 if (lm->lmvar == LM_DFA_GRAMMAR) { 00627 /* setup additional grammar info of new ones */ 00628 for(m=lm->grammars;m;m=m->next) { 00629 if (m->newbie) { 00630 jlog("STAT: Gram #%d %s: new grammar loaded, now mash it up for recognition\n", m->id, m->name); 00631 /* map dict item to dfa terminal symbols */ 00632 if (make_dfa_voca_ref(m->dfa, m->winfo) == FALSE) { 00633 jlog("ERROR: failed to map dict <-> DFA. This grammar will be deleted\n"); 00634 /* mark as to be deleted */ 00635 m->hook |= MULTIGRAM_DELETE; 00636 continue; 00637 } 00638 /* set dfa->sp_id and dfa->is_sp */ 00639 dfa_find_pause_word(m->dfa, m->winfo, lm->am->hmminfo); 00640 /* build catergory-pair information */ 00641 jlog("STAT: Gram #%d %s: extracting category-pair constraint for the 1st pass\n", m->id, m->name); 00642 if (extract_cpair(m->dfa) == FALSE) { 00643 jlog("ERROR: failed to extract category pair. This grammar will be deleted\n"); 00644 /* mark as to be deleted */ 00645 m->hook |= MULTIGRAM_DELETE; 00646 } 00647 } 00648 } 00649 } 00650 00651 rebuild_flag = FALSE; 00652 /* delete grammars marked as "delete" */ 00653 if (multigram_exec_delete(lm)) { /* some built grammars deleted */ 00654 rebuild_flag = TRUE; /* needs rebuilding global grammar */ 00655 } 00656 /* find modified grammar */ 00657 for(m=lm->grammars;m;m=m->next) { 00658 if (m->hook & MULTIGRAM_MODIFIED) { 00659 rebuild_flag = TRUE; /* needs rebuilding global grammar */ 00660 m->hook &= ~(MULTIGRAM_MODIFIED); 00661 } 00662 } 00663 00664 if (rebuild_flag) { 00665 /* rebuild global grammar from scratch (including new) */ 00666 /* active status not changed here (inactive grammar will also included) */ 00667 /* activate/deactivate hook will be handled later, so just keep it here */ 00668 #ifdef MDEBUG 00669 jlog("STAT: re-build whole global grammar...\n"); 00670 #endif 00671 /* free old if not yet */ 00672 if (lm->dfa != NULL) { 00673 dfa_info_free(lm->dfa); 00674 lm->dfa = NULL; 00675 } 00676 if (lm->winfo != NULL) { 00677 word_info_free(lm->winfo); 00678 lm->winfo = NULL; 00679 } 00680 /* concatinate all existing grammars to global */ 00681 for(m=lm->grammars;m;m=m->next) { 00682 if (lm->lmvar == LM_DFA_GRAMMAR && lm->dfa == NULL) { 00683 lm->dfa = dfa_info_new(); 00684 dfa_state_init(lm->dfa); 00685 } 00686 if (lm->winfo == NULL) { 00687 lm->winfo = word_info_new(); 00688 winfo_init(lm->winfo); 00689 } 00690 if (m->newbie) m->newbie = FALSE; 00691 if (lm->lmvar == LM_DFA_WORD) { 00692 /* just append dictionaty */ 00693 m->word_begin = lm->winfo->num; 00694 if (voca_append(lm->winfo, m->winfo, m->id, m->word_begin) == FALSE) { 00695 jlog("ERROR: multi-gram: failed to add dictionary #%d to recognition network\n", m->id); 00696 /* mark as delete */ 00697 m->hook |= MULTIGRAM_DELETE; 00698 } 00699 } else { 00700 if (multigram_append_to_global(lm->dfa, lm->winfo, m) == FALSE) { 00701 jlog("ERROR: multi-gram: failed to add grammar #%d to recognition network\n", m->id); 00702 /* mark as delete */ 00703 m->hook |= MULTIGRAM_DELETE; 00704 } 00705 } 00706 } 00707 /* delete the error grammars if exist */ 00708 if (multigram_exec_delete(lm)) { 00709 jlog("ERROR: errorous grammar deleted\n"); 00710 } 00711 lm->global_modified = TRUE; 00712 } else { /* global not need changed by the deletion */ 00713 /* append only new grammars */ 00714 for(m=lm->grammars;m;m=m->next) { 00715 if (m->newbie) { 00716 if (lm->lmvar == LM_DFA_GRAMMAR && lm->dfa == NULL) { 00717 lm->dfa = dfa_info_new(); 00718 dfa_state_init(lm->dfa); 00719 } 00720 if (lm->winfo == NULL) { 00721 lm->winfo = word_info_new(); 00722 winfo_init(lm->winfo); 00723 } 00724 if (m->newbie) m->newbie = FALSE; 00725 if (lm->lmvar == LM_DFA_WORD) { 00726 /* just append dictionaty */ 00727 m->word_begin = lm->winfo->num; 00728 if (voca_append(lm->winfo, m->winfo, m->id, m->word_begin) == FALSE) { 00729 jlog("ERROR: multi-gram: failed to add dictionary #%d to recognition network\n", m->id); 00730 /* mark as delete */ 00731 m->hook |= MULTIGRAM_DELETE; 00732 } 00733 } else { 00734 if (multigram_append_to_global(lm->dfa, lm->winfo, m) == FALSE) { 00735 jlog("ERROR: multi-gram: failed to add grammar #%d to recognition network\n", m->id); 00736 /* mark as delete */ 00737 m->hook |= MULTIGRAM_DELETE; 00738 } 00739 } 00740 lm->global_modified = TRUE; 00741 } 00742 } 00743 } 00744 00745 /* process activate/deactivate hook */ 00746 active_changed = multigram_exec_activate(lm); 00747 00748 if (lm->global_modified) { /* if global lexicon has changed */ 00749 /* now global grammar info has been updated */ 00750 /* check if no grammar */ 00751 if (lm->lmvar == LM_DFA_GRAMMAR) { 00752 if (lm->dfa == NULL || lm->winfo == NULL) { 00753 if (lm->dfa != NULL) { 00754 dfa_info_free(lm->dfa); 00755 lm->dfa = NULL; 00756 } 00757 if (lm->winfo != NULL) { 00758 word_info_free(lm->winfo); 00759 lm->winfo = NULL; 00760 } 00761 } 00762 } 00763 #ifdef MDEBUG 00764 jlog("STAT: grammar update completed\n"); 00765 #endif 00766 } 00767 00768 if (lm->global_modified || active_changed) { 00769 return (TRUE); 00770 } 00771 00772 return FALSE; 00773 } 00774 00791 static boolean 00792 multigram_read_file_and_add(char *dfa_file, char *dict_file, PROCESS_LM *lm) 00793 { 00794 WORD_INFO *new_winfo; 00795 DFA_INFO *new_dfa; 00796 char buf[MAXGRAMNAMELEN], *p, *q; 00797 boolean ret; 00798 00799 if (dfa_file != NULL) { 00800 jlog("STAT: reading [%s] and [%s]...\n", dfa_file, dict_file); 00801 } else { 00802 jlog("STAT: reading [%s]...\n", dict_file); 00803 } 00804 00805 /* read dict*/ 00806 new_winfo = word_info_new(); 00807 00808 if (lm->lmvar == LM_DFA_GRAMMAR) { 00809 ret = init_voca(new_winfo, dict_file, lm->am->hmminfo, 00810 #ifdef MONOTREE 00811 TRUE, 00812 #else 00813 FALSE, 00814 #endif 00815 lm->config->forcedict_flag); 00816 if ( ! ret ) { 00817 jlog("ERROR: failed to read dictionary \"%s\"\n", dict_file); 00818 word_info_free(new_winfo); 00819 return FALSE; 00820 } 00821 } else if (lm->lmvar == LM_DFA_WORD) { 00822 ret = init_wordlist(new_winfo, dict_file, lm->am->hmminfo, 00823 lm->config->wordrecog_head_silence_model_name, 00824 lm->config->wordrecog_tail_silence_model_name, 00825 (lm->config->wordrecog_silence_context_name[0] == '\0') ? NULL : lm->config->wordrecog_silence_context_name, 00826 lm->config->forcedict_flag); 00827 if ( ! ret ) { 00828 jlog("ERROR: failed to read word list \"%s\"\n", dict_file); 00829 word_info_free(new_winfo); 00830 return FALSE; 00831 } 00832 } 00833 00834 new_dfa = NULL; 00835 if (lm->lmvar == LM_DFA_GRAMMAR) { 00836 /* read dfa */ 00837 new_dfa = dfa_info_new(); 00838 if (init_dfa(new_dfa, dfa_file) == FALSE) { 00839 jlog("ERROR: multi-gram: error in reading DFA\n"); 00840 word_info_free(new_winfo); 00841 dfa_info_free(new_dfa); 00842 return FALSE; 00843 } 00844 } 00845 00846 jlog("STAT: done\n"); 00847 00848 /* extract name */ 00849 p = &(dict_file[0]); 00850 q = p; 00851 while(*p != '\0') { 00852 if (*p == '/') q = p + 1; 00853 p++; 00854 } 00855 p = q; 00856 while(*p != '\0' && *p != '.') { 00857 buf[p-q] = *p; 00858 p++; 00859 } 00860 buf[p-q] = '\0'; 00861 00862 /* register the new grammar to multi-gram tree */ 00863 multigram_add(new_dfa, new_winfo, buf, lm); 00864 00865 return TRUE; 00866 00867 } 00868 00869 00886 boolean 00887 multigram_load_all_gramlist(PROCESS_LM *lm) 00888 { 00889 GRAMLIST *g; 00890 GRAMLIST *groot; 00891 boolean ok_p; 00892 00893 switch(lm->config->lmvar) { 00894 case LM_DFA_GRAMMAR: groot = lm->config->gramlist_root; break; 00895 case LM_DFA_WORD: groot = lm->config->wordlist_root; break; 00896 } 00897 00898 ok_p = TRUE; 00899 for(g = groot; g; g = g->next) { 00900 if (multigram_read_file_and_add(g->dfafile, g->dictfile, lm) == FALSE) { 00901 ok_p = FALSE; 00902 } 00903 } 00904 return(ok_p); 00905 } 00906 00926 int 00927 multigram_get_all_num(PROCESS_LM *lm) 00928 { 00929 MULTIGRAM *m; 00930 int cnt; 00931 00932 cnt = 0; 00933 for(m=lm->grammars;m;m=m->next) cnt++; 00934 return(cnt); 00935 } 00936 00958 int 00959 multigram_get_gram_from_category(int category, PROCESS_LM *lm) 00960 { 00961 MULTIGRAM *m; 00962 int tb, te; 00963 for(m = lm->grammars; m; m = m->next) { 00964 if (m->newbie) continue; 00965 tb = m->cate_begin; 00966 te = tb + m->dfa->term_num; 00967 if (tb <= category && category < te) { /* found */ 00968 return(m->id); 00969 } 00970 } 00971 return(-1); 00972 } 00973 00995 int 00996 multigram_get_gram_from_wid(WORD_ID wid, PROCESS_LM *lm) 00997 { 00998 MULTIGRAM *m; 00999 int wb, we; 01000 01001 for(m = lm->grammars; m; m = m->next) { 01002 if (m->newbie) continue; 01003 wb = m->word_begin; 01004 we = wb + m->winfo->num; 01005 if (wb <= wid && wid < we) { /* found */ 01006 return(m->id); 01007 } 01008 } 01009 return(-1); 01010 } 01011 01012 01027 void 01028 multigram_free_all(MULTIGRAM *root) 01029 { 01030 MULTIGRAM *m, *mtmp; 01031 01032 m = root; 01033 while(m) { 01034 mtmp = m->next; 01035 if (m->dfa) dfa_info_free(m->dfa); 01036 word_info_free(m->winfo); 01037 free(m); 01038 m = mtmp; 01039 } 01040 } 01041 01060 int 01061 multigram_get_id_by_name(PROCESS_LM *lm, char *gramname) 01062 { 01063 MULTIGRAM *m; 01064 01065 for(m=lm->grammars;m;m=m->next) { 01066 if (strmatch(m->name, gramname)) break; 01067 } 01068 if (!m) { 01069 jlog("ERROR: multigram: cannot find grammar \"%s\"\n", gramname); 01070 return -1; 01071 } 01072 return m->id; 01073 } 01074 01093 MULTIGRAM * 01094 multigram_get_grammar_by_name(PROCESS_LM *lm, char *gramname) 01095 { 01096 MULTIGRAM *m; 01097 01098 for(m=lm->grammars;m;m=m->next) { 01099 if (strmatch(m->name, gramname)) break; 01100 } 01101 if (!m) { 01102 jlog("ERROR: multigram: cannot find grammar \"%s\"\n", gramname); 01103 return NULL; 01104 } 01105 return m; 01106 } 01107 01126 MULTIGRAM * 01127 multigram_get_grammar_by_id(PROCESS_LM *lm, unsigned short id) 01128 { 01129 MULTIGRAM *m; 01130 01131 for(m=lm->grammars;m;m=m->next) { 01132 if (m->id == id) break; 01133 } 01134 if (!m) { 01135 jlog("ERROR: multi-gram: cannot find grammar id \"%d\"\n", id); 01136 return NULL; 01137 } 01138 return m; 01139 } 01140 01175 boolean 01176 multigram_add_words_to_grammar(PROCESS_LM *lm, MULTIGRAM *m, WORD_INFO *winfo) 01177 { 01178 int offset; 01179 01180 if (lm == NULL || m == NULL || winfo == NULL) return FALSE; 01181 01182 offset = m->winfo->num; 01183 printf("adding %d words to grammar #%d (%d words)\n", winfo->num, m->id, m->winfo->num); 01184 /* append to the grammar */ 01185 if (voca_append(m->winfo, winfo, m->id, offset) == FALSE) { 01186 jlog("ERROR: multi-gram: failed to add words to dict in grammar #%d \"%s\"\n", m->id, m->name); 01187 return FALSE; 01188 } 01189 /* update dictianary info */ 01190 if (lm->lmvar == LM_DFA_GRAMMAR) { 01191 if (m->dfa->term_num != 0) free_terminfo(&(m->dfa->term)); 01192 if (make_dfa_voca_ref(m->dfa, m->winfo) == FALSE) { 01193 jlog("ERROR: failed to map dict <-> DFA. This grammar will be deleted\n"); 01194 return FALSE; 01195 } 01196 } 01197 /* prepare for update */ 01198 m->hook |= MULTIGRAM_MODIFIED; 01199 01200 return TRUE; 01201 } 01202 01228 boolean 01229 multigram_add_words_to_grammar_by_name(PROCESS_LM *lm, char *gramname, WORD_INFO *winfo) 01230 { 01231 return(multigram_add_words_to_grammar(lm, multigram_get_grammar_by_name(lm, gramname), winfo)); 01232 } 01233 01259 boolean 01260 multigram_add_words_to_grammar_by_id(PROCESS_LM *lm, unsigned short id, WORD_INFO *winfo) 01261 { 01262 return(multigram_add_words_to_grammar(lm, multigram_get_grammar_by_id(lm, id), winfo)); 01263 } 01264 01265 /* end of file */