libsent/src/phmm/calc_tied_mix.c

Go to the documentation of this file.
00001 
00028 /*
00029  * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University
00030  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00031  * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology
00032  * All rights reserved
00033  */
00034 
00035 #include <sent/stddefs.h>
00036 #include <sent/speech.h>
00037 #include <sent/htk_hmm.h>
00038 #include <sent/htk_param.h>
00039 #include <sent/hmm.h>
00040 #include <sent/hmm_calc.h>
00041 
00042 
00050 boolean
00051 calc_tied_mix_init(HMMWork *wrk)
00052 {
00053   wrk->mixture_cache = NULL;
00054   wrk->tmix_allocframenum = 0;
00055   wrk->mroot = NULL;
00056   wrk->tmix_last_id = (int *)mymalloc(sizeof(int) * wrk->OP_hmminfo->maxmixturenum);
00057   return TRUE;
00058 }
00059 
00068 boolean
00069 calc_tied_mix_prepare(HMMWork *wrk, int framenum)
00070 {
00071   int bid, t;
00072 
00073   /* clear */
00074   for(t=0;t<wrk->tmix_allocframenum;t++) {
00075     for(bid=0;bid<wrk->OP_hmminfo->codebooknum;bid++) {
00076       wrk->mixture_cache[t][bid][0].score = LOG_ZERO;
00077     }
00078   }
00079 
00080   return TRUE;
00081 }
00082 
00089 static void
00090 calc_tied_mix_extend(HMMWork *wrk, int reqframe)
00091 {
00092   int newnum;
00093   int bid, t, size;
00094   
00095   /* if enough length are already allocated, return immediately */
00096   if (reqframe < wrk->tmix_allocframenum) return;
00097 
00098   /* allocate per certain period */
00099   newnum = reqframe + 1;
00100   if (newnum < wrk->tmix_allocframenum + OUTPROB_CACHE_PERIOD)
00101     newnum = wrk->tmix_allocframenum + OUTPROB_CACHE_PERIOD;
00102 
00103   if (wrk->mixture_cache == NULL) {
00104     wrk->mixture_cache = (MIXCACHE ***)mymalloc(sizeof(MIXCACHE **) * newnum);
00105   } else {
00106     wrk->mixture_cache = (MIXCACHE ***)myrealloc(wrk->mixture_cache, sizeof(MIXCACHE **) * newnum);
00107   }
00108 
00109   size = wrk->OP_gprune_num * wrk->OP_hmminfo->codebooknum;
00110 
00111   for(t = wrk->tmix_allocframenum; t < newnum; t++) {
00112     wrk->mixture_cache[t] = (MIXCACHE **)mybmalloc2(sizeof(MIXCACHE *) * wrk->OP_hmminfo->codebooknum, &(wrk->mroot));
00113     wrk->mixture_cache[t][0] = (MIXCACHE *)mybmalloc2(sizeof(MIXCACHE) * size, &(wrk->mroot));
00114     for(bid=1;bid<wrk->OP_hmminfo->codebooknum;bid++) {
00115       wrk->mixture_cache[t][bid] = &(wrk->mixture_cache[t][0][wrk->OP_gprune_num * bid]);
00116     }
00117     /* clear the new part */
00118     for(bid=0;bid<wrk->OP_hmminfo->codebooknum;bid++) {
00119       wrk->mixture_cache[t][bid][0].score = LOG_ZERO;
00120     }
00121   }
00122 
00123   wrk->tmix_allocframenum = newnum;
00124 }
00125 
00132 void
00133 calc_tied_mix_free(HMMWork *wrk)
00134 {
00135   if (wrk->mroot != NULL) mybfree2(&(wrk->mroot));
00136   if (wrk->mixture_cache != NULL) free(wrk->mixture_cache);
00137   free(wrk->tmix_last_id);
00138 }
00139 
00153 LOGPROB
00154 calc_tied_mix(HMMWork *wrk)
00155 {
00156   GCODEBOOK *book = (GCODEBOOK *)(wrk->OP_state->b);
00157   LOGPROB logprob;
00158   int i, id;
00159   MIXCACHE *ttcache;
00160   MIXCACHE *last_ttcache;
00161   PROB *weight;
00162 
00163   weight = wrk->OP_state->bweight;
00164 
00165 #if 0
00166   if (wrk->OP_last_time != wrk->OP_time) { /* different frame */
00167     if (wrk->OP_time >= 1) {
00168       last_tcache = wrk->mixture_cache[wrk->OP_time-1];
00169     } else {
00170       last_tcache = NULL;
00171     }
00172   }
00173 #endif
00174 
00175   /* extend cache if needed */
00176   calc_tied_mix_extend(wrk, wrk->OP_time);
00177   ttcache = wrk->mixture_cache[wrk->OP_time][book->id];
00178   if (ttcache[0].score != LOG_ZERO) { /* already calced */
00179     /* calculate using cache and weight */
00180     for (i=0;i<wrk->OP_calced_num;i++) {
00181       wrk->OP_calced_score[i] = ttcache[i].score + weight[ttcache[i].id];
00182     }
00183   } else { /* not calced yet */
00184     /* compute Gaussian set */
00185     if (wrk->OP_time >= 1) {
00186       last_ttcache = wrk->mixture_cache[wrk->OP_time-1][book->id];
00187       if (last_ttcache[0].score != LOG_ZERO) {
00188         for(i=0;i<wrk->OP_gprune_num;i++) wrk->tmix_last_id[i] = last_ttcache[i].id;
00189         /* tell last calced best */
00190         (*(wrk->compute_gaussset))(wrk, book->d, book->num, wrk->tmix_last_id);
00191       } else {
00192         (*(wrk->compute_gaussset))(wrk, book->d, book->num, NULL);
00193       }
00194     } else {
00195       (*(wrk->compute_gaussset))(wrk, book->d, book->num, NULL);
00196     }
00197     /* computed Gaussians will be set in:
00198        score ... OP_calced_score[0..OP_calced_num]
00199        id    ... OP_calced_id[0..OP_calced_num] */
00200     /* OP_gprune_num = required, OP_calced_num = actually calced */
00201     /* store to cache */
00202     for (i=0;i<wrk->OP_calced_num;i++) {
00203       id = wrk->OP_calced_id[i];
00204       ttcache[i].id = id;
00205       ttcache[i].score = wrk->OP_calced_score[i];
00206       /* now OP_calced_{id|score} can be used for work area */
00207       wrk->OP_calced_score[i] += weight[id];
00208     }
00209   }
00210   logprob = addlog_array(wrk->OP_calced_score, wrk->OP_calced_num);
00211   if (logprob <= LOG_ZERO) return LOG_ZERO;
00212   return (logprob * INV_LOG_TEN);
00213 }  

Generated on Tue Dec 18 15:59:56 2007 for Julius by  doxygen 1.5.4