00001
00028
00029
00030
00031
00032
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
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
00096 if (reqframe < wrk->tmix_allocframenum) return;
00097
00098
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
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) {
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
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) {
00179
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 {
00184
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
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
00198
00199
00200
00201
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
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 }