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 }
00121
00122
00128 void
00129 init_hmm(HTK_HMM_INFO *hmm)
00130 {
00131
00132 hmm->opt.stream_info.num = 1;
00133 hmm->opt.cov_type = C_DIAG_C;
00134 hmm->opt.dur_type = D_NULL;
00135
00136 hmm->trstart = NULL;
00137 hmm->vrstart = NULL;
00138 hmm->ststart = NULL;
00139 hmm->dnstart = NULL;
00140 hmm->start = NULL;
00141 hmm->lgstart = NULL;
00142 hmm->physical_root = NULL;
00143 hmm->logical_root = NULL;
00144 hmm->tr_root = NULL;
00145 hmm->vr_root = NULL;
00146 hmm->dn_root = NULL;
00147 hmm->st_root = NULL;
00148 hmm->codebooknum = 0;
00149 hmm->codebook_root = NULL;
00150 hmm->maxcodebooksize = 0;
00151 hmm->totalmixnum = 0;
00152 hmm->totalstatenum = 0;
00153 hmm->totalhmmnum = 0;
00154 hmm->totallogicalnum = 0;
00155 hmm->is_triphone = FALSE;
00156 hmm->is_tied_mixture = FALSE;
00157 hmm->cdset_method = IWCD_NBEST;
00158 hmm->cdmax_num = 3;
00159 hmm->totalpseudonum = 0;
00160 }
00161
00173 boolean
00174 rdhmmdef(FILE *fp, HTK_HMM_INFO *hmm)
00175 {
00176 char macrosw;
00177 char *name;
00178
00179
00180 init_hmm(hmm);
00181
00182
00183 read_token(fp);
00184
00185
00186 while (rdhmmdef_token != NULL) {
00187 if (rdhmmdef_token[0] != '~') {
00188 return FALSE;
00189 }
00190 macrosw = rdhmmdef_token[1];
00191 read_token(fp);
00192 switch(macrosw) {
00193 case 'o':
00194 set_global_opt(fp,hmm);
00195 break;
00196 case 't':
00197 name = mybstrdup(rdhmmdef_token);
00198 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00199 read_token(fp);
00200 def_trans_macro(name, fp, hmm);
00201 break;
00202 case 's':
00203 name = mybstrdup(rdhmmdef_token);
00204 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00205 read_token(fp);
00206 def_state_macro(name, fp, hmm);
00207 break;
00208 case 'm':
00209 name = mybstrdup(rdhmmdef_token);
00210 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00211 read_token(fp);
00212 def_dens_macro(name, fp, hmm);
00213 break;
00214 case 'h':
00215 name = mybstrdup(rdhmmdef_token);
00216 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00217 read_token(fp);
00218 def_HMM(name, fp, hmm);
00219 break;
00220 case 'v':
00221 name = mybstrdup(rdhmmdef_token);
00222 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00223 read_token(fp);
00224 def_var_macro(name, fp, hmm);
00225 break;
00226 case 'r':
00227 name = mybstrdup(rdhmmdef_token);
00228 if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long");
00229 read_token(fp);
00230 def_regtree_macro(name, fp, hmm);
00231 break;
00232 }
00233 }
00234
00235 j_printerr("(ascii)...");
00236
00237
00238 if (check_all_hmm_limit(hmm)) {
00239 j_printerr("limit check passed\n");
00240 } else {
00241 j_error("Error: cannot use this HMM for system limitation.\n");
00242 }
00243
00244 conv_log_arc(hmm);
00245
00246
00247 if (!check_hmm_options(hmm)) {
00248 j_error("hmm options check failed\n");
00249 }
00250
00251
00252
00253 {
00254 HTK_HMM_State *stmp;
00255 int n, max;
00256 n = 0;
00257 max = 0;
00258 for (stmp = hmm->ststart; stmp; stmp = stmp->next) {
00259 if (max < stmp->mix_num) max = stmp->mix_num;
00260 stmp->id = n++;
00261 if (n >= MAX_STATE_NUM) {
00262 j_error("Error: too much states > %d\n", MAX_STATE_NUM);
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 }