00001
00036
00037
00038
00039
00040
00041
00042
00043 #include <sent/stddefs.h>
00044 #include <sent/htk_param.h>
00045 #include <sent/htk_hmm.h>
00046
00047 #define MAXBUFLEN 4096
00048
00049 char *rdhmmdef_token;
00050 static char *buf = NULL;
00051 static int line;
00052
00053
00054
00060 void
00061 rderr(char *str)
00062 {
00063 if (rdhmmdef_token == NULL) {
00064 jlog("Error: rdhmmdef: %s on end of file\n", str);
00065 } else {
00066 jlog("Error: rdhmmdef: read error at line %d: %s\n", line, (str) ? str : "parse error");
00067 }
00068 jlog_flush();
00069 exit(1);
00070 }
00071
00079 char *
00080 read_token(FILE *fp)
00081 {
00082 if (buf != NULL) {
00083
00084 if ((rdhmmdef_token = mystrtok_quote(NULL, HMMDEF_DELM)) != NULL) {
00085
00086 return rdhmmdef_token;
00087 }
00088 } else {
00089
00090 buf = (char *)mymalloc(MAXBUFLEN);
00091 line = 1;
00092 }
00093
00094 if (getl(buf, MAXBUFLEN, fp) == NULL) {
00095 rdhmmdef_token = NULL;
00096 } else {
00097 rdhmmdef_token = mystrtok_quote(buf, HMMDEF_DELM);
00098 line++;
00099 }
00100 return rdhmmdef_token;
00101 }
00102
00108 static void
00109 conv_log_arc(HTK_HMM_INFO *hmm)
00110 {
00111 HTK_HMM_Trans *tr;
00112 int i,j;
00113 LOGPROB l;
00114
00115 for (tr = hmm->trstart; tr; tr = tr->next) {
00116 for(i=0;i<tr->statenum;i++) {
00117 for(j=0;j<tr->statenum;j++) {
00118 l = tr->a[i][j];
00119 tr->a[i][j] = (l != 0.0) ? (float)log10(l) : LOG_ZERO;
00120 }
00121 }
00122 }
00123 }
00129 void
00130 htk_hmm_inverse_variances(HTK_HMM_INFO *hmm)
00131 {
00132 HTK_HMM_Var *v;
00133 int i;
00134
00135 for (v = hmm->vrstart; v; v = v->next) {
00136 for(i=0;i<v->len;i++) {
00137 v->vec[i] = 1 / v->vec[i];
00138 }
00139 }
00140 }
00141
00142
00154 boolean
00155 rdhmmdef(FILE *fp, HTK_HMM_INFO *hmm)
00156 {
00157 char macrosw;
00158 char *name;
00159
00160
00161 hmm->variance_inversed = FALSE;
00162
00163
00164 read_token(fp);
00165
00166
00167 while (rdhmmdef_token != NULL) {
00168 if (rdhmmdef_token[0] != '~') {
00169 return FALSE;
00170 }
00171 macrosw = rdhmmdef_token[1];
00172 read_token(fp);
00173 switch(macrosw) {
00174 case 'o':
00175 set_global_opt(fp,hmm);
00176 break;
00177 case 't':
00178 name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00179 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00180 read_token(fp);
00181 def_trans_macro(name, fp, hmm);
00182 break;
00183 case 's':
00184 name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00185 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00186 read_token(fp);
00187 def_state_macro(name, fp, hmm);
00188 break;
00189 case 'm':
00190 name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00191 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00192 read_token(fp);
00193 def_dens_macro(name, fp, hmm);
00194 break;
00195 case 'h':
00196 name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00197 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00198 read_token(fp);
00199 def_HMM(name, fp, hmm);
00200 break;
00201 case 'v':
00202 name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00203 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00204 read_token(fp);
00205 def_var_macro(name, fp, hmm);
00206 break;
00207 case 'r':
00208 name = mybstrdup2(rdhmmdef_token, &(hmm->mroot));
00209 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00210 read_token(fp);
00211 def_regtree_macro(name, fp, hmm);
00212 break;
00213 }
00214 }
00215
00216
00217 conv_log_arc(hmm);
00218
00219 jlog("Stat: rdhmmdef: ascii format HMM definition\n");
00220
00221
00222 if (check_all_hmm_limit(hmm)) {
00223 jlog("Stat: rdhmmdef: limit check passed\n");
00224 } else {
00225 jlog("Error: rdhmmdef: cannot handle this HMM due to system limitation\n");
00226 return FALSE;
00227 }
00228
00229
00230 hmm->need_multipath = htk_hmm_has_several_arc_on_edge(hmm);
00231 if (hmm->need_multipath) {
00232 jlog("Stat: rdhmmdef: this HMM requires multipath handling at decoding\n");
00233 } else {
00234 jlog("Stat: rdhmmdef: this HMM does not need multipath handling\n");
00235 }
00236
00237
00238 if (! hmm->variance_inversed) {
00239 htk_hmm_inverse_variances(hmm);
00240 hmm->variance_inversed = TRUE;
00241 }
00242
00243
00244 if (!check_hmm_options(hmm)) {
00245 jlog("Error: rdhmmdef: hmm options check failed\n");
00246 return FALSE;
00247 }
00248
00249
00250
00251 {
00252 HTK_HMM_State *stmp;
00253 int n, max;
00254 n = 0;
00255 max = 0;
00256 for (stmp = hmm->ststart; stmp; stmp = stmp->next) {
00257 if (max < stmp->mix_num) max = stmp->mix_num;
00258 stmp->id = n++;
00259 if (n >= MAX_STATE_NUM) {
00260 jlog("Error: rdhmmdef: too much states in a model > %d\n", MAX_STATE_NUM);
00261 jlog("Error: you can try changing value of MAX_STATE_NUM\n");
00262 return FALSE;
00263 }
00264 }
00265 hmm->totalstatenum = n;
00266 hmm->maxmixturenum = max;
00267 }
00268
00269 {
00270 HTK_HMM_Data *dtmp;
00271 int n, maxlen;
00272 n = 0;
00273 maxlen = 0;
00274 for (dtmp = hmm->start; dtmp; dtmp = dtmp->next) {
00275 if (maxlen < dtmp->state_num) maxlen = dtmp->state_num;
00276 n++;
00277 }
00278 hmm->maxstatenum = maxlen;
00279 hmm->totalhmmnum = n;
00280 }
00281
00282 {
00283 HTK_HMM_Dens *dtmp;
00284 int n = 0;
00285 for (dtmp = hmm->dnstart; dtmp; dtmp = dtmp->next) {
00286 n++;
00287 }
00288 hmm->totalmixnum = n;
00289 }
00290
00291 {
00292 HTK_HMM_Dens *dtmp;
00293 int n = 0;
00294 for (dtmp = hmm->dnstart; dtmp; dtmp = dtmp->next) {
00295 n++;
00296 }
00297 hmm->totalmixnum = n;
00298 }
00299
00300 return(TRUE);
00301 }