00001
00017
00018
00019
00020
00021
00022
00023
00024 #include <sent/stddefs.h>
00025 #include <sent/htk_hmm.h>
00026
00027 extern char *rdhmmdef_token;
00028
00034 static HTK_HMM_State *
00035 state_new()
00036 {
00037 HTK_HMM_State *new;
00038
00039 new = (HTK_HMM_State *)mybmalloc(sizeof(HTK_HMM_State));
00040
00041 new->name = NULL;
00042 new->mix_num = 0;
00043 new->b = NULL;
00044 new->bweight = NULL;
00045 new->id = 0;
00046 new->next = NULL;
00047
00048 return(new);
00049 }
00050
00057 void
00058 state_add(HTK_HMM_INFO *hmm, HTK_HMM_State *new)
00059 {
00060 HTK_HMM_State *match;
00061
00062
00063 new->next = hmm->ststart;
00064 hmm->ststart = new;
00065
00066 if (new->name != NULL) {
00067
00068 if (hmm->st_root == NULL) {
00069 hmm->st_root = aptree_make_root_node(new);
00070 } else {
00071 match = aptree_search_data(new->name, hmm->st_root);
00072 if (strmatch(match->name, new->name)) {
00073 j_printerr("Error: ~s \"%s\" is already defined\n", new->name);
00074 rderr(NULL);
00075 } else {
00076 aptree_add_entry(new->name, new, match->name, &(hmm->st_root));
00077 }
00078 }
00079 }
00080
00081 }
00082
00091 HTK_HMM_State *
00092 state_lookup(HTK_HMM_INFO *hmm, char *keyname)
00093 {
00094 HTK_HMM_State *s;
00095
00096 s = aptree_search_data(keyname, hmm->st_root);
00097 if (strmatch(s->name, keyname)) {
00098 return s;
00099 } else {
00100 return NULL;
00101 }
00102 }
00103
00118 static HTK_HMM_State *
00119 state_read(FILE *fp, HTK_HMM_INFO *hmm)
00120 {
00121 HTK_HMM_State *new;
00122 int mid;
00123 int i;
00124 boolean single_gaussian;
00125
00126 new = state_new();
00127
00128 if (currentis("NUMMIXES")) {
00129 read_token(fp);
00130 NoTokErr("missing NUMMIXES value");
00131 new->mix_num = atoi(rdhmmdef_token);
00132 read_token(fp);
00133 single_gaussian = FALSE;
00134 } else {
00135 new->mix_num = 1;
00136 single_gaussian = TRUE;
00137 }
00138
00139 if (currentis("TMIX")) {
00140 read_token(fp);
00141
00142 tmix_read(fp, new, hmm);
00143 } else {
00144
00145 new->b = (HTK_HMM_Dens **) mybmalloc(sizeof(HTK_HMM_Dens *) * new->mix_num);
00146 new->bweight = (PROB *) mybmalloc(sizeof(PROB) * new->mix_num);
00147 for (i=0;i<new->mix_num;i++) {
00148 new->b[i] = NULL;
00149 new->bweight[i] = LOG_ZERO;
00150 }
00151
00152 if (single_gaussian) {
00153 mid = 0;
00154 new->bweight[mid] = 0.0;
00155 new->b[mid] = get_dens_data(fp, hmm);
00156 } else {
00157 for (;;) {
00158 if (!currentis("MIXTURE")) break;
00159 read_token(fp);
00160 NoTokErr("missing MIXTURE id");
00161 mid = atoi(rdhmmdef_token) - 1;
00162 read_token(fp);
00163 NoTokErr("missing MIXTURE weight");
00164 new->bweight[mid] = (PROB)log(atof(rdhmmdef_token));
00165 read_token(fp);
00166 new->b[mid] = get_dens_data(fp, hmm);
00167 }
00168 }
00169 }
00170
00171 #if 0
00172
00173 for (i=0;i<new->mix_num;i++) {
00174
00175 if (new->b[i] == NULL) {
00176 j_printerr("Warning: lack of mixture component found, use previous insted...\n");
00177 new->b[i] = new->b[i-1];
00178 }
00179 }
00180 #endif
00181
00182
00183 return (new);
00184 }
00185
00199 HTK_HMM_State *
00200 get_state_data(FILE *fp, HTK_HMM_INFO *hmm)
00201 {
00202 HTK_HMM_State *tmp;
00203
00204 if (currentis("NUMMIXES")||currentis("MEAN")||currentis("RCLASS")) {
00205
00206 tmp = state_read(fp, hmm);
00207 tmp->name = NULL;
00208 state_add(hmm, tmp);
00209 return tmp;
00210 } else if (currentis("~s")) {
00211
00212 read_token(fp);
00213 NoTokErr("missing state macro name");
00214 tmp = state_lookup(hmm, rdhmmdef_token);
00215 if (tmp == NULL) {
00216 j_printerr("Error: ~s \"%s\" not defined\n", rdhmmdef_token);
00217 rderr(NULL);
00218 }
00219 read_token(fp);
00220 return tmp;
00221 } else {
00222 rderr("no state data");
00223 return NULL;
00224 }
00225 }
00226
00227
00228
00236 void
00237 def_state_macro(char *name, FILE *fp, HTK_HMM_INFO *hmm)
00238 {
00239 HTK_HMM_State *new;
00240
00241
00242 new = state_read(fp, hmm);
00243
00244
00245 new->name = name;
00246 state_add(hmm, new);
00247 }