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
00109 static void
00110 generate_lattice(int endtime, WORD_ID wid, BACKTRELLIS *bt, WORD_INFO *winfo)
00111 {
00112 TRELLIS_ATOM *ta, *ta_last;
00113 int i,j;
00114 boolean new_node = FALSE;
00115
00116 glevel++;
00117
00118 if (endtime >= 0) {
00119 for (i=0;i<bt->num[endtime];i++) {
00120 ta = bt->rw[endtime][i];
00121 if (ta->wid == wid) {
00122 if (ta->within_wordgraph) {
00123
00124 } else {
00125
00126 ta->within_wordgraph = TRUE;
00127 garcs++;
00128 new_node = TRUE;
00129 ta_last = ta->last_tre;
00130 if (debug2_flag) {
00131 for(j=0;j<glevel;j++) j_printf(" ");
00132 j_printf("%s: %d->", winfo->wname[ta->wid], ta->endtime);
00133 if (ta_last->wid == WORD_INVALID) {
00134 j_printf("%d(WORD_INVALID)\n", ta_last->endtime);
00135 } else {
00136 j_printf("%d(%s)\n", ta_last->endtime, winfo->wname[ta_last->wid]);
00137 }
00138 }
00139
00140 generate_lattice(ta_last->endtime, ta_last->wid, bt, winfo);
00141 }
00142 }
00143 }
00144 }
00145 if (new_node) {
00146 gnodes++;
00147 }
00148 glevel--;
00149 }
00150 #endif
00151
00166 static void
00167 put_atom(TRELLIS_ATOM *atom, WORD_INFO *winfo)
00168 {
00169 int i;
00170 j_printf("%3d,%3d %f %16s (id=%5d)", atom->begintime, atom->endtime,
00171 atom->backscore, winfo->wname[atom->wid], atom->wid);
00172 for (i=0;i<winfo->wlen[atom->wid]; i++) {
00173 j_printf(" %s",winfo->wseq[atom->wid][i]->name);
00174 }
00175 j_printf("\n");
00176 }
00177
00210 static LOGPROB
00211 trace_backptr(WORD_ID wordseq_rt[MAXSEQNUM], int *rt_wordlen, TRELLIS_ATOM *atom, BACKTRELLIS *backtrellis, WORD_INFO *winfo)
00212 {
00213 int wordlen = 0;
00214 TRELLIS_ATOM *tretmp;
00215 LOGPROB langscore = 0.0;
00216 static WORD_ID wordseq[MAXSEQNUM];
00217 int i;
00218
00219
00220 wordseq[0] = atom->wid;
00221 wordlen = 1;
00222 tretmp = atom;
00223 #ifdef USE_NGRAM
00224 langscore += tretmp->lscore;
00225 #endif
00226 if (debug2_flag) {
00227 put_atom(tretmp, winfo);
00228 }
00229
00230
00231 while (tretmp->begintime > 0) {
00232 tretmp = tretmp->last_tre;
00233
00234
00235 if (tretmp == NULL) {
00236 j_error("ERROR: BackTrellis Pass missing??\n");
00237 }
00238 #ifdef USE_NGRAM
00239 langscore += tretmp->lscore;
00240 #endif
00241 wordseq[wordlen] = tretmp->wid;
00242 wordlen++;
00243 if (debug2_flag) {
00244 put_atom(tretmp, winfo);
00245 }
00246 if (wordlen >= MAXSEQNUM) {
00247 j_error("sentence length exceeded ( > %d)\n",MAXSEQNUM);
00248 }
00249 }
00250 *rt_wordlen = wordlen;
00251
00252 for(i=0;i<wordlen;i++) wordseq_rt[i] = wordseq[wordlen-i-1];
00253 return(langscore);
00254 }
00255
00305 static LOGPROB
00306 print_1pass_result(BACKTRELLIS *backtrellis, int framelen, WORD_INFO *winfo)
00307 {
00308 WORD_ID wordseq[MAXSEQNUM];
00309 int wordlen;
00310 int i;
00311 TRELLIS_ATOM *best;
00312 int last_time;
00313 LOGPROB total_lscore;
00314 #if defined(USE_DFA) || defined(SP_BREAK_CURRENT_FRAME)
00315 LOGPROB maxscore;
00316 TRELLIS_ATOM *tmp;
00317 #endif
00318
00319
00320 for (last_time = framelen - 1; last_time >= 0; last_time--) {
00321 #ifdef USE_NGRAM
00322 #ifdef SP_BREAK_CURRENT_FRAME
00323
00324
00325 maxscore = LOG_ZERO;
00326 for (i=0;i<backtrellis->num[last_time];i++) {
00327 tmp = backtrellis->rw[last_time][i];
00328 if (maxscore < tmp->backscore) {
00329 maxscore = tmp->backscore;
00330 best = tmp;
00331 }
00332 }
00333 if (maxscore != LOG_ZERO) break;
00334 #else
00335
00336
00337 best = bt_binsearch_atom(backtrellis, last_time, winfo->tail_silwid);
00338 if (best != NULL) break;
00339 #endif
00340 #else
00341
00342
00343 maxscore = LOG_ZERO;
00344 for (i=0;i<backtrellis->num[last_time];i++) {
00345 tmp = backtrellis->rw[last_time][i];
00346
00347 if (maxscore < tmp->backscore) {
00348 maxscore = tmp->backscore;
00349 best = tmp;
00350 }
00351
00352 }
00353 if (maxscore != LOG_ZERO) break;
00354 #endif
00355 }
00356 if (last_time < 0) {
00357 j_printerr("[no sentence-end word survived on last beam]\n");
00358
00359 result_pass1_final(NULL, 0, LOG_ZERO, LOG_ZERO, winfo);
00360 return(LOG_ZERO);
00361 }
00362
00363
00364 total_lscore = trace_backptr(wordseq, &wordlen, best, backtrellis, winfo);
00365
00366 if (progout_flag) {
00367 result_pass1_current(last_time, wordseq, wordlen, best->backscore, total_lscore, winfo);
00368 }
00369
00370
00371 if (verbose_flag || !progout_flag) {
00372 result_pass1_final(wordseq, wordlen, best->backscore, total_lscore, winfo);
00373 }
00374 result_pass1_end();
00375
00376
00377 for(i=0;i<wordlen;i++) pass1_wseq[i] = wordseq[i];
00378 pass1_wnum = wordlen;
00379 pass1_score = best->backscore;
00380
00381 #ifdef WORD_GRAPH
00382
00383
00384
00385
00386
00387 glevel = 0;
00388 gnodes = 1;
00389 garcs = 0;
00390 generate_lattice(last_time, winfo->tail_silwid, backtrellis, winfo);
00391 if (verbose_flag) j_printf("word graph generated (nodes=%d,arcs=%d)\n",gnodes, garcs);
00392 #endif
00393
00394
00395 return(best->backscore);
00396 }
00397
00415 static void
00416 bt_current_max(BACKTRELLIS *bt, int t, WORD_INFO *winfo)
00417 {
00418 static WORD_ID wordseq[MAXSEQNUM];
00419 int wordlen;
00420 TRELLIS_ATOM *tre;
00421 TRELLIS_ATOM *tremax;
00422 LOGPROB maxscore;
00423 LOGPROB lscore;
00424
00425
00426 maxscore = LOG_ZERO;
00427 tremax = NULL;
00428 tre = bt->list;
00429 while (tre != NULL && tre->endtime == t) {
00430 if (maxscore < tre->backscore) {
00431 maxscore = tre->backscore;
00432 tremax = tre;
00433 }
00434 tre = tre->next;
00435 }
00436
00437 if (maxscore != LOG_ZERO) {
00438 lscore = trace_backptr(wordseq, &wordlen, tremax, bt, winfo);
00439 result_pass1_current(t, wordseq, wordlen, tremax->backscore, lscore, winfo);
00440 } else {
00441 wordlen = 0;
00442 result_pass1_current(t, wordseq, wordlen, LOG_ZERO, LOG_ZERO, winfo);
00443 }
00444 }
00445
00463 static void
00464 bt_current_max_word(BACKTRELLIS *bt, int t, WORD_INFO *winfo)
00465 {
00466 TRELLIS_ATOM *tre;
00467 TRELLIS_ATOM *tremax;
00468 LOGPROB maxscore;
00469 WORD_ID w;
00470
00471
00472
00473 maxscore = LOG_ZERO;
00474 tremax = NULL;
00475 tre = bt->list;
00476 while (tre != NULL && tre->endtime == t) {
00477 if (maxscore < tre->backscore) {
00478 maxscore = tre->backscore;
00479 tremax = tre;
00480 }
00481 tre = tre->next;
00482 }
00483
00484 if (maxscore != LOG_ZERO) {
00485 j_printf("%3d: ",t);
00486 w = tremax->wid;
00487 j_printf("\"%s [%s]\"(id=%d)",
00488 winfo->wname[w], winfo->woutput[w], w);
00489 j_printf(" [%d-%d] %f <- ", tremax->begintime, t, tremax->backscore);
00490 w = tremax->last_tre->wid;
00491 if (w != WORD_INVALID) {
00492 j_printf("\"%s [%s]\"(id=%d)\n",
00493 winfo->wname[w], winfo->woutput[w], w);
00494 } else {
00495 j_printf("bgn\n");
00496 }
00497 }
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 static TOKEN2 *tlist[2];
00520 static TOKENID *tindex[2];
00521 static int maxtnum = 0;
00522 static int expand_step = 0;
00523 static int tnum[2];
00524 static int n_start;
00525 static int n_end;
00526 static int tl;
00527 static int tn;
00528
00529
00530 static TOKENID *token;
00531 static int totalnodenum;
00532
00533
00534 static TRELLIS_ATOM bos;
00535 static boolean nodes_malloced = FALSE;
00536
00555 static void
00556 malloc_nodes(int n, int ntoken_init, int ntoken_step)
00557 {
00558 totalnodenum = n;
00559 token = mymalloc(sizeof(TOKENID)*totalnodenum);
00560 if (maxtnum < ntoken_init) maxtnum = ntoken_init;
00561 tlist[0] = mymalloc(sizeof(TOKEN2)*maxtnum);
00562 tlist[1] = mymalloc(sizeof(TOKEN2)*maxtnum);
00563 tindex[0] = mymalloc(sizeof(TOKENID)*maxtnum);
00564 tindex[1] = mymalloc(sizeof(TOKENID)*maxtnum);
00565 tnum[0] = tnum[1] = 0;
00566 if (expand_step < ntoken_step) expand_step = ntoken_step;
00567 nodes_malloced = TRUE;
00568 }
00569
00578 static void
00579 expand_tlist()
00580 {
00581 maxtnum += expand_step;
00582 tlist[0] = myrealloc(tlist[0],sizeof(TOKEN2)*maxtnum);
00583 tlist[1] = myrealloc(tlist[1],sizeof(TOKEN2)*maxtnum);
00584 tindex[0] = myrealloc(tindex[0],sizeof(TOKENID)*maxtnum);
00585 tindex[1] = myrealloc(tindex[1],sizeof(TOKENID)*maxtnum);
00586
00587 }
00588
00597 static void
00598 free_nodes()
00599 {
00600 if (nodes_malloced) {
00601 free(token);
00602 free(tlist[0]);
00603 free(tlist[1]);
00604 free(tindex[0]);
00605 free(tindex[1]);
00606 nodes_malloced = FALSE;
00607 }
00608 }
00609
00622 static void
00623 clear_tlist(int tt)
00624 {
00625 tnum[tt] = 0;
00626 }
00627
00640 static void
00641 clear_tokens(int tt)
00642 {
00643 int j;
00644
00645 for (j=0; j<tnum[tt]; j++) {
00646 token[tlist[tt][j].node] = TOKENID_UNDEFINED;
00647 }
00648 }
00649
00662 static TOKENID
00663 create_token()
00664 {
00665 TOKENID newid;
00666 newid = tnum[tn];
00667 tnum[tn]++;
00668 if (tnum[tn]>=maxtnum) expand_tlist();
00669 tindex[tn][newid] = newid;
00670 #ifdef WPAIR
00671
00672 tlist[tn][newid].next = TOKENID_UNDEFINED;
00673 #endif
00674 return(newid);
00675 }
00676
00704 static void
00705 node_assign_token(int node, TOKENID tkid)
00706 {
00707 #ifdef WPAIR
00708
00709 tlist[tn][tkid].next = token[node];
00710 #endif
00711 token[node] = tkid;
00712 tlist[tn][tkid].node = node;
00713 }
00714
00749 static TOKENID
00750 node_exist_token(int tt, int node, WORD_ID wid)
00751 {
00752 #ifdef WPAIR
00753
00754
00755 #ifdef WPAIR_KEEP_NLIMIT
00756
00757
00758
00759 int i = 0;
00760 TOKENID lowest_token = TOKENID_UNDEFINED;
00761 #endif
00762 TOKENID tmp;
00763 for(tmp=token[node]; tmp != TOKENID_UNDEFINED; tmp=tlist[tt][tmp].next) {
00764 if (tlist[tt][tmp].last_tre->wid == wid) {
00765 return(tmp);
00766 }
00767 #ifdef WPAIR_KEEP_NLIMIT
00768 if (lowest_token == TOKENID_UNDEFINED ||
00769 tlist[tt][lowest_token].score < tlist[tt][tmp].score)
00770 lowest_token = tmp;
00771 if (++i >= wpair_keep_nlimit) break;
00772 #endif
00773 }
00774 #ifdef WPAIR_KEEP_NLIMIT
00775 if (i >= wpair_keep_nlimit) {
00776 return(lowest_token);
00777 } else {
00778 return(TOKENID_UNDEFINED);
00779 }
00780 #else
00781 return(TOKENID_UNDEFINED);
00782 #endif
00783
00784 #else
00785
00786
00787
00788 return(token[node]);
00789 #endif
00790 }
00791
00792 #ifdef DEBUG
00793
00794
00795
00796
00797
00798 static void
00799 node_check_token(int tt)
00800 {
00801 int i;
00802 for(i=0;i<tnum[tt];i++) {
00803 if (node_exist_token(tt, tlist[tt][i].node, tlist[tt][i].last_tre->wid) != i) {
00804 j_printerr("token %d not found on node %d\n", i, tlist[tt][i].node);
00805 }
00806 }
00807 }
00808 #endif
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821 #define SD(A) tindex[tn][A-1]
00822 #define SCOPY(D,S) D = S
00823 #define SVAL(A) (tlist[tn][tindex[tn][A-1]].score)
00824 #define STVAL (tlist[tn][s].score)
00825
00826
00848 static void
00849 sort_token_upward(int neednum, int totalnum)
00850 {
00851 int n,root,child,parent;
00852 TOKENID s;
00853 for (root = totalnum/2; root >= 1; root--) {
00854 SCOPY(s, SD(root));
00855 parent = root;
00856 while ((child = parent * 2) <= totalnum) {
00857 if (child < totalnum && SVAL(child) < SVAL(child+1)) {
00858 child++;
00859 }
00860 if (STVAL >= SVAL(child)) {
00861 break;
00862 }
00863 SCOPY(SD(parent), SD(child));
00864 parent = child;
00865 }
00866 SCOPY(SD(parent), s);
00867 }
00868 n = totalnum;
00869 while ( n > totalnum - neednum) {
00870 SCOPY(s, SD(n));
00871 SCOPY(SD(n), SD(1));
00872 n--;
00873 parent = 1;
00874 while ((child = parent * 2) <= n) {
00875 if (child < n && SVAL(child) < SVAL(child+1)) {
00876 child++;
00877 }
00878 if (STVAL >= SVAL(child)) {
00879 break;
00880 }
00881 SCOPY(SD(parent), SD(child));
00882 parent = child;
00883 }
00884 SCOPY(SD(parent), s);
00885 }
00886 }
00887
00912 static void
00913 sort_token_downward(int neednum, int totalnum)
00914 {
00915 int n,root,child,parent;
00916 TOKENID s;
00917 for (root = totalnum/2; root >= 1; root--) {
00918 SCOPY(s, SD(root));
00919 parent = root;
00920 while ((child = parent * 2) <= totalnum) {
00921 if (child < totalnum && SVAL(child) > SVAL(child+1)) {
00922 child++;
00923 }
00924 if (STVAL <= SVAL(child)) {
00925 break;
00926 }
00927 SCOPY(SD(parent), SD(child));
00928 parent = child;
00929 }
00930 SCOPY(SD(parent), s);
00931 }
00932 n = totalnum;
00933 while ( n > totalnum - neednum) {
00934 SCOPY(s, SD(n));
00935 SCOPY(SD(n), SD(1));
00936 n--;
00937 parent = 1;
00938 while ((child = parent * 2) <= n) {
00939 if (child < n && SVAL(child) > SVAL(child+1)) {
00940 child++;
00941 }
00942 if (STVAL <= SVAL(child)) {
00943 break;
00944 }
00945 SCOPY(SD(parent), SD(child));
00946 parent = child;
00947 }
00948 SCOPY(SD(parent), s);
00949 }
00950 }
00951
00982 static void
00983 sort_token_no_order(int neednum, int *start, int *end)
00984 {
00985 int totalnum = tnum[tn];
00986 int restnum;
00987
00988 restnum = totalnum - neednum;
00989
00990 if (neednum >= totalnum) {
00991
00992 *start = 0;
00993 *end = totalnum - 1;
00994 } else if (neednum < restnum) {
00995
00996 sort_token_upward(neednum,totalnum);
00997 *start = totalnum - neednum;
00998 *end = totalnum - 1;
00999 } else {
01000
01001 sort_token_downward(restnum,totalnum);
01002 *start = 0;
01003 *end = neednum - 1;
01004 }
01005 }
01006
01007
01008 #ifdef SP_BREAK_CURRENT_FRAME
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 static boolean in_sparea;
01030 static int sparea_start;
01031 static int tmp_sparea_start;
01032 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01033 static WORD_ID tmp_sp_break_last_word;
01034 #else
01035 static WORD_ID last_tre_word;
01036 #endif
01037 static boolean first_sparea;
01038 static int sp_duration;
01039
01066 boolean
01067 is_sil(WORD_ID w, WORD_INFO *winfo, HTK_HMM_INFO *hmm)
01068 {
01069
01070 if (winfo->wlen[w] > 1) return FALSE;
01071
01072
01073 if (winfo->wseq[w][0] == hmm->sp) return TRUE;
01074
01075
01076 if (w == winfo->head_silwid || w == winfo->tail_silwid) return TRUE;
01077
01078
01079 return FALSE;
01080 }
01081
01105 static boolean
01106 detect_end_of_segment(BACKTRELLIS *backtrellis, int time, WCHMM_INFO *wchmm)
01107 {
01108 TRELLIS_ATOM *tre;
01109 LOGPROB maxscore = LOG_ZERO;
01110 TRELLIS_ATOM *tremax = NULL;
01111 int count = 0;
01112 boolean detected = FALSE;
01113
01114
01115 for(tre = backtrellis->list; tre != NULL && tre->endtime == time; tre = tre->next) {
01116 if (maxscore < tre->backscore) {
01117 maxscore = tre->backscore;
01118 tremax = tre;
01119 }
01120 count++;
01121 }
01122 if (tremax == NULL) {
01123 detected = TRUE;
01124 } else if (count > 0) {
01125 if (is_sil(tremax->wid, wchmm->winfo, wchmm->hmminfo)) {
01126 detected = TRUE;
01127 }
01128 }
01129
01130
01131
01132 if (in_sparea && detected) {
01133 sp_duration++;
01134 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01135
01136
01137
01138
01139 if (tmp_sp_break_last_word == WORD_INVALID) {
01140 if (tremax != NULL) tmp_sp_break_last_word = tremax->wid;
01141 }
01142 #else
01143
01144
01145 if (tremax != NULL) last_tre_word = tremax->wid;
01146 #endif
01147 }
01148
01149
01150
01151 else if (!in_sparea && detected) {
01152
01153
01154 tmp_sparea_start = time;
01155 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01156
01157
01158 tmp_sp_break_last_word = tremax ? tremax->wid : WORD_INVALID;
01159 #endif
01160 in_sparea = TRUE;
01161 sp_duration = 1;
01162 #ifdef SP_BREAK_DEBUG
01163 printf("sp start %d\n", time);
01164 #endif
01165 }
01166
01167
01168
01169 else if (in_sparea && !detected) {
01170
01171 in_sparea = FALSE;
01172 #ifdef SP_BREAK_DEBUG
01173 printf("sp end %d\n", time);
01174 #endif
01175
01176
01177 if (sp_duration < sp_frame_duration) {
01178
01179
01180 #ifdef SP_BREAK_DEBUG
01181 printf("too short (%d<%d), ignored\n", sp_duration, sp_frame_duration);
01182 #endif
01183 } else if (first_sparea) {
01184
01185
01186 first_sparea = FALSE;
01187 #ifdef SP_BREAK_DEBUG
01188 printf("first silence, ignored\n");
01189 #endif
01190 } else {
01191
01192
01193 #ifdef SP_BREAK_DEBUG
01194 printf(">> segment [%d..%d]\n", sparea_start, time-1);
01195 #else
01196 if (idc_on) j_printerr("|");
01197 #endif
01198
01199 sparea_start = tmp_sparea_start;
01200 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01201
01202 sp_break_last_word = tmp_sp_break_last_word;
01203 #else
01204
01205 sp_break_last_word = last_tre_word;
01206 #endif
01207
01208
01209 return(TRUE);
01210 }
01211 }
01212
01213 #ifdef SP_BREAK_EVAL
01214 printf("[%d %d %d]\n", time, count, (detected) ? 50 : 0);
01215 #endif
01216 return (FALSE);
01217 }
01218
01219 #endif
01220
01221
01222
01223
01224
01225
01226
01227
01246 static void
01247 init_nodescore(HTK_Param *param, WCHMM_INFO *wchmm)
01248 {
01249 TOKENID newid;
01250 TOKEN2 *new;
01251 #ifdef USE_NGRAM
01252 WORD_ID beginword;
01253 #endif
01254 int node;
01255 #ifdef USE_DFA
01256 int i;
01257 #endif
01258
01259
01260
01261 #ifdef SP_BREAK_CURRENT_FRAME
01262
01263 if (sp_break_last_nword == wchmm->winfo->tail_silwid) {
01264
01265 bos.wid = WORD_INVALID;
01266 } else {
01267 bos.wid = sp_break_last_nword;
01268 }
01269 #else
01270 bos.wid = WORD_INVALID;
01271 #endif
01272 bos.begintime = bos.endtime = -1;
01273
01274
01275
01276 for(node=0;node<totalnodenum;node++) {
01277 token[node] = TOKENID_UNDEFINED;
01278 }
01279 tnum[0] = tnum[1] = 0;
01280
01281 #ifdef PASS1_IWCD
01282
01283
01284 outprob_style_cache_init(wchmm);
01285 #endif
01286
01287
01288
01289 #ifdef USE_NGRAM
01290
01291 #ifdef SP_BREAK_CURRENT_FRAME
01292 if (sp_break_last_word != WORD_INVALID) {
01293
01294
01295
01296
01297
01298 if (sp_break_last_word == wchmm->winfo->tail_silwid) {
01299 beginword = wchmm->winfo->head_silwid;
01300 bos.wid = WORD_INVALID;
01301 } else {
01302 beginword = sp_break_last_word;
01303 }
01304 } else {
01305
01306 beginword = wchmm->winfo->head_silwid;
01307 }
01308 #else
01309
01310 beginword = wchmm->winfo->head_silwid;
01311 #endif
01312 #ifdef SP_BREAK_DEBUG
01313 printf("startword=[%s], last_nword=[%s]\n",
01314 (beginword == WORD_INVALID) ? "WORD_INVALID" : wchmm->winfo->wname[beginword],
01315 (bos.wid == WORD_INVALID) ? "WORD_INVALID" : wchmm->winfo->wname[bos.wid]);
01316 #endif
01317
01318 newid = create_token();
01319 new = &(tlist[tn][newid]);
01320
01321 #ifdef MULTIPATH_VERSION
01322 node = wchmm->wordbegin[beginword];
01323 #else
01324 node = wchmm->offset[beginword][0];
01325 #endif
01326
01327 if (wchmm->state[node].scid != 0) {
01328
01329 new->last_lscore = max_successor_prob(wchmm, bos.wid, node);
01330 } else {
01331
01332 new->last_lscore = 0.0;
01333 }
01334 #ifdef FIX_PENALTY
01335 new->last_lscore = new->last_lscore * lm_weight;
01336 #else
01337 new->last_lscore = new->last_lscore * lm_weight + lm_penalty;
01338 #endif
01339
01340 new->last_tre = &bos;
01341 new->last_cword = bos.wid;
01342 #ifdef MULTIPATH_VERSION
01343
01344 new->score = new->last_lscore;
01345 #else
01346
01347 new->score = outprob_style(wchmm, node, bos.wid, 0, param) + new->last_lscore;
01348 #endif
01349
01350 node_assign_token(node, newid);
01351
01352 #else
01353
01354
01355
01356
01357
01358 {
01359 MULTIGRAM *m;
01360 int t,tb,te;
01361 WORD_ID iw;
01362
01363
01364 for(m = gramlist; m; m = m->next) {
01365 if (m->active) {
01366 tb = m->cate_begin;
01367 te = tb + m->dfa->term_num;
01368 for(t=tb;t<te;t++) {
01369
01370 if (dfa_cp_begin(dfa, t) == TRUE) {
01371
01372 for (iw=0;iw<dfa->term.wnum[t];iw++) {
01373
01374 i = dfa->term.tw[t][iw];
01375 #ifdef MULTIPATH_VERSION
01376 node = wchmm->wordbegin[i];
01377 #else
01378 node = wchmm->offset[i][0];
01379 #endif
01380
01381 if (node_exist_token(tn, node, bos.wid) != TOKENID_UNDEFINED) continue;
01382 newid = create_token();
01383 new = &(tlist[tn][newid]);
01384 new->last_tre = &bos;
01385 #ifdef MULTIPATH_VERSION
01386 new->score = 0.0;
01387 #else
01388 new->score = outprob_style(wchmm, node, bos.wid, 0, param);
01389 #endif
01390 node_assign_token(node, newid);
01391 }
01392 }
01393 }
01394 }
01395 }
01396 }
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411 #endif
01412 }
01413
01414
01415
01416
01417
01418
01444 void
01445 get_back_trellis_init(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis)
01446 {
01447
01448
01449
01450
01451
01452 tn = 0;
01453 tl = 1;
01454
01455
01456
01457 bt_prepare(backtrellis);
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468 malloc_nodes(wchmm->n, trellis_beam_width * 2 + wchmm->startnum, trellis_beam_width);
01469
01470
01471
01472 init_nodescore(param, wchmm);
01473 sort_token_no_order(trellis_beam_width, &n_start, &n_end);
01474
01475
01476
01477 result_pass1_begin();
01478
01479
01480 progout_interval_frame = (int)((float)progout_interval / ((float)param->header.wshift / 10000.0));
01481
01482
01483
01484 if (!realtime_flag && verbose_flag && (!progout_flag) && isatty(1)) {
01485 idc_on = TRUE;
01486 } else {
01487 idc_on = FALSE;
01488 }
01489
01490 #ifdef SP_BREAK_CURRENT_FRAME
01491
01492
01493 in_sparea = TRUE;
01494 sparea_start = tmp_sparea_start = 0;
01495 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01496 tmp_sp_break_last_word = WORD_INVALID;
01497 #endif
01498 sp_break_last_word = WORD_INVALID;
01499
01500
01501
01502 first_sparea = TRUE;
01503 sp_break_2_begin_word = WORD_INVALID;
01504 #endif
01505
01506 if (gmm != NULL) {
01507
01508 gmm_prepare(gmm);
01509 }
01510 }
01511
01512
01513 static TRELLIS_ATOM *tre;
01514 static int node;
01515 static int stid;
01516 static A_CELL *ac;
01517 static int next_node2;
01518 #ifdef USE_NGRAM
01519 static LOGPROB tmpprob;
01520 static LOGPROB *iwparray;
01521 #endif
01522 #ifdef UNIGRAM_FACTORING
01523
01524 static LOGPROB wordend_best_score;
01525 static int wordend_best_node;
01526 static TRELLIS_ATOM *wordend_best_tre;
01527 static WORD_ID wordend_best_last_cword;
01528 static int isoid;
01529 #endif
01530
01531
01532
01533
01534
01535
01575 boolean
01576 get_back_trellis_proceed(int t, HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis
01577 #ifdef MULTIPATH_VERSION
01578 , boolean final
01579 #endif
01580 )
01581 {
01582 LOGPROB tmpsum;
01583 int j, next_node, sword;
01584 TOKEN2 *tk, *tknext;
01585 TOKENID tknextid;
01586 #ifdef USE_NGRAM
01587 LOGPROB ngram_score_cache;
01588 #endif
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599 tl = tn;
01600 if (tn == 0) tn = 1; else tn = 0;
01601
01602
01603
01604 if (idc_on) {
01605 #ifdef SP_BREAK_CURRENT_FRAME
01606 if (in_sparea) j_printerr("."); else j_printerr("-");
01607 #else
01608 j_printerr(".");
01609 #endif
01610 }
01611
01612 #ifdef UNIGRAM_FACTORING
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630 wordend_best_score = LOG_ZERO;
01631 #endif
01632
01633 #ifdef DEBUG
01634
01635
01636 #endif
01637
01638
01639
01640 clear_tokens(tl);
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 for (j=n_start;j<=n_end;j++) {
01651
01652
01653
01654 tk = &(tlist[tl][tindex[tl][j]]);
01655 node = tk->node;
01656 if (tk->score <= LOG_ZERO) continue;
01657
01658
01659
01660
01661
01662 for (ac = wchmm->state[node].ac; ac; ac = ac->next) {
01663 next_node = ac->arc;
01664
01665
01666
01667
01668
01669
01670
01671
01672 tmpsum = tk->score + ac->a;
01673 #ifdef USE_NGRAM
01674 ngram_score_cache = LOG_ZERO;
01675 #endif
01676
01677
01678
01679 #ifndef CATEGORY_TREE
01680
01681
01682
01683
01684
01685
01686
01687 if (next_node != node) {
01688 if (wchmm->state[next_node].scid != 0
01689 #ifdef UNIGRAM_FACTORING
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704 #endif
01705 ){
01706 #ifdef USE_NGRAM
01707
01708
01709
01710
01711 #ifdef FIX_PENALTY
01712
01713 if (tk->last_cword == WORD_INVALID) {
01714 ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight;
01715 } else {
01716 ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight + lm_penalty;
01717 }
01718 #else
01719 ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight + lm_penalty;
01720 #endif
01721
01722
01723
01724
01725
01726
01727 tmpsum -= tk->last_lscore;
01728 tmpsum += ngram_score_cache;
01729
01730 #else
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753 if (!can_succeed(wchmm, tk->last_tre->wid, next_node)) {
01754 tmpsum = LOG_ZERO;
01755 }
01756
01757 #endif
01758 }
01759 }
01760 #endif
01761
01762
01763
01764
01765
01766
01767
01768 if ((tknextid = node_exist_token(tn, next_node, tk->last_tre->wid)) != TOKENID_UNDEFINED) {
01769
01770
01771 tknext = &(tlist[tn][tknextid]);
01772 if (tknext->score < tmpsum) {
01773
01774
01775 tknext->last_tre = tk->last_tre;
01776 #ifdef USE_NGRAM
01777 tknext->last_cword = tk->last_cword;
01778 tknext->last_lscore = (ngram_score_cache != LOG_ZERO) ? ngram_score_cache : tk->last_lscore;
01779 #endif
01780 tknext->score = tmpsum;
01781 }
01782 } else {
01783
01784
01785 if (tmpsum > LOG_ZERO) {
01786 tknextid = create_token();
01787 tknext = &(tlist[tn][tknextid]);
01788
01789
01790
01791 tk = &(tlist[tl][tindex[tl][j]]);
01792 tknext->last_tre = tk->last_tre;
01793 #ifdef USE_NGRAM
01794 tknext->last_cword = tk->last_cword;
01795 tknext->last_lscore = (ngram_score_cache != LOG_ZERO) ? ngram_score_cache : tk->last_lscore;
01796 #endif
01797 tknext->score = tmpsum;
01798 node_assign_token(next_node, tknextid);
01799 }
01800 }
01801 }
01802
01803 #ifdef MULTIPATH_VERSION
01804
01805 }
01806
01807
01808
01809
01810
01811
01812 sort_token_no_order(trellis_beam_width, &n_start, &n_end);
01813
01814
01815
01816
01817
01818
01819 for(j=n_start; j<=n_end; j++) {
01820 tk = &(tlist[tn][tindex[tn][j]]);
01821 node = tk->node;
01822
01823 #endif
01824
01825
01826
01827 if (wchmm->stend[node] != WORD_INVALID) {
01828
01829 sword = wchmm->stend[node];
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844 tre = (TRELLIS_ATOM *)mymalloc(sizeof(TRELLIS_ATOM));
01845 tre->wid = sword;
01846 tre->backscore = tk->score;
01847 tre->begintime = tk->last_tre->endtime + 1;
01848 tre->endtime = t-1;
01849 tre->last_tre = tk->last_tre;
01850 #ifdef USE_NGRAM
01851 tre->lscore = tk->last_lscore;
01852 #endif
01853 bt_store(backtrellis, tre);
01854
01855
01856
01857
01858
01859
01860 #ifdef MULTIPATH_VERSION
01861
01862
01863 if (final) continue;
01864 #endif
01865
01866
01867
01868
01869
01870
01871 #ifdef UNIGRAM_FACTORING
01872
01873
01874
01875
01876
01877 #endif
01878
01879 #ifdef USE_NGRAM
01880
01881
01882 if (sword == wchmm->winfo->tail_silwid) continue;
01883
01884 #ifdef UNIGRAM_FACTORING
01885
01886
01887
01888
01889
01890 if (wordend_best_score < tk->score
01891 #ifndef MULTIPATH_VERSION
01892 + wchmm->wordend_a[sword]
01893 #endif
01894 ) {
01895 wordend_best_score = tk->score
01896 #ifndef MULTIPATH_VERSION
01897 + wchmm->wordend_a[sword]
01898 #endif
01899 ;
01900 wordend_best_node = node;
01901 wordend_best_tre = tre;
01902 wordend_best_last_cword = tk->last_cword;
01903 }
01904 #endif
01905
01906
01907
01908
01909
01910
01911
01912 if (wchmm->winfo->is_transparent[sword]) {
01913 iwparray = max_successor_prob_iw(wchmm, tk->last_cword);
01914 } else {
01915 iwparray = max_successor_prob_iw(wchmm, sword);
01916 }
01917 #endif
01918
01919
01920
01921
01922
01923 for (stid = wchmm->startnum - 1; stid >= 0; stid--) {
01924 next_node = wchmm->startnode[stid];
01925 #ifdef MULTIPATH_VERSION
01926 #ifdef USE_NGRAM
01927
01928 if (wchmm->wordbegin[wchmm->winfo->head_silwid] == next_node) continue;
01929 #endif
01930 #endif
01931
01932
01933
01934
01935
01936
01937 #ifdef USE_NGRAM
01938
01939
01940 #ifdef UNIGRAM_FACTORING
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962 isoid = wchmm->start2isolate[stid];
01963
01964
01965
01966
01967 if (isoid == -1) continue;
01968 tmpprob = iwparray[isoid];
01969 #else
01970 tmpprob = iwparray[stid];
01971 #endif
01972 #endif
01973
01974 #ifdef USE_NGRAM
01975
01976
01977
01978
01979
01980
01981
01982
01983 #endif
01984
01985 #ifdef CATEGORY_TREE
01986
01987
01988
01989
01990
01991 if (dfa_cp(dfa, wchmm->winfo->wton[sword],
01992 #ifdef MULTIPATH_VERSION
01993 wchmm->winfo->wton[wchmm->start2wid[stid]]
01994 #else
01995 wchmm->winfo->wton[wchmm->ststart[next_node]]
01996 #endif
01997 ) == FALSE) continue;
01998 #endif
01999
02000
02001
02002
02003
02004 tmpsum = tk->score
02005 #ifndef MULTIPATH_VERSION
02006 + wchmm->wordend_a[sword]
02007 #endif
02008 ;
02009
02010 #ifdef USE_NGRAM
02011
02012
02013 ngram_score_cache = tmpprob * lm_weight + lm_penalty;
02014 tmpsum += ngram_score_cache;
02015 if (wchmm->winfo->is_transparent[sword] && wchmm->winfo->is_transparent[tk->last_cword]) {
02016
02017 tmpsum += lm_penalty_trans;
02018 }
02019 #else
02020
02021
02022 tmpsum += penalty1;
02023
02024
02025 #ifdef CATEGORY_TREE
02026
02027 #else
02028 if (!can_succeed(wchmm, sword, next_node)) {
02029 tmpsum = LOG_ZERO;
02030 }
02031 #endif
02032 #endif
02033
02034
02035
02036
02037
02038
02039
02040 #ifndef MULTIPATH_VERSION
02041 next_node2 = next_node;
02042 #else
02043 for(ac=wchmm->state[next_node].ac; ac; ac=ac->next) {
02044 next_node2 = ac->arc;
02045 #endif
02046
02047 if ((tknextid = node_exist_token(tn, next_node2, tre->wid)) != TOKENID_UNDEFINED) {
02048
02049
02050 tknext = &(tlist[tn][tknextid]);
02051 if (tknext->score < tmpsum) {
02052
02053
02054 #ifdef USE_NGRAM
02055 tknext->last_lscore = ngram_score_cache;
02056
02057 if (wchmm->winfo->is_transparent[sword]) {
02058
02059
02060
02061 tknext->last_cword = tk->last_cword;
02062 } else {
02063
02064 tknext->last_cword = sword;
02065 }
02066 #endif
02067
02068 tknext->score = tmpsum;
02069 #ifdef MULTIPATH_VERSION
02070 tknext->score += ac->a;
02071 #endif
02072
02073
02074
02075
02076 tknext->last_tre = tre;
02077 }
02078 } else {
02079
02080
02081 if (tmpsum > LOG_ZERO) {
02082 tknextid = create_token();
02083 tknext = &(tlist[tn][tknextid]);
02084
02085
02086
02087 #ifdef MULTIPATH_VERSION
02088 tk = &(tlist[tn][tindex[tn][j]]);
02089 #else
02090 tk = &(tlist[tl][tindex[tl][j]]);
02091 #endif
02092 #ifdef USE_NGRAM
02093 tknext->last_lscore = ngram_score_cache;
02094
02095 if (wchmm->winfo->is_transparent[sword]) {
02096
02097
02098
02099 tknext->last_cword = tk->last_cword;
02100 } else {
02101
02102 tknext->last_cword = sword;
02103 }
02104 #endif
02105 tknext->score = tmpsum;
02106 #ifdef MULTIPATH_VERSION
02107 tknext->score += ac->a;
02108 #endif
02109
02110
02111
02112
02113 tknext->last_tre = tre;
02114
02115 node_assign_token(next_node2, tknextid);
02116 }
02117 }
02118 #ifdef MULTIPATH_VERSION
02119 }
02120 #endif
02121
02122 }
02123 }
02124
02125 }
02126 #ifdef UNIGRAM_FACTORING
02127
02128
02129
02130
02131
02132 if (wordend_best_score > LOG_ZERO) {
02133 node = wordend_best_node;
02134 sword = wchmm->stend[node];
02135 for (stid = wchmm->startnum - 1; stid >= 0; stid--) {
02136 next_node = wchmm->startnode[stid];
02137
02138
02139 if (wchmm->start2isolate[stid] != -1) continue;
02140
02141 if (wchmm->state[next_node].scid >= 0) {
02142 j_error("InternalError: scid mismatch at 1-gram factoring of shared states\n");
02143 }
02144 tmpprob = wchmm->fscore[- wchmm->state[next_node].scid];
02145 ngram_score_cache = tmpprob * lm_weight + lm_penalty;
02146 tmpsum = wordend_best_score;
02147 tmpsum += ngram_score_cache;
02148 if (wchmm->winfo->is_transparent[sword] && wchmm->winfo->is_transparent[wordend_best_last_cword]) {
02149 tmpsum += lm_penalty_trans;
02150 }
02151
02152 #ifndef MULTIPATH_VERSION
02153 next_node2 = next_node;
02154 #else
02155 for(ac=wchmm->state[next_node].ac; ac; ac=ac->next) {
02156 next_node2 = ac->arc;
02157 #endif
02158 if ((tknextid = node_exist_token(tn, next_node2, sword)) != TOKENID_UNDEFINED) {
02159 tknext = &(tlist[tn][tknextid]);
02160 if (tknext->score < tmpsum) {
02161 tknext->last_lscore = ngram_score_cache;
02162 if (wchmm->winfo->is_transparent[sword]) {
02163 tknext->last_cword = wordend_best_last_cword;
02164 } else {
02165 tknext->last_cword = sword;
02166 }
02167 tknext->score = tmpsum;
02168 #ifdef MULTIPATH_VERSION
02169 tknext->score += ac->a;
02170 #endif
02171 tknext->last_tre = wordend_best_tre;
02172 }
02173 } else {
02174 if (tmpsum > LOG_ZERO) {
02175 tknextid = create_token();
02176 tknext = &(tlist[tn][tknextid]);
02177 tknext->last_lscore = ngram_score_cache;
02178 if (wchmm->winfo->is_transparent[sword]) {
02179 tknext->last_cword = wordend_best_last_cword;
02180 } else {
02181 tknext->last_cword = sword;
02182 }
02183 tknext->score = tmpsum;
02184 #ifdef MULTIPATH_VERSION
02185 tknext->score += ac->a;
02186 #endif
02187 tknext->last_tre = wordend_best_tre;
02188 node_assign_token(next_node2, tknextid);
02189 }
02190 }
02191 #ifdef MULTIPATH_VERSION
02192 }
02193 #endif
02194
02195 }
02196 }
02197 #endif
02198
02199
02200
02201
02202
02203
02204
02205
02206 #ifdef MULTIPATH_VERSION
02207
02208
02209 if (! final) {
02210 #endif
02211 for (j=0;j<tnum[tn];j++) {
02212 tk = &(tlist[tn][tindex[tn][j]]);
02213 #ifdef MULTIPATH_VERSION
02214
02215 if (wchmm->state[tk->node].out.state == NULL) continue;
02216 #endif
02217 tk->score += outprob_style(wchmm, tk->node, tk->last_tre->wid, t, param);
02218 }
02219 #ifdef MULTIPATH_VERSION
02220 }
02221 #endif
02222
02223 if (gmm != NULL) {
02224
02225 gmm_proceed(gmm, param, t);
02226 }
02227
02228
02229
02230
02231
02232
02233
02234 clear_tlist(tl);
02235
02236
02237
02238 sort_token_no_order(trellis_beam_width, &n_start, &n_end);
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257 if (progout_flag) {
02258
02259
02260 if ((t % progout_interval_frame) == 0) {
02261 bt_current_max(backtrellis, t-1, wchmm->winfo);
02262 }
02263 }
02264
02265
02266 if (debug2_flag) {
02267 bt_current_max_word(backtrellis, t-1, wchmm->winfo);
02268 }
02269
02270 #ifdef SP_BREAK_CURRENT_FRAME
02271
02272 if (detect_end_of_segment(backtrellis, t-1, wchmm)) {
02273
02274 return FALSE;
02275 }
02276 #endif
02277
02278
02279 if (tnum[tn] == 0) {
02280 j_printerr("Error: %dth frame: no nodes left in beam! model mismatch or wrong input?\n", t);
02281 return(FALSE);
02282 }
02283
02284 return(TRUE);
02285
02286 }
02287
02288
02289
02290
02291
02292
02316 void
02317 get_back_trellis_end(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis)
02318 {
02319 int t, node, j;
02320 TOKEN2 *tk;
02321
02322
02323
02324
02325 #ifdef MULTIPATH_VERSION
02326
02327
02328
02329 get_back_trellis_proceed(param->samplenum, param, wchmm, backtrellis, TRUE);
02330
02331 #else
02332
02333 t = param->samplenum;
02334 tl = tn;
02335 if (tn == 0) tn = 1; else tn = 0;
02336 for (j=n_start; j<=n_end; j++) {
02337 tk = &(tlist[tl][tindex[tl][j]]);
02338 node = tk->node;
02339 if (wchmm->stend[node] != WORD_INVALID) {
02340 tre = (TRELLIS_ATOM *)mymalloc(sizeof(TRELLIS_ATOM));
02341 tre->wid = wchmm->stend[node];
02342 tre->backscore = tk->score;
02343 tre->begintime = tk->last_tre->endtime + 1;
02344 tre->endtime = t-1;
02345 tre->last_tre = tk->last_tre;
02346 #ifdef USE_NGRAM
02347 tre->lscore = tk->last_lscore;
02348 #endif
02349 bt_store(backtrellis, tre);
02350 }
02351 }
02352
02353 #endif
02354
02355 #ifdef SP_BREAK_CURRENT_FRAME
02356
02357
02358
02359 #endif
02360 }
02361
02362
02363
02364
02365
02398 LOGPROB
02399 finalize_1st_pass(BACKTRELLIS *backtrellis, WORD_INFO *winfo, int len)
02400 {
02401 LOGPROB lastscore;
02402 int mseclen;
02403 boolean ok_p;
02404
02405 backtrellis->framelen = len;
02406
02407
02408
02409
02410
02411 ok_p = TRUE;
02412 if (rejectshortlen > 0) {
02413 mseclen = (float)len * (float)smpPeriod * (float)fshift / 10000.0;
02414 if (mseclen < rejectshortlen) {
02415 ok_p = FALSE;
02416 }
02417 }
02418
02419
02420
02421 if (ok_p) {
02422 bt_relocate_rw(backtrellis);
02423 bt_sort_rw(backtrellis);
02424 if (backtrellis->num == NULL) {
02425 if (backtrellis->framelen > 0) j_printerr("no survived word!\n");
02426 ok_p = FALSE;
02427 }
02428 }
02429
02430
02431
02432 if (verbose_flag && (!progout_flag)) j_printerr("\n");
02433 if (ok_p) {
02434 lastscore = print_1pass_result(backtrellis, len, winfo);
02435 } else {
02436 lastscore = LOG_ZERO;
02437 }
02438
02439 #ifdef USE_NGRAM
02440
02441
02442
02443
02444 #endif
02445
02446 free_nodes();
02447
02448 if (ok_p) {
02449 if (gmm != NULL) {
02450
02451 gmm_end(gmm);
02452 }
02453 }
02454
02455
02456 return(lastscore);
02457 }
02458
02459 #ifdef SP_BREAK_CURRENT_FRAME
02460
02461
02462
02463
02493 void
02494 finalize_segment(BACKTRELLIS *backtrellis, HTK_Param *param, int len)
02495 {
02496 int t;
02497
02498
02499
02500
02501 set_terminal_words(backtrellis);
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515 if (len != param->samplenum) {
02516
02517 VERMES("segmented: processed length=%d\n", len);
02518 VERMES("segmented: next decoding will restart from %d\n", sparea_start);
02519
02520
02521 rest_param = new_param();
02522 memcpy(&(rest_param->header), &(param->header), sizeof(HTK_Param_Header));
02523 rest_param->samplenum = param->samplenum - sparea_start;
02524 rest_param->header.samplenum = rest_param->samplenum;
02525 rest_param->veclen = param->veclen;
02526 rest_param->parvec = (VECT **)mymalloc(sizeof(VECT *) * rest_param->samplenum);
02527
02528 for(t=sparea_start;t<len;t++) {
02529 rest_param->parvec[t-sparea_start] = (VECT *)mymalloc(sizeof(VECT) * rest_param->veclen);
02530 memcpy(rest_param->parvec[t-sparea_start], param->parvec[t], sizeof(VECT) * rest_param->veclen);
02531 }
02532
02533 for(t=len;t<param->samplenum;t++) {
02534 rest_param->parvec[t-sparea_start] = param->parvec[t];
02535 }
02536
02537
02538
02539 param->samplenum = len;
02540 param->parvec = (VECT **)myrealloc(param->parvec, sizeof(VECT *) * param->samplenum);
02541 sp_break_last_nword_allow_override = TRUE;
02542
02543 } else {
02544
02545
02546 rest_param = NULL;
02547
02548 sp_break_last_word = WORD_INVALID;
02549 sp_break_last_nword = WORD_INVALID;
02550 sp_break_last_nword_allow_override = FALSE;
02551 }
02552 }
02553 #endif
02554
02555
02556
02557
02558
02559
02560
02561
02599 void
02600 get_back_trellis(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis,
02601 LOGPROB *backmax)
02602 {
02603 int t;
02604
02605
02606
02607 get_back_trellis_init(param, wchmm, backtrellis);
02608
02609
02610
02611 for (
02612 #ifdef MULTIPATH_VERSION
02613
02614 t = 0
02615 #else
02616
02617 t = 1
02618 #endif
02619 ; t < param->samplenum; t++) {
02620 if (get_back_trellis_proceed(t, param, wchmm, backtrellis
02621 #ifdef MULTIPATH_VERSION
02622 ,FALSE
02623 #endif
02624 ) == FALSE
02625 || catch_intr_flag
02626 || (module_mode && module_wants_terminate())) {
02627
02628
02629
02630
02631 *backmax = finalize_1st_pass(backtrellis, wchmm->winfo, t-1);
02632 #ifdef SP_BREAK_CURRENT_FRAME
02633
02634
02635
02636 finalize_segment(backtrellis, param, t-1);
02637 #endif
02638
02639 return;
02640 }
02641 }
02642
02643
02644 get_back_trellis_end(param, wchmm, backtrellis);
02645
02646
02647 *backmax = finalize_1st_pass(backtrellis, wchmm->winfo, param->samplenum);
02648 #ifdef SP_BREAK_CURRENT_FRAME
02649
02650
02651
02652 finalize_segment(backtrellis, param, param->samplenum);
02653 #endif
02654 }
02655
02656