00001
00052
00053
00054
00055
00056
00057
00058
00059 #include <julius.h>
00060
00061 #undef DEBUG
00062
00063 static boolean idc_on;
00064 static int progout_interval_frame;
00065
00066
00067
00068
00069
00070
00071
00072 #ifdef WORD_GRAPH
00073
00074
00075 static int glevel;
00076 static int gnodes;
00077 static int garcs;
00078
00107 static void
00108 generate_lattice(int frame, BACKTRELLIS *bt, WORD_INFO *winfo)
00109 {
00110 TRELLIS_ATOM *ta;
00111 int i, j;
00112 boolean new_node = FALSE;
00113 LOGPROB l;
00114
00115 glevel++;
00116
00117 if (frame >= 0) {
00118 for (i=0;i<bt->num[frame];i++) {
00119 ta = bt->rw[frame][i];
00120
00121
00122 if (! ta->within_context) continue;
00123 if (ta->within_wordgraph) continue;
00124
00125 ta->within_wordgraph = TRUE;
00126 new_node = TRUE;
00127 if (debug2_flag) {
00128 for(j=0;j<glevel;j++) j_printf(" ");
00129 j_printf("%s: [%d..%d]\n", winfo->wname[ta->wid], ta->begintime, ta->endtime);
00130 }
00131 if (verbose_flag) {
00132 j_printf("%d: [%d..%d] wid=%d name=\"%s\" lname=\"%s\" score=%f", garcs, ta->begintime, ta->endtime, ta->wid, winfo->woutput[ta->wid], winfo->wname[ta->wid], ta->backscore);
00133 }
00134 #ifdef USE_NGRAM
00135 j_printf(" lscore=%f", ta->lscore);
00136 #endif
00137 l = ta->backscore;
00138 if (ta->last_tre->wid != WORD_INVALID) {
00139 l -= ta->last_tre->backscore;
00140 }
00141 #ifdef USE_NGRAM
00142 l -= ta->lscore;
00143 #endif
00144 j_printf(" AMavg=%f\n", l / (ta->endtime - ta->begintime + 1));
00145
00146 garcs++;
00147
00148 generate_lattice(ta->last_tre->endtime, bt, winfo);
00149 }
00150 }
00151 if (new_node) {
00152 gnodes++;
00153 }
00154 glevel--;
00155 }
00156 #endif
00157
00172 static void
00173 put_atom(TRELLIS_ATOM *atom, WORD_INFO *winfo)
00174 {
00175 int i;
00176 j_printf("%3d,%3d %f %16s (id=%5d)", atom->begintime, atom->endtime,
00177 atom->backscore, winfo->wname[atom->wid], atom->wid);
00178 for (i=0;i<winfo->wlen[atom->wid]; i++) {
00179 j_printf(" %s",winfo->wseq[atom->wid][i]->name);
00180 }
00181 j_printf("\n");
00182 }
00183
00216 static LOGPROB
00217 trace_backptr(WORD_ID wordseq_rt[MAXSEQNUM], int *rt_wordlen, TRELLIS_ATOM *atom, BACKTRELLIS *backtrellis, WORD_INFO *winfo)
00218 {
00219 int wordlen = 0;
00220 TRELLIS_ATOM *tretmp;
00221 LOGPROB langscore = 0.0;
00222 static WORD_ID wordseq[MAXSEQNUM];
00223 int i;
00224
00225
00226 wordseq[0] = atom->wid;
00227 wordlen = 1;
00228 tretmp = atom;
00229 #ifdef USE_NGRAM
00230 langscore += tretmp->lscore;
00231 #endif
00232 if (debug2_flag) {
00233 put_atom(tretmp, winfo);
00234 }
00235
00236
00237 while (tretmp->begintime > 0) {
00238 tretmp = tretmp->last_tre;
00239
00240
00241 if (tretmp == NULL) {
00242 j_error("ERROR: BackTrellis Pass missing??\n");
00243 }
00244 #ifdef USE_NGRAM
00245 langscore += tretmp->lscore;
00246 #endif
00247 wordseq[wordlen] = tretmp->wid;
00248 wordlen++;
00249 if (debug2_flag) {
00250 put_atom(tretmp, winfo);
00251 }
00252 if (wordlen >= MAXSEQNUM) {
00253 j_error("sentence length exceeded ( > %d)\n",MAXSEQNUM);
00254 }
00255 }
00256 *rt_wordlen = wordlen;
00257
00258 for(i=0;i<wordlen;i++) wordseq_rt[i] = wordseq[wordlen-i-1];
00259 return(langscore);
00260 }
00261
00311 static LOGPROB
00312 print_1pass_result(BACKTRELLIS *backtrellis, int framelen, WORD_INFO *winfo)
00313 {
00314 WORD_ID wordseq[MAXSEQNUM];
00315 int wordlen;
00316 int i;
00317 TRELLIS_ATOM *best;
00318 int last_time;
00319 LOGPROB total_lscore;
00320 LOGPROB maxscore;
00321 TRELLIS_ATOM *tmp;
00322
00323
00324 for (last_time = framelen - 1; last_time >= 0; last_time--) {
00325 #ifdef USE_NGRAM
00326 #ifdef SP_BREAK_CURRENT_FRAME
00327
00328
00329 maxscore = LOG_ZERO;
00330 for (i=0;i<backtrellis->num[last_time];i++) {
00331 tmp = backtrellis->rw[last_time][i];
00332 #ifdef WORD_GRAPH
00333
00334 if (!tmp->within_context) continue;
00335 #endif
00336 if (maxscore < tmp->backscore) {
00337 maxscore = tmp->backscore;
00338 best = tmp;
00339 }
00340 }
00341 if (maxscore != LOG_ZERO) break;
00342 #else
00343
00344
00345 maxscore = LOG_ZERO;
00346 for (i=0;i<backtrellis->num[last_time];i++) {
00347 tmp = backtrellis->rw[last_time][i];
00348 #ifdef WORD_GRAPH
00349
00350 if (!tmp->within_context) continue;
00351 #endif
00352 if (tmp->wid == winfo->tail_silwid && maxscore < tmp->backscore) {
00353 maxscore = tmp->backscore;
00354 best = tmp;
00355 break;
00356 }
00357 }
00358 if (maxscore != LOG_ZERO) break;
00359 #endif
00360 #else
00361
00362
00363 maxscore = LOG_ZERO;
00364 for (i=0;i<backtrellis->num[last_time];i++) {
00365 tmp = backtrellis->rw[last_time][i];
00366 #ifdef WORD_GRAPH
00367
00368 if (!tmp->within_context) continue;
00369 #endif
00370
00371 if (maxscore < tmp->backscore) {
00372 maxscore = tmp->backscore;
00373 best = tmp;
00374 }
00375
00376 }
00377 if (maxscore != LOG_ZERO) break;
00378 #endif
00379 }
00380 if (last_time < 0) {
00381 j_printerr("[no sentence-end word survived on last beam]\n");
00382
00383 result_pass1_final(NULL, 0, LOG_ZERO, LOG_ZERO, winfo);
00384 return(LOG_ZERO);
00385 }
00386
00387
00388 total_lscore = trace_backptr(wordseq, &wordlen, best, backtrellis, winfo);
00389
00390 if (progout_flag) {
00391 result_pass1_current(last_time, wordseq, wordlen, best->backscore, total_lscore, winfo);
00392 }
00393
00394
00395 if (verbose_flag || !progout_flag) {
00396 result_pass1_final(wordseq, wordlen, best->backscore, total_lscore, winfo);
00397 }
00398 result_pass1_end();
00399
00400
00401 for(i=0;i<wordlen;i++) pass1_wseq[i] = wordseq[i];
00402 pass1_wnum = wordlen;
00403 pass1_score = best->backscore;
00404
00405 #ifdef WORD_GRAPH
00406
00407
00408
00409
00410
00411 glevel = 0;
00412 gnodes = 0;
00413 garcs = 0;
00414 j_printf("--- begin wordgraph data pass1 ---\n");
00415 generate_lattice(last_time, backtrellis, winfo);
00416 if (verbose_flag) j_printf("word graph generated (nodes=%d,arcs=%d)\n",gnodes, garcs);
00417 j_printf("--- end wordgraph data pass1 ---\n");
00418 #endif
00419
00420
00421 return(best->backscore);
00422 }
00423
00441 static void
00442 bt_current_max(BACKTRELLIS *bt, int t, WORD_INFO *winfo)
00443 {
00444 static WORD_ID wordseq[MAXSEQNUM];
00445 int wordlen;
00446 TRELLIS_ATOM *tre;
00447 TRELLIS_ATOM *tremax;
00448 LOGPROB maxscore;
00449 LOGPROB lscore;
00450
00451
00452 maxscore = LOG_ZERO;
00453 tremax = NULL;
00454 tre = bt->list;
00455 while (tre != NULL && tre->endtime == t) {
00456 if (maxscore < tre->backscore) {
00457 maxscore = tre->backscore;
00458 tremax = tre;
00459 }
00460 tre = tre->next;
00461 }
00462
00463 if (maxscore != LOG_ZERO) {
00464 lscore = trace_backptr(wordseq, &wordlen, tremax, bt, winfo);
00465 result_pass1_current(t, wordseq, wordlen, tremax->backscore, lscore, winfo);
00466 } else {
00467 wordlen = 0;
00468 result_pass1_current(t, wordseq, wordlen, LOG_ZERO, LOG_ZERO, winfo);
00469 }
00470 }
00471
00489 static void
00490 bt_current_max_word(BACKTRELLIS *bt, int t, WORD_INFO *winfo)
00491 {
00492 TRELLIS_ATOM *tre;
00493 TRELLIS_ATOM *tremax;
00494 LOGPROB maxscore;
00495 WORD_ID w;
00496
00497
00498
00499 maxscore = LOG_ZERO;
00500 tremax = NULL;
00501 tre = bt->list;
00502 while (tre != NULL && tre->endtime == t) {
00503 if (maxscore < tre->backscore) {
00504 maxscore = tre->backscore;
00505 tremax = tre;
00506 }
00507 tre = tre->next;
00508 }
00509
00510 if (maxscore != LOG_ZERO) {
00511 j_printf("%3d: ",t);
00512 w = tremax->wid;
00513 j_printf("\"%s [%s]\"(id=%d)",
00514 winfo->wname[w], winfo->woutput[w], w);
00515 j_printf(" [%d-%d] %f <- ", tremax->begintime, t, tremax->backscore);
00516 w = tremax->last_tre->wid;
00517 if (w != WORD_INVALID) {
00518 j_printf("\"%s [%s]\"(id=%d)\n",
00519 winfo->wname[w], winfo->woutput[w], w);
00520 } else {
00521 j_printf("bgn\n");
00522 }
00523 }
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 static TOKEN2 *tlist[2];
00546 static TOKENID *tindex[2];
00547 static int maxtnum = 0;
00548 static int expand_step = 0;
00549 static int tnum[2];
00550 static int n_start;
00551 static int n_end;
00552 static int tl;
00553 static int tn;
00554
00555
00556 static TOKENID *token;
00557 static int totalnodenum;
00558
00559
00560 static TRELLIS_ATOM bos;
00561 static boolean nodes_malloced = FALSE;
00562
00581 static void
00582 malloc_nodes(int n, int ntoken_init, int ntoken_step)
00583 {
00584 totalnodenum = n;
00585 token = mymalloc(sizeof(TOKENID)*totalnodenum);
00586 if (maxtnum < ntoken_init) maxtnum = ntoken_init;
00587 tlist[0] = mymalloc(sizeof(TOKEN2)*maxtnum);
00588 tlist[1] = mymalloc(sizeof(TOKEN2)*maxtnum);
00589 tindex[0] = mymalloc(sizeof(TOKENID)*maxtnum);
00590 tindex[1] = mymalloc(sizeof(TOKENID)*maxtnum);
00591 tnum[0] = tnum[1] = 0;
00592 if (expand_step < ntoken_step) expand_step = ntoken_step;
00593 nodes_malloced = TRUE;
00594 }
00595
00604 static void
00605 expand_tlist()
00606 {
00607 maxtnum += expand_step;
00608 tlist[0] = myrealloc(tlist[0],sizeof(TOKEN2)*maxtnum);
00609 tlist[1] = myrealloc(tlist[1],sizeof(TOKEN2)*maxtnum);
00610 tindex[0] = myrealloc(tindex[0],sizeof(TOKENID)*maxtnum);
00611 tindex[1] = myrealloc(tindex[1],sizeof(TOKENID)*maxtnum);
00612
00613 }
00614
00623 static void
00624 free_nodes()
00625 {
00626 if (nodes_malloced) {
00627 free(token);
00628 free(tlist[0]);
00629 free(tlist[1]);
00630 free(tindex[0]);
00631 free(tindex[1]);
00632 nodes_malloced = FALSE;
00633 }
00634 }
00635
00648 static void
00649 clear_tlist(int tt)
00650 {
00651 tnum[tt] = 0;
00652 }
00653
00666 static void
00667 clear_tokens(int tt)
00668 {
00669 int j;
00670
00671 for (j=0; j<tnum[tt]; j++) {
00672 token[tlist[tt][j].node] = TOKENID_UNDEFINED;
00673 }
00674 }
00675
00688 static TOKENID
00689 create_token()
00690 {
00691 TOKENID newid;
00692 newid = tnum[tn];
00693 tnum[tn]++;
00694 if (tnum[tn]>=maxtnum) expand_tlist();
00695 tindex[tn][newid] = newid;
00696 #ifdef WPAIR
00697
00698 tlist[tn][newid].next = TOKENID_UNDEFINED;
00699 #endif
00700 return(newid);
00701 }
00702
00730 static void
00731 node_assign_token(int node, TOKENID tkid)
00732 {
00733 #ifdef WPAIR
00734
00735 tlist[tn][tkid].next = token[node];
00736 #endif
00737 token[node] = tkid;
00738 tlist[tn][tkid].node = node;
00739 }
00740
00775 static TOKENID
00776 node_exist_token(int tt, int node, WORD_ID wid)
00777 {
00778 #ifdef WPAIR
00779
00780
00781 #ifdef WPAIR_KEEP_NLIMIT
00782
00783
00784
00785 int i = 0;
00786 TOKENID lowest_token = TOKENID_UNDEFINED;
00787 #endif
00788 TOKENID tmp;
00789 for(tmp=token[node]; tmp != TOKENID_UNDEFINED; tmp=tlist[tt][tmp].next) {
00790 if (tlist[tt][tmp].last_tre->wid == wid) {
00791 return(tmp);
00792 }
00793 #ifdef WPAIR_KEEP_NLIMIT
00794 if (lowest_token == TOKENID_UNDEFINED ||
00795 tlist[tt][lowest_token].score < tlist[tt][tmp].score)
00796 lowest_token = tmp;
00797 if (++i >= wpair_keep_nlimit) break;
00798 #endif
00799 }
00800 #ifdef WPAIR_KEEP_NLIMIT
00801 if (i >= wpair_keep_nlimit) {
00802 return(lowest_token);
00803 } else {
00804 return(TOKENID_UNDEFINED);
00805 }
00806 #else
00807 return(TOKENID_UNDEFINED);
00808 #endif
00809
00810 #else
00811
00812
00813
00814 return(token[node]);
00815 #endif
00816 }
00817
00818 #ifdef DEBUG
00819
00820
00821
00822
00823
00824 static void
00825 node_check_token(int tt)
00826 {
00827 int i;
00828 for(i=0;i<tnum[tt];i++) {
00829 if (node_exist_token(tt, tlist[tt][i].node, tlist[tt][i].last_tre->wid) != i) {
00830 j_printerr("token %d not found on node %d\n", i, tlist[tt][i].node);
00831 }
00832 }
00833 }
00834 #endif
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 #define SD(A) tindex[tn][A-1]
00848 #define SCOPY(D,S) D = S
00849 #define SVAL(A) (tlist[tn][tindex[tn][A-1]].score)
00850 #define STVAL (tlist[tn][s].score)
00851
00852
00874 static void
00875 sort_token_upward(int neednum, int totalnum)
00876 {
00877 int n,root,child,parent;
00878 TOKENID s;
00879 for (root = totalnum/2; root >= 1; root--) {
00880 SCOPY(s, SD(root));
00881 parent = root;
00882 while ((child = parent * 2) <= totalnum) {
00883 if (child < totalnum && SVAL(child) < SVAL(child+1)) {
00884 child++;
00885 }
00886 if (STVAL >= SVAL(child)) {
00887 break;
00888 }
00889 SCOPY(SD(parent), SD(child));
00890 parent = child;
00891 }
00892 SCOPY(SD(parent), s);
00893 }
00894 n = totalnum;
00895 while ( n > totalnum - neednum) {
00896 SCOPY(s, SD(n));
00897 SCOPY(SD(n), SD(1));
00898 n--;
00899 parent = 1;
00900 while ((child = parent * 2) <= n) {
00901 if (child < n && SVAL(child) < SVAL(child+1)) {
00902 child++;
00903 }
00904 if (STVAL >= SVAL(child)) {
00905 break;
00906 }
00907 SCOPY(SD(parent), SD(child));
00908 parent = child;
00909 }
00910 SCOPY(SD(parent), s);
00911 }
00912 }
00913
00938 static void
00939 sort_token_downward(int neednum, int totalnum)
00940 {
00941 int n,root,child,parent;
00942 TOKENID s;
00943 for (root = totalnum/2; root >= 1; root--) {
00944 SCOPY(s, SD(root));
00945 parent = root;
00946 while ((child = parent * 2) <= totalnum) {
00947 if (child < totalnum && SVAL(child) > SVAL(child+1)) {
00948 child++;
00949 }
00950 if (STVAL <= SVAL(child)) {
00951 break;
00952 }
00953 SCOPY(SD(parent), SD(child));
00954 parent = child;
00955 }
00956 SCOPY(SD(parent), s);
00957 }
00958 n = totalnum;
00959 while ( n > totalnum - neednum) {
00960 SCOPY(s, SD(n));
00961 SCOPY(SD(n), SD(1));
00962 n--;
00963 parent = 1;
00964 while ((child = parent * 2) <= n) {
00965 if (child < n && SVAL(child) > SVAL(child+1)) {
00966 child++;
00967 }
00968 if (STVAL <= SVAL(child)) {
00969 break;
00970 }
00971 SCOPY(SD(parent), SD(child));
00972 parent = child;
00973 }
00974 SCOPY(SD(parent), s);
00975 }
00976 }
00977
01008 static void
01009 sort_token_no_order(int neednum, int *start, int *end)
01010 {
01011 int totalnum = tnum[tn];
01012 int restnum;
01013
01014 restnum = totalnum - neednum;
01015
01016 if (neednum >= totalnum) {
01017
01018 *start = 0;
01019 *end = totalnum - 1;
01020 } else if (neednum < restnum) {
01021
01022 sort_token_upward(neednum,totalnum);
01023 *start = totalnum - neednum;
01024 *end = totalnum - 1;
01025 } else {
01026
01027 sort_token_downward(restnum,totalnum);
01028 *start = 0;
01029 *end = neednum - 1;
01030 }
01031 }
01032
01033
01034 #ifdef SP_BREAK_CURRENT_FRAME
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 static boolean in_sparea;
01056 static int sparea_start;
01057 static int tmp_sparea_start;
01058 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01059 static WORD_ID tmp_sp_break_last_word;
01060 #else
01061 static WORD_ID last_tre_word;
01062 #endif
01063 static boolean first_sparea;
01064 static int sp_duration;
01065
01092 boolean
01093 is_sil(WORD_ID w, WORD_INFO *winfo, HTK_HMM_INFO *hmm)
01094 {
01095
01096 if (winfo->wlen[w] > 1) return FALSE;
01097
01098
01099 if (winfo->wseq[w][0] == hmm->sp) return TRUE;
01100
01101
01102 if (w == winfo->head_silwid || w == winfo->tail_silwid) return TRUE;
01103
01104
01105 return FALSE;
01106 }
01107
01131 static boolean
01132 detect_end_of_segment(BACKTRELLIS *backtrellis, int time, WCHMM_INFO *wchmm)
01133 {
01134 TRELLIS_ATOM *tre;
01135 LOGPROB maxscore = LOG_ZERO;
01136 TRELLIS_ATOM *tremax = NULL;
01137 int count = 0;
01138 boolean detected = FALSE;
01139
01140
01141 for(tre = backtrellis->list; tre != NULL && tre->endtime == time; tre = tre->next) {
01142 if (maxscore < tre->backscore) {
01143 maxscore = tre->backscore;
01144 tremax = tre;
01145 }
01146 count++;
01147 }
01148 if (tremax == NULL) {
01149 detected = TRUE;
01150 } else if (count > 0) {
01151 if (is_sil(tremax->wid, wchmm->winfo, wchmm->hmminfo)) {
01152 detected = TRUE;
01153 }
01154 }
01155
01156
01157
01158 if (in_sparea && detected) {
01159 sp_duration++;
01160 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01161
01162
01163
01164
01165 if (tmp_sp_break_last_word == WORD_INVALID) {
01166 if (tremax != NULL) tmp_sp_break_last_word = tremax->wid;
01167 }
01168 #else
01169
01170
01171 if (tremax != NULL) last_tre_word = tremax->wid;
01172 #endif
01173 }
01174
01175
01176
01177 else if (!in_sparea && detected) {
01178
01179
01180 tmp_sparea_start = time;
01181 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01182
01183
01184 tmp_sp_break_last_word = tremax ? tremax->wid : WORD_INVALID;
01185 #endif
01186 in_sparea = TRUE;
01187 sp_duration = 1;
01188 #ifdef SP_BREAK_DEBUG
01189 printf("sp start %d\n", time);
01190 #endif
01191 }
01192
01193
01194
01195 else if (in_sparea && !detected) {
01196
01197 in_sparea = FALSE;
01198 #ifdef SP_BREAK_DEBUG
01199 printf("sp end %d\n", time);
01200 #endif
01201
01202
01203 if (sp_duration < sp_frame_duration) {
01204
01205
01206 #ifdef SP_BREAK_DEBUG
01207 printf("too short (%d<%d), ignored\n", sp_duration, sp_frame_duration);
01208 #endif
01209 } else if (first_sparea) {
01210
01211
01212 first_sparea = FALSE;
01213 #ifdef SP_BREAK_DEBUG
01214 printf("first silence, ignored\n");
01215 #endif
01216 } else {
01217
01218
01219 #ifdef SP_BREAK_DEBUG
01220 printf(">> segment [%d..%d]\n", sparea_start, time-1);
01221 #else
01222 if (idc_on) j_printerr("|");
01223 #endif
01224
01225 sparea_start = tmp_sparea_start;
01226 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01227
01228 sp_break_last_word = tmp_sp_break_last_word;
01229 #else
01230
01231 sp_break_last_word = last_tre_word;
01232 #endif
01233
01234
01235 return(TRUE);
01236 }
01237 }
01238
01239 #ifdef SP_BREAK_EVAL
01240 printf("[%d %d %d]\n", time, count, (detected) ? 50 : 0);
01241 #endif
01242 return (FALSE);
01243 }
01244
01245 #endif
01246
01247
01248
01249
01250
01251
01252
01253
01272 static void
01273 init_nodescore(HTK_Param *param, WCHMM_INFO *wchmm)
01274 {
01275 TOKENID newid;
01276 TOKEN2 *new;
01277 #ifdef USE_NGRAM
01278 WORD_ID beginword;
01279 #endif
01280 int node;
01281 #ifdef USE_DFA
01282 int i;
01283 #endif
01284
01285
01286
01287 #ifdef SP_BREAK_CURRENT_FRAME
01288
01289 if (sp_break_last_nword == wchmm->winfo->tail_silwid) {
01290
01291 bos.wid = WORD_INVALID;
01292 } else {
01293 bos.wid = sp_break_last_nword;
01294 }
01295 #else
01296 bos.wid = WORD_INVALID;
01297 #endif
01298 bos.begintime = bos.endtime = -1;
01299
01300
01301
01302 for(node=0;node<totalnodenum;node++) {
01303 token[node] = TOKENID_UNDEFINED;
01304 }
01305 tnum[0] = tnum[1] = 0;
01306
01307 #ifdef PASS1_IWCD
01308
01309
01310 outprob_style_cache_init(wchmm);
01311 #endif
01312
01313
01314
01315 #ifdef USE_NGRAM
01316
01317 #ifdef SP_BREAK_CURRENT_FRAME
01318 if (sp_break_last_word != WORD_INVALID) {
01319
01320
01321
01322
01323
01324 if (sp_break_last_word == wchmm->winfo->tail_silwid) {
01325 beginword = wchmm->winfo->head_silwid;
01326 bos.wid = WORD_INVALID;
01327 } else {
01328 beginword = sp_break_last_word;
01329 }
01330 } else {
01331
01332 beginword = wchmm->winfo->head_silwid;
01333 }
01334 #else
01335
01336 beginword = wchmm->winfo->head_silwid;
01337 #endif
01338 #ifdef SP_BREAK_DEBUG
01339 printf("startword=[%s], last_nword=[%s]\n",
01340 (beginword == WORD_INVALID) ? "WORD_INVALID" : wchmm->winfo->wname[beginword],
01341 (bos.wid == WORD_INVALID) ? "WORD_INVALID" : wchmm->winfo->wname[bos.wid]);
01342 #endif
01343
01344 newid = create_token();
01345 new = &(tlist[tn][newid]);
01346
01347 #ifdef MULTIPATH_VERSION
01348 node = wchmm->wordbegin[beginword];
01349 #else
01350 node = wchmm->offset[beginword][0];
01351 #endif
01352
01353 if (wchmm->state[node].scid != 0) {
01354
01355 new->last_lscore = max_successor_prob(wchmm, bos.wid, node);
01356 } else {
01357
01358 new->last_lscore = 0.0;
01359 }
01360 #ifdef FIX_PENALTY
01361 new->last_lscore = new->last_lscore * lm_weight;
01362 #else
01363 new->last_lscore = new->last_lscore * lm_weight + lm_penalty;
01364 #endif
01365
01366 new->last_tre = &bos;
01367 new->last_cword = bos.wid;
01368 #ifdef MULTIPATH_VERSION
01369
01370 new->score = new->last_lscore;
01371 #else
01372
01373 new->score = outprob_style(wchmm, node, bos.wid, 0, param) + new->last_lscore;
01374 #endif
01375
01376 node_assign_token(node, newid);
01377
01378 #else
01379
01380
01381
01382
01383
01384 {
01385 MULTIGRAM *m;
01386 int t,tb,te;
01387 WORD_ID iw;
01388 boolean flag;
01389
01390 flag = FALSE;
01391
01392 for(m = gramlist; m; m = m->next) {
01393 if (m->active) {
01394 tb = m->cate_begin;
01395 te = tb + m->dfa->term_num;
01396 for(t=tb;t<te;t++) {
01397
01398 if (dfa_cp_begin(dfa, t) == TRUE) {
01399
01400 flag = TRUE;
01401 for (iw=0;iw<dfa->term.wnum[t];iw++) {
01402
01403 i = dfa->term.tw[t][iw];
01404 #ifdef MULTIPATH_VERSION
01405 node = wchmm->wordbegin[i];
01406 #else
01407 node = wchmm->offset[i][0];
01408 #endif
01409
01410 if (node_exist_token(tn, node, bos.wid) != TOKENID_UNDEFINED) continue;
01411 newid = create_token();
01412 new = &(tlist[tn][newid]);
01413 new->last_tre = &bos;
01414 #ifdef MULTIPATH_VERSION
01415 new->score = 0.0;
01416 #else
01417 new->score = outprob_style(wchmm, node, bos.wid, 0, param);
01418 #endif
01419 node_assign_token(node, newid);
01420 }
01421 }
01422 }
01423 }
01424 }
01425 if (!flag) {
01426 j_printerr("Error: no initial state found in active DFA grammar!\n");
01427 }
01428 }
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443 #endif
01444 }
01445
01446
01447
01448
01449
01450
01476 void
01477 get_back_trellis_init(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis)
01478 {
01479
01480
01481
01482
01483
01484 tn = 0;
01485 tl = 1;
01486
01487
01488
01489 bt_prepare(backtrellis);
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500 malloc_nodes(wchmm->n, trellis_beam_width * 2 + wchmm->startnum, trellis_beam_width);
01501
01502
01503
01504 init_nodescore(param, wchmm);
01505 sort_token_no_order(trellis_beam_width, &n_start, &n_end);
01506
01507
01508
01509 result_pass1_begin();
01510
01511
01512 progout_interval_frame = (int)((float)progout_interval / ((float)param->header.wshift / 10000.0));
01513
01514
01515
01516 if (!realtime_flag && verbose_flag && (!progout_flag) && isatty(1)) {
01517 idc_on = TRUE;
01518 } else {
01519 idc_on = FALSE;
01520 }
01521
01522 #ifdef SP_BREAK_CURRENT_FRAME
01523
01524
01525 in_sparea = TRUE;
01526 sparea_start = tmp_sparea_start = 0;
01527 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01528 tmp_sp_break_last_word = WORD_INVALID;
01529 #endif
01530 sp_break_last_word = WORD_INVALID;
01531
01532
01533
01534 first_sparea = TRUE;
01535 sp_break_2_begin_word = WORD_INVALID;
01536 #endif
01537
01538 if (gmm != NULL) {
01539
01540 gmm_prepare(gmm);
01541 }
01542 }
01543
01544
01545 static TRELLIS_ATOM *tre;
01546 static int node;
01547 static int stid;
01548 static A_CELL *ac;
01549 static int next_node2;
01550 #ifdef USE_NGRAM
01551 static LOGPROB tmpprob;
01552 static LOGPROB *iwparray;
01553 #endif
01554 #ifdef UNIGRAM_FACTORING
01555
01556 static LOGPROB wordend_best_score;
01557 static int wordend_best_node;
01558 static TRELLIS_ATOM *wordend_best_tre;
01559 static WORD_ID wordend_best_last_cword;
01560 static int isoid;
01561 #endif
01562
01563
01564
01565
01566
01567
01607 boolean
01608 get_back_trellis_proceed(int t, HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis
01609 #ifdef MULTIPATH_VERSION
01610 , boolean final
01611 #endif
01612 )
01613 {
01614 LOGPROB tmpsum;
01615 int j, next_node, sword;
01616 TOKEN2 *tk, *tknext;
01617 TOKENID tknextid;
01618 #ifdef USE_NGRAM
01619 LOGPROB ngram_score_cache;
01620 #endif
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631 tl = tn;
01632 if (tn == 0) tn = 1; else tn = 0;
01633
01634
01635
01636 if (idc_on) {
01637 #ifdef SP_BREAK_CURRENT_FRAME
01638 if (in_sparea) j_printerr("."); else j_printerr("-");
01639 #else
01640 j_printerr(".");
01641 #endif
01642 }
01643
01644 #ifdef UNIGRAM_FACTORING
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662 wordend_best_score = LOG_ZERO;
01663 #endif
01664
01665 #ifdef DEBUG
01666
01667
01668 #endif
01669
01670
01671
01672 clear_tokens(tl);
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682 for (j=n_start;j<=n_end;j++) {
01683
01684
01685
01686 tk = &(tlist[tl][tindex[tl][j]]);
01687 node = tk->node;
01688 if (tk->score <= LOG_ZERO) continue;
01689
01690
01691
01692
01693
01694 for (ac = wchmm->state[node].ac; ac; ac = ac->next) {
01695 next_node = ac->arc;
01696
01697
01698
01699
01700
01701
01702
01703
01704 tmpsum = tk->score + ac->a;
01705 #ifdef USE_NGRAM
01706 ngram_score_cache = LOG_ZERO;
01707 #endif
01708
01709
01710
01711 #ifndef CATEGORY_TREE
01712
01713
01714
01715
01716
01717
01718
01719 if (next_node != node) {
01720 if (wchmm->state[next_node].scid != 0
01721 #ifdef UNIGRAM_FACTORING
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736 #endif
01737 ){
01738 #ifdef USE_NGRAM
01739
01740
01741
01742
01743 #ifdef FIX_PENALTY
01744
01745 if (tk->last_cword == WORD_INVALID) {
01746 ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight;
01747 } else {
01748 ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight + lm_penalty;
01749 }
01750 #else
01751 ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight + lm_penalty;
01752 #endif
01753
01754
01755
01756
01757
01758
01759 tmpsum -= tk->last_lscore;
01760 tmpsum += ngram_score_cache;
01761
01762 #else
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785 if (!can_succeed(wchmm, tk->last_tre->wid, next_node)) {
01786 tmpsum = LOG_ZERO;
01787 }
01788
01789 #endif
01790 }
01791 }
01792 #endif
01793
01794
01795
01796
01797
01798
01799
01800 if ((tknextid = node_exist_token(tn, next_node, tk->last_tre->wid)) != TOKENID_UNDEFINED) {
01801
01802
01803 tknext = &(tlist[tn][tknextid]);
01804 if (tknext->score < tmpsum) {
01805
01806
01807 tknext->last_tre = tk->last_tre;
01808 #ifdef USE_NGRAM
01809 tknext->last_cword = tk->last_cword;
01810 tknext->last_lscore = (ngram_score_cache != LOG_ZERO) ? ngram_score_cache : tk->last_lscore;
01811 #endif
01812 tknext->score = tmpsum;
01813 }
01814 } else {
01815
01816
01817 if (tmpsum > LOG_ZERO) {
01818 tknextid = create_token();
01819 tknext = &(tlist[tn][tknextid]);
01820
01821
01822
01823 tk = &(tlist[tl][tindex[tl][j]]);
01824 tknext->last_tre = tk->last_tre;
01825 #ifdef USE_NGRAM
01826 tknext->last_cword = tk->last_cword;
01827 tknext->last_lscore = (ngram_score_cache != LOG_ZERO) ? ngram_score_cache : tk->last_lscore;
01828 #endif
01829 tknext->score = tmpsum;
01830 node_assign_token(next_node, tknextid);
01831 }
01832 }
01833 }
01834
01835 #ifdef MULTIPATH_VERSION
01836
01837 }
01838
01839
01840
01841
01842
01843
01844 sort_token_no_order(trellis_beam_width, &n_start, &n_end);
01845
01846
01847
01848
01849
01850
01851 for(j=n_start; j<=n_end; j++) {
01852 tk = &(tlist[tn][tindex[tn][j]]);
01853 node = tk->node;
01854
01855 #endif
01856
01857
01858
01859 if (wchmm->stend[node] != WORD_INVALID) {
01860
01861 sword = wchmm->stend[node];
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876 tre = (TRELLIS_ATOM *)mybmalloc2(sizeof(TRELLIS_ATOM), &(backtrellis->root));
01877 tre->wid = sword;
01878 tre->backscore = tk->score;
01879 tre->begintime = tk->last_tre->endtime + 1;
01880 tre->endtime = t-1;
01881 tre->last_tre = tk->last_tre;
01882 #ifdef USE_NGRAM
01883 tre->lscore = tk->last_lscore;
01884 #endif
01885 bt_store(backtrellis, tre);
01886 #ifdef WORD_GRAPH
01887 if (tre->last_tre != NULL) {
01888
01889 tre->last_tre->within_context = TRUE;
01890 }
01891 #ifdef MULTIPATH_VERSION
01892 if (final) {
01893
01894 if (tre->wid == winfo->tail_silwid) {
01895 tre->within_context = TRUE;
01896 }
01897 }
01898 #endif
01899 #endif
01900
01901
01902
01903
01904
01905
01906 #ifdef MULTIPATH_VERSION
01907
01908
01909 if (final) continue;
01910 #endif
01911
01912
01913
01914
01915
01916
01917 #ifdef UNIGRAM_FACTORING
01918
01919
01920
01921
01922
01923 #endif
01924
01925 #ifdef USE_NGRAM
01926
01927
01928 if (sword == wchmm->winfo->tail_silwid) continue;
01929
01930 #ifdef UNIGRAM_FACTORING
01931
01932
01933
01934
01935
01936 if (wordend_best_score < tk->score
01937 #ifndef MULTIPATH_VERSION
01938 + wchmm->wordend_a[sword]
01939 #endif
01940 ) {
01941 wordend_best_score = tk->score
01942 #ifndef MULTIPATH_VERSION
01943 + wchmm->wordend_a[sword]
01944 #endif
01945 ;
01946 wordend_best_node = node;
01947 wordend_best_tre = tre;
01948 wordend_best_last_cword = tk->last_cword;
01949 }
01950 #endif
01951
01952
01953
01954
01955
01956
01957
01958 if (wchmm->winfo->is_transparent[sword]) {
01959 iwparray = max_successor_prob_iw(wchmm, tk->last_cword);
01960 } else {
01961 iwparray = max_successor_prob_iw(wchmm, sword);
01962 }
01963 #endif
01964
01965
01966
01967
01968
01969 for (stid = wchmm->startnum - 1; stid >= 0; stid--) {
01970 next_node = wchmm->startnode[stid];
01971 #ifdef MULTIPATH_VERSION
01972 #ifdef USE_NGRAM
01973
01974 if (wchmm->wordbegin[wchmm->winfo->head_silwid] == next_node) continue;
01975 #endif
01976 #endif
01977
01978
01979
01980
01981
01982
01983 #ifdef USE_NGRAM
01984
01985
01986 #ifdef UNIGRAM_FACTORING
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008 isoid = wchmm->start2isolate[stid];
02009
02010
02011
02012
02013 if (isoid == -1) continue;
02014 tmpprob = iwparray[isoid];
02015 #else
02016 tmpprob = iwparray[stid];
02017 #endif
02018 #endif
02019
02020 #ifdef USE_NGRAM
02021
02022
02023
02024
02025
02026
02027
02028
02029 #endif
02030
02031 #ifdef CATEGORY_TREE
02032
02033
02034
02035
02036
02037 if (dfa_cp(dfa, wchmm->winfo->wton[sword],
02038 #ifdef MULTIPATH_VERSION
02039 wchmm->winfo->wton[wchmm->start2wid[stid]]
02040 #else
02041 wchmm->winfo->wton[wchmm->ststart[next_node]]
02042 #endif
02043 ) == FALSE) continue;
02044 #endif
02045
02046
02047
02048
02049
02050 tmpsum = tk->score
02051 #ifndef MULTIPATH_VERSION
02052 + wchmm->wordend_a[sword]
02053 #endif
02054 ;
02055
02056 #ifdef USE_NGRAM
02057
02058
02059 ngram_score_cache = tmpprob * lm_weight + lm_penalty;
02060 tmpsum += ngram_score_cache;
02061 if (wchmm->winfo->is_transparent[sword] && wchmm->winfo->is_transparent[tk->last_cword]) {
02062
02063 tmpsum += lm_penalty_trans;
02064 }
02065 #else
02066
02067
02068 tmpsum += penalty1;
02069
02070
02071 #ifdef CATEGORY_TREE
02072
02073 #else
02074 if (!can_succeed(wchmm, sword, next_node)) {
02075 tmpsum = LOG_ZERO;
02076 }
02077 #endif
02078 #endif
02079
02080
02081
02082
02083
02084
02085
02086 #ifndef MULTIPATH_VERSION
02087 next_node2 = next_node;
02088 #else
02089 for(ac=wchmm->state[next_node].ac; ac; ac=ac->next) {
02090 next_node2 = ac->arc;
02091 #endif
02092
02093 if ((tknextid = node_exist_token(tn, next_node2, tre->wid)) != TOKENID_UNDEFINED) {
02094
02095
02096 tknext = &(tlist[tn][tknextid]);
02097 if (tknext->score < tmpsum) {
02098
02099
02100 #ifdef USE_NGRAM
02101 tknext->last_lscore = ngram_score_cache;
02102
02103 if (wchmm->winfo->is_transparent[sword]) {
02104
02105
02106
02107 tknext->last_cword = tk->last_cword;
02108 } else {
02109
02110 tknext->last_cword = sword;
02111 }
02112 #endif
02113
02114 tknext->score = tmpsum;
02115 #ifdef MULTIPATH_VERSION
02116 tknext->score += ac->a;
02117 #endif
02118
02119
02120
02121
02122 tknext->last_tre = tre;
02123 }
02124 } else {
02125
02126
02127 if (tmpsum > LOG_ZERO) {
02128 tknextid = create_token();
02129 tknext = &(tlist[tn][tknextid]);
02130
02131
02132
02133 #ifdef MULTIPATH_VERSION
02134 tk = &(tlist[tn][tindex[tn][j]]);
02135 #else
02136 tk = &(tlist[tl][tindex[tl][j]]);
02137 #endif
02138 #ifdef USE_NGRAM
02139 tknext->last_lscore = ngram_score_cache;
02140
02141 if (wchmm->winfo->is_transparent[sword]) {
02142
02143
02144
02145 tknext->last_cword = tk->last_cword;
02146 } else {
02147
02148 tknext->last_cword = sword;
02149 }
02150 #endif
02151 tknext->score = tmpsum;
02152 #ifdef MULTIPATH_VERSION
02153 tknext->score += ac->a;
02154 #endif
02155
02156
02157
02158
02159 tknext->last_tre = tre;
02160
02161 node_assign_token(next_node2, tknextid);
02162 }
02163 }
02164 #ifdef MULTIPATH_VERSION
02165 }
02166 #endif
02167
02168 }
02169 }
02170
02171 }
02172 #ifdef UNIGRAM_FACTORING
02173
02174
02175
02176
02177
02178 if (wordend_best_score > LOG_ZERO) {
02179 node = wordend_best_node;
02180 sword = wchmm->stend[node];
02181 for (stid = wchmm->startnum - 1; stid >= 0; stid--) {
02182 next_node = wchmm->startnode[stid];
02183
02184
02185 if (wchmm->start2isolate[stid] != -1) continue;
02186
02187 if (wchmm->state[next_node].scid >= 0) {
02188 j_error("InternalError: scid mismatch at 1-gram factoring of shared states\n");
02189 }
02190 tmpprob = wchmm->fscore[- wchmm->state[next_node].scid];
02191 ngram_score_cache = tmpprob * lm_weight + lm_penalty;
02192 tmpsum = wordend_best_score;
02193 tmpsum += ngram_score_cache;
02194 if (wchmm->winfo->is_transparent[sword] && wchmm->winfo->is_transparent[wordend_best_last_cword]) {
02195 tmpsum += lm_penalty_trans;
02196 }
02197
02198 #ifndef MULTIPATH_VERSION
02199 next_node2 = next_node;
02200 #else
02201 for(ac=wchmm->state[next_node].ac; ac; ac=ac->next) {
02202 next_node2 = ac->arc;
02203 #endif
02204 if ((tknextid = node_exist_token(tn, next_node2, sword)) != TOKENID_UNDEFINED) {
02205 tknext = &(tlist[tn][tknextid]);
02206 if (tknext->score < tmpsum) {
02207 tknext->last_lscore = ngram_score_cache;
02208 if (wchmm->winfo->is_transparent[sword]) {
02209 tknext->last_cword = wordend_best_last_cword;
02210 } else {
02211 tknext->last_cword = sword;
02212 }
02213 tknext->score = tmpsum;
02214 #ifdef MULTIPATH_VERSION
02215 tknext->score += ac->a;
02216 #endif
02217 tknext->last_tre = wordend_best_tre;
02218 }
02219 } else {
02220 if (tmpsum > LOG_ZERO) {
02221 tknextid = create_token();
02222 tknext = &(tlist[tn][tknextid]);
02223 tknext->last_lscore = ngram_score_cache;
02224 if (wchmm->winfo->is_transparent[sword]) {
02225 tknext->last_cword = wordend_best_last_cword;
02226 } else {
02227 tknext->last_cword = sword;
02228 }
02229 tknext->score = tmpsum;
02230 #ifdef MULTIPATH_VERSION
02231 tknext->score += ac->a;
02232 #endif
02233 tknext->last_tre = wordend_best_tre;
02234 node_assign_token(next_node2, tknextid);
02235 }
02236 }
02237 #ifdef MULTIPATH_VERSION
02238 }
02239 #endif
02240
02241 }
02242 }
02243 #endif
02244
02245
02246
02247
02248
02249
02250
02251
02252 #ifdef MULTIPATH_VERSION
02253
02254
02255 if (! final) {
02256 #endif
02257 for (j=0;j<tnum[tn];j++) {
02258 tk = &(tlist[tn][tindex[tn][j]]);
02259 #ifdef MULTIPATH_VERSION
02260
02261 if (wchmm->state[tk->node].out.state == NULL) continue;
02262 #endif
02263 tk->score += outprob_style(wchmm, tk->node, tk->last_tre->wid, t, param);
02264 }
02265 #ifdef MULTIPATH_VERSION
02266 }
02267 #endif
02268
02269 if (gmm != NULL) {
02270
02271 gmm_proceed(gmm, param, t);
02272 }
02273
02274
02275
02276
02277
02278
02279
02280 clear_tlist(tl);
02281
02282
02283
02284 sort_token_no_order(trellis_beam_width, &n_start, &n_end);
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303 if (progout_flag) {
02304
02305
02306 if ((t % progout_interval_frame) == 0) {
02307 bt_current_max(backtrellis, t-1, wchmm->winfo);
02308 }
02309 }
02310
02311
02312 if (debug2_flag) {
02313 bt_current_max_word(backtrellis, t-1, wchmm->winfo);
02314 }
02315
02316 #ifdef SP_BREAK_CURRENT_FRAME
02317
02318 if (detect_end_of_segment(backtrellis, t-1, wchmm)) {
02319
02320 return FALSE;
02321 }
02322 #endif
02323
02324
02325 if (tnum[tn] == 0) {
02326 j_printerr("Error: %dth frame: no nodes left in beam! model mismatch or wrong input?\n", t);
02327 return(FALSE);
02328 }
02329
02330 return(TRUE);
02331
02332 }
02333
02334
02335
02336
02337
02338
02362 void
02363 get_back_trellis_end(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis)
02364 {
02365 int t, node, j;
02366 TOKEN2 *tk;
02367
02368
02369
02370
02371 #ifdef MULTIPATH_VERSION
02372
02373
02374
02375 get_back_trellis_proceed(param->samplenum, param, wchmm, backtrellis, TRUE);
02376
02377 #else
02378
02379 t = param->samplenum;
02380 tl = tn;
02381 if (tn == 0) tn = 1; else tn = 0;
02382 for (j=n_start; j<=n_end; j++) {
02383 tk = &(tlist[tl][tindex[tl][j]]);
02384 node = tk->node;
02385 if (wchmm->stend[node] != WORD_INVALID) {
02386 tre = (TRELLIS_ATOM *)mybmalloc2(sizeof(TRELLIS_ATOM), &(backtrellis->root));
02387 tre->wid = wchmm->stend[node];
02388 tre->backscore = tk->score;
02389 tre->begintime = tk->last_tre->endtime + 1;
02390 tre->endtime = t-1;
02391 tre->last_tre = tk->last_tre;
02392 #ifdef USE_NGRAM
02393 tre->lscore = tk->last_lscore;
02394 #endif
02395 bt_store(backtrellis, tre);
02396 #ifdef WORD_GRAPH
02397 if (tre->last_tre != NULL) {
02398
02399 tre->last_tre->within_context = TRUE;
02400 }
02401
02402 if (tre->wid == winfo->tail_silwid) {
02403 tre->within_context = TRUE;
02404 }
02405 #endif
02406 }
02407 }
02408
02409 #endif
02410
02411 #ifdef SP_BREAK_CURRENT_FRAME
02412
02413
02414
02415 #endif
02416 }
02417
02418
02419
02420
02421
02454 LOGPROB
02455 finalize_1st_pass(BACKTRELLIS *backtrellis, WORD_INFO *winfo, int len)
02456 {
02457 LOGPROB lastscore;
02458 int mseclen;
02459 boolean ok_p;
02460
02461 backtrellis->framelen = len;
02462
02463
02464
02465
02466
02467 ok_p = TRUE;
02468 if (rejectshortlen > 0) {
02469 mseclen = (float)len * (float)para.smp_period * (float)para.frameshift / 10000.0;
02470 if (mseclen < rejectshortlen) {
02471 ok_p = FALSE;
02472 }
02473 }
02474
02475
02476
02477 if (ok_p) {
02478 bt_relocate_rw(backtrellis);
02479 bt_sort_rw(backtrellis);
02480 if (backtrellis->num == NULL) {
02481 if (backtrellis->framelen > 0) j_printerr("no survived word!\n");
02482 ok_p = FALSE;
02483 }
02484 }
02485
02486
02487
02488 if (verbose_flag && (!progout_flag)) j_printerr("\n");
02489 if (ok_p) {
02490 lastscore = print_1pass_result(backtrellis, len, winfo);
02491 } else {
02492 lastscore = LOG_ZERO;
02493 }
02494
02495 #ifdef USE_NGRAM
02496
02497
02498
02499
02500 #endif
02501
02502 free_nodes();
02503
02504 if (ok_p) {
02505 if (gmm != NULL) {
02506
02507 gmm_end(gmm);
02508 }
02509 }
02510
02511
02512 return(lastscore);
02513 }
02514
02515 #ifdef SP_BREAK_CURRENT_FRAME
02516
02517
02518
02519
02549 void
02550 finalize_segment(BACKTRELLIS *backtrellis, HTK_Param *param, int len)
02551 {
02552 int t;
02553
02554
02555
02556
02557 set_terminal_words(backtrellis);
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571 if (len != param->samplenum) {
02572
02573 VERMES("segmented: processed length=%d\n", len);
02574 VERMES("segmented: next decoding will restart from %d\n", sparea_start);
02575
02576
02577 rest_param = new_param();
02578 memcpy(&(rest_param->header), &(param->header), sizeof(HTK_Param_Header));
02579 rest_param->samplenum = param->samplenum - sparea_start;
02580 rest_param->header.samplenum = rest_param->samplenum;
02581 rest_param->veclen = param->veclen;
02582 rest_param->parvec = (VECT **)mymalloc(sizeof(VECT *) * rest_param->samplenum);
02583
02584 for(t=sparea_start;t<len;t++) {
02585 rest_param->parvec[t-sparea_start] = (VECT *)mymalloc(sizeof(VECT) * rest_param->veclen);
02586 memcpy(rest_param->parvec[t-sparea_start], param->parvec[t], sizeof(VECT) * rest_param->veclen);
02587 }
02588
02589 for(t=len;t<param->samplenum;t++) {
02590 rest_param->parvec[t-sparea_start] = param->parvec[t];
02591 }
02592
02593
02594
02595 param->samplenum = len;
02596 param->parvec = (VECT **)myrealloc(param->parvec, sizeof(VECT *) * param->samplenum);
02597 sp_break_last_nword_allow_override = TRUE;
02598
02599 } else {
02600
02601
02602 rest_param = NULL;
02603
02604 sp_break_last_word = WORD_INVALID;
02605 sp_break_last_nword = WORD_INVALID;
02606 sp_break_last_nword_allow_override = FALSE;
02607 }
02608 }
02609 #endif
02610
02611
02612
02613
02614
02615
02616
02617
02655 void
02656 get_back_trellis(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis,
02657 LOGPROB *backmax)
02658 {
02659 int t;
02660
02661
02662
02663 get_back_trellis_init(param, wchmm, backtrellis);
02664
02665
02666
02667 for (
02668 #ifdef MULTIPATH_VERSION
02669
02670 t = 0
02671 #else
02672
02673 t = 1
02674 #endif
02675 ; t < param->samplenum; t++) {
02676 if (get_back_trellis_proceed(t, param, wchmm, backtrellis
02677 #ifdef MULTIPATH_VERSION
02678 ,FALSE
02679 #endif
02680 ) == FALSE
02681 || (module_mode && module_wants_terminate())) {
02682
02683
02684
02685
02686 *backmax = finalize_1st_pass(backtrellis, wchmm->winfo, t-1);
02687 #ifdef SP_BREAK_CURRENT_FRAME
02688
02689
02690
02691 finalize_segment(backtrellis, param, t-1);
02692 #endif
02693
02694 return;
02695 }
02696 }
02697
02698
02699 get_back_trellis_end(param, wchmm, backtrellis);
02700
02701
02702 *backmax = finalize_1st_pass(backtrellis, wchmm->winfo, param->samplenum);
02703 #ifdef SP_BREAK_CURRENT_FRAME
02704
02705
02706
02707 finalize_segment(backtrellis, param, param->samplenum);
02708 #endif
02709 }
02710
02711