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 }