00001 00027 /* 00028 * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University 00029 * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology 00030 * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology, Nagoya Institute of Technology 00031 * All rights reserved 00032 */ 00033 00034 #include <sent/stddefs.h> 00035 #include <sent/htk_hmm.h> 00036 #include <sent/htk_param.h> 00037 #include <sent/hmm.h> 00038 #include <sent/gprune.h> 00039 #include "globalvars.h" 00040 00041 00042 /* book cache */ 00043 static MIXCACHE ***mixture_cache = NULL; 00044 static MIXCACHE **tcache; 00045 static MIXCACHE *ttcache; 00046 static int *last_id; 00047 static int allocframenum; 00048 static MIXCACHE **last_tcache; 00049 static MIXCACHE *last_ttcache; 00050 00056 boolean 00057 calc_tied_mix_init() 00058 { 00059 mixture_cache = NULL; 00060 allocframenum = -1; 00061 last_id = (int *)mybmalloc(sizeof(int) * OP_hmminfo->maxmixturenum); 00062 return TRUE; 00063 } 00064 00072 boolean 00073 calc_tied_mix_prepare(int framenum) 00074 { 00075 int bid, t, size; 00076 00077 /* (re)-allocate */ 00078 if (allocframenum < framenum) { 00079 if (mixture_cache != NULL) { 00080 for(t=0;t<allocframenum;t++) { 00081 free(mixture_cache[t][0]); 00082 free(mixture_cache[t]); 00083 } 00084 free(mixture_cache); 00085 } 00086 size = OP_gprune_num * OP_hmminfo->codebooknum; 00087 00088 mixture_cache = (MIXCACHE ***)mymalloc(sizeof(MIXCACHE **) * framenum); 00089 for(t=0;t<framenum;t++) { 00090 mixture_cache[t] = (MIXCACHE **)mymalloc(sizeof(MIXCACHE *) * OP_hmminfo->codebooknum); 00091 mixture_cache[t][0] = (MIXCACHE *)mymalloc(sizeof(MIXCACHE) * size); 00092 for(bid=1;bid<OP_hmminfo->codebooknum;bid++) { 00093 mixture_cache[t][bid] = &(mixture_cache[t][0][OP_gprune_num * bid]); 00094 } 00095 } 00096 allocframenum = framenum; 00097 } 00098 /* clear */ 00099 for(t=0;t<framenum;t++) { 00100 for(bid=0;bid<OP_hmminfo->codebooknum;bid++) { 00101 mixture_cache[t][bid][0].score = LOG_ZERO; 00102 } 00103 } 00104 00105 return TRUE; 00106 } 00107 00119 LOGPROB 00120 calc_tied_mix() 00121 { 00122 GCODEBOOK *book = (GCODEBOOK *)(OP_state->b); 00123 LOGPROB logprob; 00124 int i; 00125 00126 if (OP_last_time != OP_time) { /* different frame */ 00127 tcache = mixture_cache[OP_time]; 00128 if (OP_time >= 1) { 00129 last_tcache = mixture_cache[OP_time-1]; 00130 } else { 00131 last_tcache = NULL; 00132 } 00133 } 00134 ttcache = tcache[book->id]; 00135 if (tcache[book->id][0].score != LOG_ZERO) { /* already calced */ 00136 /* calculate using cache and weight */ 00137 for (i=0;i<OP_calced_num;i++) { 00138 OP_calced_score[i] = ttcache[i].score + OP_state->bweight[ttcache[i].id]; 00139 } 00140 } else { /* not calced yet */ 00141 /* compute Gaussian set */ 00142 if (OP_time >= 1) { 00143 last_ttcache = last_tcache[book->id]; 00144 if (last_ttcache[0].score != LOG_ZERO) { 00145 for(i=0;i<OP_gprune_num;i++) last_id[i] = last_ttcache[i].id; 00146 /* tell last calced best */ 00147 compute_gaussset(book->d, book->num, last_id); 00148 } else { 00149 compute_gaussset(book->d, book->num, NULL); 00150 } 00151 } else { 00152 compute_gaussset(book->d, book->num, NULL); 00153 } 00154 /* computed Gaussians will be set in: 00155 score ... OP_calced_score[0..OP_calced_num] 00156 id ... OP_calced_id[0..OP_calced_num] */ 00157 /* OP_gprune_num = required, OP_calced_num = actually calced */ 00158 /* store to cache */ 00159 for (i=0;i<OP_calced_num;i++) { 00160 ttcache[i].id = OP_calced_id[i]; 00161 ttcache[i].score = OP_calced_score[i]; 00162 /* now OP_calced_{id|score} can be used for work area */ 00163 OP_calced_score[i] += OP_state->bweight[OP_calced_id[i]]; 00164 } 00165 } 00166 logprob = addlog_array(OP_calced_score, OP_calced_num); 00167 if (logprob <= LOG_ZERO) return LOG_ZERO; 00168 return (logprob / LOG_TEN); 00169 }