00001 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 #include <julius.h>
00081 
00082 static char rbuf[MAX_HMMNAME_LEN]; 
00083 
00084 #ifdef PASS1_IWCD
00085 
00098 void
00099 outprob_style_cache_init(WCHMM_INFO *wchmm)
00100 {
00101   int n;
00102   for(n=0;n<wchmm->n;n++) {
00103 #ifdef MULTIPATH_VERSION
00104     if (wchmm->state[n].out.state == NULL) continue;
00105 #endif
00106     if (wchmm->outstyle[n] == AS_RSET) {
00107       (wchmm->state[n].out.rset)->cache.state = NULL;
00108     } else if (wchmm->outstyle[n] == AS_LRSET) {
00109       (wchmm->state[n].out.lrset)->cache.state = NULL;
00110     }
00111   }
00112 }
00113 
00114 
00115 
00116 #ifdef CATEGORY_TREE
00117 
00118 static char lccbuf[MAX_HMMNAME_LEN+7]; 
00119 static char lccbuf2[MAX_HMMNAME_LEN+7]; 
00120 
00143 CD_Set *
00144 lcdset_lookup_with_category(WCHMM_INFO *wchmm, HMM_Logical *hmm, WORD_ID category)
00145 {
00146   CD_Set *cd;
00147 
00148   leftcenter_name(hmm->name, lccbuf);
00149   sprintf(lccbuf2, "%s::%04d", lccbuf, category);
00150   if (wchmm->lcdset_category_root != NULL) {
00151     cd = aptree_search_data(lccbuf2, wchmm->lcdset_category_root);
00152     if (strmatch(lccbuf2, cd->name)) {
00153       return cd;
00154     }
00155   }
00156   return NULL;
00157 }
00158 
00208 static void
00209 lcdset_register_with_category(WCHMM_INFO *wchmm, HTK_HMM_INFO *hmminfo, DFA_INFO *dfa, HMM_Logical *hmm, WORD_ID category)
00210 {
00211   CD_Set *ret;
00212   WORD_ID c2, i, w;
00213   HMM_Logical *ltmp;
00214 
00215   int cnt_c, cnt_w, cnt_p;
00216 
00217   if (lcdset_lookup_with_category(wchmm, hmm, category) == NULL) {
00218     leftcenter_name(hmm->name, lccbuf);
00219     sprintf(lccbuf2, "%s::%04d", lccbuf, category);
00220     if (debug2_flag) {
00221       j_printf("category-aware lcdset {%s}...", lccbuf2);
00222     }
00223     cnt_c = cnt_w = cnt_p = 0;
00224     
00225     for(c2=0;c2<dfa->term_num;c2++) {
00226       if (! dfa_cp(dfa, category, c2)) continue;
00227       
00228 
00229       for(i=0;i<dfa->term.wnum[c2];i++) {
00230         w = dfa->term.tw[c2][i];
00231         ltmp = get_right_context_HMM(hmm, winfo->wseq[w][0]->name, hmminfo);
00232         if (ltmp == NULL) {
00233           ltmp = hmm;
00234           if (ltmp->is_pseudo) {
00235             error_missing_right_triphone(hmm, winfo->wseq[w][0]->name);
00236           }
00237         }
00238         if (! ltmp->is_pseudo) {
00239           if (regist_cdset(&(wchmm->lcdset_category_root), ltmp->body.defined, lccbuf2)) {
00240             cnt_p++;
00241           }
00242         }
00243       }
00244       cnt_c++;
00245       cnt_w += dfa->term.wnum[c2];
00246     }
00247     if (debug2_flag) {
00248       j_printf("%d categories (%d words) can follow, %d HMMs registered\n", cnt_c, cnt_w, cnt_p);
00249     }
00250   }
00251 }
00252 
00272 void
00273 lcdset_register_with_category_all(WCHMM_INFO *wchmm, HTK_HMM_INFO *hmminfo, WORD_INFO *winfo, DFA_INFO *dfa)
00274 {
00275   WORD_ID c1, w, w_prev;
00276   int i;
00277   HMM_Logical *ltmp;
00278   
00279   
00280   
00281   for(w=0;w<winfo->num;w++) {
00282     ltmp = winfo->wseq[w][winfo->wlen[w]-1];
00283     lcdset_register_with_category(wchmm, hmminfo, dfa, ltmp, winfo->wton[w]);
00284   }
00285   
00286   
00287   for(w=0;w<winfo->num;w++) {
00288     if (winfo->wlen[w] > 1) continue;
00289     for(c1=0;c1<dfa->term_num;c1++) {
00290       if (! dfa_cp(dfa, c1, winfo->wton[w])) continue;
00291       for(i=0;i<dfa->term.wnum[c1];i++) {
00292         w_prev = dfa->term.tw[c1][i];
00293         ltmp = get_left_context_HMM(winfo->wseq[w][0], winfo->wseq[w_prev][winfo->wlen[w_prev]-1]->name, hmminfo);
00294         if (ltmp == NULL) continue; 
00295         if (ltmp->is_pseudo) continue; 
00296         lcdset_register_with_category(wchmm, hmminfo, dfa, ltmp, winfo->wton[w]);
00297       }
00298     }
00299   }
00300 }
00301 
00317 void
00318 lcdset_remove_with_category_all(WCHMM_INFO *wchmm)
00319 {
00320   free_cdset(&(wchmm->lcdset_category_root));
00321 }
00322 
00323 #endif 
00324 
00325 #endif 
00326 
00353 LOGPROB
00354 outprob_style(WCHMM_INFO *wchmm, int node, int last_wid, int t, HTK_Param *param)
00355 {
00356 
00357 #ifndef PASS1_IWCD
00358   
00359   
00360 
00361   return(outprob_state(t, wchmm->state[node].out, param));
00362   
00363 #else  
00364 
00365   
00366   HMM_Logical *ohmm, *rhmm;
00367   RC_INFO *rset;
00368   LRC_INFO *lrset;
00369   CD_Set *lcd;
00370   WORD_INFO *winfo = wchmm->winfo;
00371   HTK_HMM_INFO *hmminfo = wchmm->hmminfo;
00372 
00373   
00374 
00375   switch(wchmm->outstyle[node]) {
00376   case AS_STATE:
00377     
00378     
00379     return(outprob_state(t, wchmm->state[node].out.state, param));
00380   case AS_LSET:
00381     
00382     
00383     return(outprob_cd(t, wchmm->state[node].out.lset, param));
00384   case AS_RSET:
00385     
00386     
00387     rset = wchmm->state[node].out.rset;
00388     
00389     if (rset->cache.state == NULL || rset->lastwid_cache != last_wid) {
00390       
00391       
00392       if (last_wid != WORD_INVALID) {
00393         
00394         if ((ohmm = get_left_context_HMM(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name, hmminfo)) != NULL) {
00395           rhmm = ohmm;
00396         } else {
00397           
00398           rhmm = rset->hmm;
00399           
00400 
00401 
00402           if (debug2_flag) {
00403             if (rhmm->is_pseudo) {
00404             error_missing_left_triphone(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name);
00405             }
00406           }
00407         }
00408       } else {
00409         
00410         rhmm = rset->hmm;
00411         
00412 
00413         if (debug2_flag) {
00414           if (rhmm->is_pseudo) {
00415             error_missing_left_triphone(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name);
00416           }
00417         }
00418       }
00419       
00420       
00421       if (rhmm->is_pseudo) {
00422         rset->last_is_lset  = TRUE;
00423         rset->cache.lset    = &(rhmm->body.pseudo->stateset[rset->state_loc]);
00424       } else {
00425         rset->last_is_lset  = FALSE;
00426         rset->cache.state   = rhmm->body.defined->s[rset->state_loc];
00427       }
00428       rset->lastwid_cache = last_wid;
00429     }
00430     
00431     if (rset->last_is_lset) {
00432       return(outprob_cd(t, rset->cache.lset, param));
00433     } else {
00434       return(outprob_state(t, rset->cache.state, param));
00435     }
00436   case AS_LRSET:
00437     
00438     lrset = wchmm->state[node].out.lrset;
00439     if (lrset->cache.state == NULL || lrset->lastwid_cache != last_wid) {
00440       
00441       rhmm = lrset->hmm;
00442       
00443       strcpy(rbuf, rhmm->name);
00444       if (last_wid != WORD_INVALID) {
00445         add_left_context(rbuf, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name);
00446       }
00447 #ifdef CATEGORY_TREE
00448       if (!old_iwcd_flag) {
00449         
00450         if (last_wid != WORD_INVALID &&
00451             (ohmm = get_left_context_HMM(rhmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name, hmminfo)) != NULL) {
00452           lcd = lcdset_lookup_with_category(wchmm, ohmm, lrset->category);
00453         } else {
00454           lcd = lcdset_lookup_with_category(wchmm, rhmm, lrset->category);
00455         }
00456       } else {
00457         lcd = lcdset_lookup_by_hmmname(hmminfo, rbuf);
00458       }
00459 #else
00460       lcd = lcdset_lookup_by_hmmname(hmminfo, rbuf);
00461 #endif 
00462       if (lcd != NULL) {        
00463         lrset->last_is_lset  = TRUE;
00464         lrset->cache.lset    = &(lcd->stateset[lrset->state_loc]);
00465         lrset->lastwid_cache = last_wid;
00466       } else {
00467         
00468         if (rhmm->is_pseudo) {
00469           lrset->last_is_lset  = TRUE;
00470           lrset->cache.lset    = &(rhmm->body.pseudo->stateset[lrset->state_loc]);
00471           lrset->lastwid_cache = last_wid;
00472         } else {
00473           lrset->last_is_lset  = FALSE;
00474           lrset->cache.state   = rhmm->body.defined->s[lrset->state_loc];
00475           lrset->lastwid_cache = last_wid;
00476         }
00477       }
00478       
00479     }
00480     
00481     if (lrset->last_is_lset) {
00482       return(outprob_cd(t, lrset->cache.lset, param));
00483     } else {
00484       return(outprob_state(t, lrset->cache.state, param));
00485     }
00486   default:
00487     
00488     j_error("InternalError: no outprob style??\n");
00489     return(LOG_ZERO);
00490   }
00491 
00492 #endif  
00493 
00494 }
00495 
00512 void
00513 error_missing_right_triphone(HMM_Logical *base, char *rc_name)
00514 {
00515   
00516   strcpy(rbuf, base->name);
00517   add_right_context(rbuf, rc_name);
00518   j_printerr("Warning: IW-triphone for word end \"%s\" not found, fallback to pseudo {%s}\n", rbuf, base->name);
00519 }
00520 
00537 void
00538 error_missing_left_triphone(HMM_Logical *base, char *lc_name)
00539 {
00540   
00541   strcpy(rbuf, base->name);
00542   add_left_context(rbuf, lc_name);
00543   j_printerr("Warning: IW-triphone for word head \"%s\" not found, fallback to pseudo {%s}\n", rbuf, base->name);
00544 }