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->mixture_cache_num = NULL;
00055 wrk->tmix_allocframenum = 0;
00056 wrk->mroot = NULL;
00057 wrk->tmix_last_id = (int *)mymalloc(sizeof(int) * wrk->OP_hmminfo->maxmixturenum * wrk->OP_nstream);
00058 return TRUE;
00059 }
00060
00069 boolean
00070 calc_tied_mix_prepare(HMMWork *wrk, int framenum)
00071 {
00072 int bid, t;
00073
00074
00075 for(t=0;t<wrk->tmix_allocframenum;t++) {
00076 for(bid=0;bid<wrk->OP_hmminfo->codebooknum;bid++) {
00077 wrk->mixture_cache_num[t][bid] = 0;
00078 }
00079 }
00080
00081 return TRUE;
00082 }
00083
00090 static void
00091 calc_tied_mix_extend(HMMWork *wrk, int reqframe)
00092 {
00093 int newnum;
00094 int bid, t, size;
00095
00096
00097 if (reqframe < wrk->tmix_allocframenum) return;
00098
00099
00100 newnum = reqframe + 1;
00101 if (newnum < wrk->tmix_allocframenum + OUTPROB_CACHE_PERIOD)
00102 newnum = wrk->tmix_allocframenum + OUTPROB_CACHE_PERIOD;
00103
00104 if (wrk->mixture_cache == NULL) {
00105 wrk->mixture_cache = (MIXCACHE ***)mymalloc(sizeof(MIXCACHE **) * newnum);
00106 wrk->mixture_cache_num = (short **)mymalloc(sizeof(short *) * newnum);
00107 } else {
00108 wrk->mixture_cache = (MIXCACHE ***)myrealloc(wrk->mixture_cache, sizeof(MIXCACHE **) * newnum);
00109 wrk->mixture_cache_num = (short **)myrealloc(wrk->mixture_cache_num, sizeof(short *) * newnum);
00110 }
00111
00112 size = wrk->OP_gprune_num * wrk->OP_hmminfo->codebooknum;
00113
00114 for(t = wrk->tmix_allocframenum; t < newnum; t++) {
00115 wrk->mixture_cache[t] = (MIXCACHE **)mybmalloc2(sizeof(MIXCACHE *) * wrk->OP_hmminfo->codebooknum, &(wrk->mroot));
00116 wrk->mixture_cache_num[t] = (short *)mybmalloc2(sizeof(short) * wrk->OP_hmminfo->codebooknum, &(wrk->mroot));
00117 wrk->mixture_cache[t][0] = (MIXCACHE *)mybmalloc2(sizeof(MIXCACHE) * size, &(wrk->mroot));
00118 for(bid=1;bid<wrk->OP_hmminfo->codebooknum;bid++) {
00119 wrk->mixture_cache[t][bid] = &(wrk->mixture_cache[t][0][wrk->OP_gprune_num * bid]);
00120 }
00121
00122 for(bid=0;bid<wrk->OP_hmminfo->codebooknum;bid++) {
00123 wrk->mixture_cache_num[t][bid] = 0;
00124 }
00125 }
00126
00127 wrk->tmix_allocframenum = newnum;
00128 }
00129
00136 void
00137 calc_tied_mix_free(HMMWork *wrk)
00138 {
00139 if (wrk->mroot != NULL) mybfree2(&(wrk->mroot));
00140 if (wrk->mixture_cache_num != NULL) free(wrk->mixture_cache_num);
00141 if (wrk->mixture_cache != NULL) free(wrk->mixture_cache);
00142 free(wrk->tmix_last_id);
00143 wrk->mroot = NULL;
00144 wrk->mixture_cache_num = NULL;
00145 wrk->mixture_cache = NULL;
00146 }
00147
00161 LOGPROB
00162 calc_tied_mix(HMMWork *wrk)
00163 {
00164 GCODEBOOK *book;
00165 LOGPROB logprob, logprobsum;
00166 int i, id;
00167 MIXCACHE *ttcache;
00168 short ttcachenum;
00169 MIXCACHE *last_ttcache;
00170 short last_ttcachenum;
00171 PROB *weight;
00172 PROB stream_weight;
00173 int s;
00174 int num;
00175
00176 logprobsum = 0.0;
00177 for(s=0;s<wrk->OP_nstream;s++) {
00178 book = (GCODEBOOK *)(wrk->OP_state->pdf[s]->b);
00179 weight = wrk->OP_state->pdf[s]->bweight;
00180
00181 if (wrk->OP_state->w) stream_weight = wrk->OP_state->w->weight[s];
00182 else stream_weight = 1.0;
00183
00184 wrk->OP_vec = wrk->OP_vec_stream[s];
00185 wrk->OP_veclen = wrk->OP_veclen_stream[s];
00186
00187 calc_tied_mix_extend(wrk, wrk->OP_time);
00188
00189 ttcache = wrk->mixture_cache[wrk->OP_time][book->id];
00190 ttcachenum = wrk->mixture_cache_num[wrk->OP_time][book->id];
00191
00192 if (ttcachenum > 0) {
00193
00194 for (i=0;i<ttcachenum;i++) {
00195 wrk->OP_calced_score[i] = ttcache[i].score + weight[ttcache[i].id];
00196 }
00197 num = ttcachenum;
00198 } else {
00199
00200
00201
00202
00203 if (wrk->OP_time >= 1) {
00204 last_ttcache = wrk->mixture_cache[wrk->OP_time-1][book->id];
00205 last_ttcachenum = wrk->mixture_cache_num[wrk->OP_time-1][book->id];
00206 if (last_ttcachenum > 0) {
00207 for(i=0;i<last_ttcachenum;i++) wrk->tmix_last_id[i] = last_ttcache[i].id;
00208
00209 (*(wrk->compute_gaussset))(wrk, book->d, book->num, wrk->tmix_last_id, last_ttcachenum);
00210 } else {
00211 (*(wrk->compute_gaussset))(wrk, book->d, book->num, NULL, 0);
00212 }
00213 } else {
00214 (*(wrk->compute_gaussset))(wrk, book->d, book->num, NULL, 0);
00215 }
00216
00217 wrk->mixture_cache_num[wrk->OP_time][book->id] = wrk->OP_calced_num;
00218 for (i=0;i<wrk->OP_calced_num;i++) {
00219 id = wrk->OP_calced_id[i];
00220 ttcache[i].id = id;
00221 ttcache[i].score = wrk->OP_calced_score[i];
00222
00223
00224 wrk->OP_calced_score[i] += weight[id];
00225 }
00226 num = wrk->OP_calced_num;
00227 }
00228
00229 logprob = addlog_array(wrk->OP_calced_score, num);
00230
00231 if (logprob <= LOG_ZERO) continue;
00232
00233 logprobsum += logprob * stream_weight;
00234 }
00235 if (logprobsum == 0.0) return(LOG_ZERO);
00236 if (logprobsum <= LOG_ZERO) return(LOG_ZERO);
00237 return (logprobsum * INV_LOG_TEN);
00238 }
00239
00240
00257 LOGPROB
00258 calc_compound_mix(HMMWork *wrk)
00259 {
00260 HTK_HMM_PDF *m;
00261 GCODEBOOK *book;
00262 LOGPROB logprob, logprobsum;
00263 int i, id;
00264 MIXCACHE *ttcache;
00265 short ttcachenum;
00266 MIXCACHE *last_ttcache;
00267 short last_ttcachenum;
00268 PROB *weight;
00269 PROB stream_weight;
00270 int s;
00271 int num;
00272
00273 logprobsum = 0.0;
00274 for(s=0;s<wrk->OP_nstream;s++) {
00275
00276 if (wrk->OP_state->w) stream_weight = wrk->OP_state->w->weight[s];
00277 else stream_weight = 1.0;
00278 m = wrk->OP_state->pdf[s];
00279
00280 wrk->OP_vec = wrk->OP_vec_stream[s];
00281 wrk->OP_veclen = wrk->OP_veclen_stream[s];
00282 weight = wrk->OP_state->pdf[s]->bweight;
00283 if (m->tmix) {
00284
00285 book = (GCODEBOOK *)(m->b);
00286
00287 calc_tied_mix_extend(wrk, wrk->OP_time);
00288
00289 ttcache = wrk->mixture_cache[wrk->OP_time][book->id];
00290 ttcachenum = wrk->mixture_cache_num[wrk->OP_time][book->id];
00291
00292 if (ttcachenum > 0) {
00293
00294 for (i=0;i<ttcachenum;i++) {
00295 wrk->OP_calced_score[i] = ttcache[i].score + weight[ttcache[i].id];
00296 }
00297 num = ttcachenum;
00298 } else {
00299
00300
00301
00302
00303 if (wrk->OP_time >= 1) {
00304 last_ttcache = wrk->mixture_cache[wrk->OP_time-1][book->id];
00305 last_ttcachenum = wrk->mixture_cache_num[wrk->OP_time-1][book->id];
00306 if (last_ttcachenum > 0) {
00307 for(i=0;i<last_ttcachenum;i++) wrk->tmix_last_id[i] = last_ttcache[i].id;
00308
00309 (*(wrk->compute_gaussset))(wrk, book->d, book->num, wrk->tmix_last_id, last_ttcachenum);
00310 } else {
00311 (*(wrk->compute_gaussset))(wrk, book->d, book->num, NULL, 0);
00312 }
00313 } else {
00314 (*(wrk->compute_gaussset))(wrk, book->d, book->num, NULL, 0);
00315 }
00316
00317 wrk->mixture_cache_num[wrk->OP_time][book->id] = wrk->OP_calced_num;
00318 for (i=0;i<wrk->OP_calced_num;i++) {
00319 id = wrk->OP_calced_id[i];
00320 ttcache[i].id = id;
00321 ttcache[i].score = wrk->OP_calced_score[i];
00322
00323
00324 wrk->OP_calced_score[i] += weight[id];
00325 }
00326 num = wrk->OP_calced_num;
00327 }
00328 } else {
00329
00330 (*(wrk->compute_gaussset))(wrk, m->b, m->mix_num, NULL, 0);
00331
00332 for(i=0;i<wrk->OP_calced_num;i++) {
00333 wrk->OP_calced_score[i] += weight[wrk->OP_calced_id[i]];
00334 }
00335 num = wrk->OP_calced_num;
00336 }
00337
00338 logprob = addlog_array(wrk->OP_calced_score, num);
00339
00340 if (logprob <= LOG_ZERO) continue;
00341
00342 logprobsum += logprob * stream_weight;
00343 }
00344 if (logprobsum == 0.0) return(LOG_ZERO);
00345 if (logprobsum <= LOG_ZERO) return(LOG_ZERO);
00346 return (logprobsum * INV_LOG_TEN);
00347 }