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