00001
00052
00053
00054
00055
00056
00057
00058
00059 #include <sent/stddefs.h>
00060 #include <sent/speech.h>
00061 #include <sent/htk_hmm.h>
00062 #include <sent/htk_param.h>
00063 #include <sent/hmm.h>
00064 #include <sent/hmm_calc.h>
00065
00066
00067
00068 #define LOG_UNDEF (LOG_ZERO - 1)
00069
00070
00077 boolean
00078 outprob_cache_init(HMMWork *wrk)
00079 {
00080 wrk->statenum = wrk->OP_hmminfo->totalstatenum;
00081 wrk->outprob_cache = NULL;
00082 wrk->outprob_allocframenum = 0;
00083 wrk->OP_time = -1;
00084 wrk->croot = NULL;
00085 return TRUE;
00086 }
00087
00095 boolean
00096 outprob_cache_prepare(HMMWork *wrk)
00097 {
00098 int s,t;
00099
00100
00101 for (t = 0; t < wrk->outprob_allocframenum; t++) {
00102 for (s = 0; s < wrk->statenum; s++) {
00103 wrk->outprob_cache[t][s] = LOG_UNDEF;
00104 }
00105 }
00106
00107 return TRUE;
00108 }
00109
00116 static void
00117 outprob_cache_extend(HMMWork *wrk, int reqframe)
00118 {
00119 int newnum;
00120 int size;
00121 int t, s;
00122 LOGPROB *tmpp;
00123
00124
00125 if (reqframe < wrk->outprob_allocframenum) return;
00126
00127
00128 newnum = reqframe + 1;
00129 if (newnum < wrk->outprob_allocframenum + OUTPROB_CACHE_PERIOD) newnum = wrk->outprob_allocframenum + OUTPROB_CACHE_PERIOD;
00130 size = (newnum - wrk->outprob_allocframenum) * wrk->statenum;
00131
00132
00133 if (wrk->outprob_cache == NULL) {
00134 wrk->outprob_cache = (LOGPROB **)mymalloc(sizeof(LOGPROB *) * newnum);
00135 } else {
00136 wrk->outprob_cache = (LOGPROB **)myrealloc(wrk->outprob_cache, sizeof(LOGPROB *) * newnum);
00137 }
00138 tmpp = (LOGPROB *)mybmalloc2(sizeof(LOGPROB) * size, &(wrk->croot));
00139
00140 for(t = wrk->outprob_allocframenum; t < newnum; t++) {
00141 wrk->outprob_cache[t] = &(tmpp[(t - wrk->outprob_allocframenum) * wrk->statenum]);
00142 for (s = 0; s < wrk->statenum; s++) {
00143 wrk->outprob_cache[t][s] = LOG_UNDEF;
00144 }
00145 }
00146
00147
00148 wrk->outprob_allocframenum = newnum;
00149 }
00150
00157 void
00158 outprob_cache_free(HMMWork *wrk)
00159 {
00160 if (wrk->croot != NULL) mybfree2(&(wrk->croot));
00161 if (wrk->outprob_cache != NULL) free(wrk->outprob_cache);
00162 }
00163
00164
00183 LOGPROB
00184 outprob_state(HMMWork *wrk, int t, HTK_HMM_State *stateinfo, HTK_Param *param)
00185 {
00186 LOGPROB outp;
00187 int sid;
00188
00189 sid = stateinfo->id;
00190
00191
00192 wrk->OP_state = stateinfo;
00193 wrk->OP_state_id = sid;
00194 wrk->OP_param = param;
00195 if (wrk->OP_time != t) {
00196 wrk->OP_last_time = wrk->OP_time;
00197 wrk->OP_time = t;
00198 wrk->OP_vec = param->parvec[t];
00199 wrk->OP_veclen = param->veclen;
00200
00201 outprob_cache_extend(wrk, t);
00202 wrk->last_cache = wrk->outprob_cache[t];
00203 }
00204
00205
00206 if ((outp = wrk->last_cache[sid]) == LOG_UNDEF) {
00207 outp = wrk->last_cache[sid] = (*(wrk->calc_outprob_state))(wrk);
00208 }
00209 return(outp);
00210 }
00211
00218 void
00219 outprob_cd_nbest_init(HMMWork *wrk, int num)
00220 {
00221 wrk->cd_nbest_maxprobs = (LOGPROB *)mymalloc(sizeof(LOGPROB) * num);
00222 wrk->cd_nbest_maxn = num;
00223 }
00224
00231 void
00232 outprob_cd_nbest_free(HMMWork *wrk)
00233 {
00234 free(wrk->cd_nbest_maxprobs);
00235 }
00236
00247 static LOGPROB
00248 outprob_cd_nbest(HMMWork *wrk, int t, CD_State_Set *lset, HTK_Param *param)
00249 {
00250 LOGPROB prob;
00251 int i, k, n;
00252
00253 n = 0;
00254 for(i=0;i<lset->num;i++) {
00255 prob = outprob_state(wrk, t, lset->s[i], param);
00256
00257 if (prob <= LOG_ZERO) continue;
00258 if (n == 0 || prob <= wrk->cd_nbest_maxprobs[n-1]) {
00259 if (n == wrk->cd_nbest_maxn) continue;
00260 wrk->cd_nbest_maxprobs[n] = prob;
00261 n++;
00262 } else {
00263 for(k=0; k<n; k++) {
00264 if (prob > wrk->cd_nbest_maxprobs[k]) {
00265 memmove(&(wrk->cd_nbest_maxprobs[k+1]), &(wrk->cd_nbest_maxprobs[k]),
00266 sizeof(LOGPROB) * (n - k - ( (n == wrk->cd_nbest_maxn) ? 1 : 0)));
00267 wrk->cd_nbest_maxprobs[k] = prob;
00268 break;
00269 }
00270 }
00271 if (n < wrk->cd_nbest_maxn) n++;
00272 }
00273 }
00274 prob = 0.0;
00275 for(i=0;i<n;i++) {
00276
00277 prob += wrk->cd_nbest_maxprobs[i];
00278 }
00279 return(prob/(float)n);
00280 }
00281
00292 static LOGPROB
00293 outprob_cd_max(HMMWork *wrk, int t, CD_State_Set *lset, HTK_Param *param)
00294 {
00295 LOGPROB maxprob, prob;
00296 int i;
00297
00298 maxprob = LOG_ZERO;
00299 for(i=0;i<lset->num;i++) {
00300 prob = outprob_state(wrk, t, lset->s[i], param);
00301 if (maxprob < prob) maxprob = prob;
00302 }
00303 return(maxprob);
00304 }
00305
00316 static LOGPROB
00317 outprob_cd_avg(HMMWork *wrk, int t, CD_State_Set *lset, HTK_Param *param)
00318 {
00319 LOGPROB sum, p;
00320 int i,j;
00321 sum = 0.0;
00322 j = 0;
00323 for(i=0;i<lset->num;i++) {
00324 p = outprob_state(wrk, t, lset->s[i], param);
00325 if (p > LOG_ZERO) {
00326 sum += p;
00327 j++;
00328 }
00329 }
00330 return(sum/(float)j);
00331 }
00332
00343 LOGPROB
00344 outprob_cd(HMMWork *wrk, int t, CD_State_Set *lset, HTK_Param *param)
00345 {
00346 LOGPROB ret;
00347
00348
00349 switch(wrk->OP_hmminfo->cdset_method) {
00350 case IWCD_AVG:
00351 ret = outprob_cd_avg(wrk, t, lset, param);
00352 break;
00353 case IWCD_MAX:
00354 ret = outprob_cd_max(wrk, t, lset, param);
00355 break;
00356 case IWCD_NBEST:
00357 ret = outprob_cd_nbest(wrk, t, lset, param);
00358 break;
00359 }
00360 return(ret);
00361 }
00362
00363
00374 LOGPROB
00375 outprob(HMMWork *wrk, int t, HMM_STATE *hmmstate, HTK_Param *param)
00376 {
00377 if (hmmstate->is_pseudo_state) {
00378 return(outprob_cd(wrk, t, hmmstate->out.cdset, param));
00379 } else {
00380 return(outprob_state(wrk, t, hmmstate->out.state, param));
00381 }
00382 }