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
00314 static void
00315 callback_free_lcdset_content(void *arg)
00316 {
00317 CD_Set *d;
00318 int j;
00319
00320 d = arg;
00321 for(j=1;j<d->state_num-1;j++) {
00322 free(d->stateset[j].s);
00323 }
00324 free(d->stateset);
00325 }
00326
00342 void
00343 lcdset_remove_with_category_all(WCHMM_INFO *wchmm)
00344 {
00345 if (wchmm->lcdset_category_root != NULL) {
00346 aptree_traverse_and_do(wchmm->lcdset_category_root, callback_free_lcdset_content);
00347 free_aptree(wchmm->lcdset_category_root);
00348 wchmm->lcdset_category_root = NULL;
00349 }
00350 }
00351
00352 #endif
00353
00354 #endif
00355
00382 LOGPROB
00383 outprob_style(WCHMM_INFO *wchmm, int node, int last_wid, int t, HTK_Param *param)
00384 {
00385
00386 #ifndef PASS1_IWCD
00387
00388
00389
00390 return(outprob_state(t, wchmm->state[node].out, param));
00391
00392 #else
00393
00394
00395 HMM_Logical *ohmm, *rhmm;
00396 RC_INFO *rset;
00397 LRC_INFO *lrset;
00398 CD_Set *lcd;
00399 WORD_INFO *winfo = wchmm->winfo;
00400 HTK_HMM_INFO *hmminfo = wchmm->hmminfo;
00401
00402
00403
00404 switch(wchmm->outstyle[node]) {
00405 case AS_STATE:
00406
00407
00408 return(outprob_state(t, wchmm->state[node].out.state, param));
00409 case AS_LSET:
00410
00411
00412 return(outprob_cd(t, wchmm->state[node].out.lset, param));
00413 case AS_RSET:
00414
00415
00416 rset = wchmm->state[node].out.rset;
00417
00418 if (rset->lastwid_cache != last_wid || rset->cache.state == NULL) {
00419
00420
00421 if (last_wid != WORD_INVALID) {
00422
00423 if ((ohmm = get_left_context_HMM(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name, hmminfo)) != NULL) {
00424 rhmm = ohmm;
00425 } else {
00426
00427 rhmm = rset->hmm;
00428
00429
00430
00431 if (debug2_flag) {
00432 if (rhmm->is_pseudo) {
00433 error_missing_left_triphone(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name);
00434 }
00435 }
00436 }
00437 } else {
00438
00439 rhmm = rset->hmm;
00440
00441
00442 if (debug2_flag) {
00443 if (rhmm->is_pseudo) {
00444 error_missing_left_triphone(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name);
00445 }
00446 }
00447 }
00448
00449
00450 if (rhmm->is_pseudo) {
00451 rset->last_is_lset = TRUE;
00452 rset->cache.lset = &(rhmm->body.pseudo->stateset[rset->state_loc]);
00453 } else {
00454 rset->last_is_lset = FALSE;
00455 rset->cache.state = rhmm->body.defined->s[rset->state_loc];
00456 }
00457 rset->lastwid_cache = last_wid;
00458 }
00459
00460 if (rset->last_is_lset) {
00461 return(outprob_cd(t, rset->cache.lset, param));
00462 } else {
00463 return(outprob_state(t, rset->cache.state, param));
00464 }
00465 case AS_LRSET:
00466
00467 lrset = wchmm->state[node].out.lrset;
00468 if (lrset->lastwid_cache != last_wid || lrset->cache.state == NULL) {
00469
00470 rhmm = lrset->hmm;
00471
00472 strcpy(rbuf, rhmm->name);
00473 if (last_wid != WORD_INVALID) {
00474 add_left_context(rbuf, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name);
00475 }
00476 #ifdef CATEGORY_TREE
00477 if (!old_iwcd_flag) {
00478
00479 if (last_wid != WORD_INVALID &&
00480 (ohmm = get_left_context_HMM(rhmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name, hmminfo)) != NULL) {
00481 lcd = lcdset_lookup_with_category(wchmm, ohmm, lrset->category);
00482 } else {
00483 lcd = lcdset_lookup_with_category(wchmm, rhmm, lrset->category);
00484 }
00485 } else {
00486 lcd = lcdset_lookup_by_hmmname(hmminfo, rbuf);
00487 }
00488 #else
00489 lcd = lcdset_lookup_by_hmmname(hmminfo, rbuf);
00490 #endif
00491 if (lcd != NULL) {
00492 lrset->last_is_lset = TRUE;
00493 lrset->cache.lset = &(lcd->stateset[lrset->state_loc]);
00494 lrset->lastwid_cache = last_wid;
00495 } else {
00496
00497 if (rhmm->is_pseudo) {
00498 lrset->last_is_lset = TRUE;
00499 lrset->cache.lset = &(rhmm->body.pseudo->stateset[lrset->state_loc]);
00500 lrset->lastwid_cache = last_wid;
00501 } else {
00502 lrset->last_is_lset = FALSE;
00503 lrset->cache.state = rhmm->body.defined->s[lrset->state_loc];
00504 lrset->lastwid_cache = last_wid;
00505 }
00506 }
00507
00508 }
00509
00510 if (lrset->last_is_lset) {
00511 return(outprob_cd(t, lrset->cache.lset, param));
00512 } else {
00513 return(outprob_state(t, lrset->cache.state, param));
00514 }
00515 default:
00516
00517 j_error("InternalError: no outprob style??\n");
00518 return(LOG_ZERO);
00519 }
00520
00521 #endif
00522
00523 }
00524
00541 void
00542 error_missing_right_triphone(HMM_Logical *base, char *rc_name)
00543 {
00544
00545 strcpy(rbuf, base->name);
00546 add_right_context(rbuf, rc_name);
00547 j_printerr("Warning: IW-triphone for word end \"%s\" not found, fallback to pseudo {%s}\n", rbuf, base->name);
00548 }
00549
00566 void
00567 error_missing_left_triphone(HMM_Logical *base, char *lc_name)
00568 {
00569
00570 strcpy(rbuf, base->name);
00571 add_left_context(rbuf, lc_name);
00572 j_printerr("Warning: IW-triphone for word head \"%s\" not found, fallback to pseudo {%s}\n", rbuf, base->name);
00573 }