00001
00018
00019
00020
00021
00022
00023
00024
00025 #include <sent/stddefs.h>
00026 #include <sent/htk_hmm.h>
00027
00028 extern char *rdhmmdef_token;
00029
00035 static HTK_HMM_State *
00036 state_new(HTK_HMM_INFO *hmm)
00037 {
00038 HTK_HMM_State *new;
00039
00040 new = (HTK_HMM_State *)mybmalloc2(sizeof(HTK_HMM_State), &(hmm->mroot));
00041
00042 new->name = NULL;
00043 new->mix_num = 0;
00044 new->b = NULL;
00045 new->bweight = NULL;
00046 new->id = 0;
00047 new->next = NULL;
00048
00049 return(new);
00050 }
00051
00058 void
00059 state_add(HTK_HMM_INFO *hmm, HTK_HMM_State *new)
00060 {
00061 HTK_HMM_State *match;
00062
00063
00064 new->next = hmm->ststart;
00065 hmm->ststart = new;
00066
00067 if (new->name != NULL) {
00068
00069 if (hmm->st_root == NULL) {
00070 hmm->st_root = aptree_make_root_node(new);
00071 } else {
00072 match = aptree_search_data(new->name, hmm->st_root);
00073 if (match != NULL && strmatch(match->name, new->name)) {
00074 jlog("Error: rdhmmdef_state: ~s \"%s\" is already defined\n", new->name);
00075 rderr(NULL);
00076 } else {
00077 aptree_add_entry(new->name, new, match->name, &(hmm->st_root));
00078 }
00079 }
00080 }
00081
00082 }
00083
00092 HTK_HMM_State *
00093 state_lookup(HTK_HMM_INFO *hmm, char *keyname)
00094 {
00095 HTK_HMM_State *s;
00096
00097 s = aptree_search_data(keyname, hmm->st_root);
00098 if (s != NULL && strmatch(s->name, keyname)) {
00099 return s;
00100 } else {
00101 return NULL;
00102 }
00103 }
00104
00119 static HTK_HMM_State *
00120 state_read(FILE *fp, HTK_HMM_INFO *hmm)
00121 {
00122 HTK_HMM_State *new;
00123 int mid;
00124 int i;
00125 boolean single_gaussian;
00126
00127 new = state_new(hmm);
00128
00129 if (currentis("NUMMIXES")) {
00130 read_token(fp);
00131 NoTokErr("missing NUMMIXES value");
00132 new->mix_num = atoi(rdhmmdef_token);
00133 read_token(fp);
00134 single_gaussian = FALSE;
00135 } else {
00136 new->mix_num = 1;
00137 single_gaussian = TRUE;
00138 }
00139
00140 if (currentis("TMIX")) {
00141 read_token(fp);
00142
00143 tmix_read(fp, new, hmm);
00144 } else {
00145
00146 new->b = (HTK_HMM_Dens **) mybmalloc2(sizeof(HTK_HMM_Dens *) * new->mix_num, &(hmm->mroot));
00147 new->bweight = (PROB *) mybmalloc2(sizeof(PROB) * new->mix_num, &(hmm->mroot));
00148 for (i=0;i<new->mix_num;i++) {
00149 new->b[i] = NULL;
00150 new->bweight[i] = LOG_ZERO;
00151 }
00152
00153 if (single_gaussian) {
00154 mid = 0;
00155 new->bweight[mid] = 0.0;
00156 new->b[mid] = get_dens_data(fp, hmm);
00157 } else {
00158 for (;;) {
00159 if (!currentis("MIXTURE")) break;
00160 read_token(fp);
00161 NoTokErr("missing MIXTURE id");
00162 mid = atoi(rdhmmdef_token) - 1;
00163 read_token(fp);
00164 NoTokErr("missing MIXTURE weight");
00165 new->bweight[mid] = (PROB)log(atof(rdhmmdef_token));
00166 read_token(fp);
00167 new->b[mid] = get_dens_data(fp, hmm);
00168 }
00169 }
00170 }
00171
00172 return (new);
00173 }
00174
00188 HTK_HMM_State *
00189 get_state_data(FILE *fp, HTK_HMM_INFO *hmm)
00190 {
00191 HTK_HMM_State *tmp;
00192
00193 if (currentis("NUMMIXES")||currentis("MEAN")||currentis("RCLASS")) {
00194
00195 tmp = state_read(fp, hmm);
00196 tmp->name = NULL;
00197 state_add(hmm, tmp);
00198 return tmp;
00199 } else if (currentis("~s")) {
00200
00201 read_token(fp);
00202 NoTokErr("missing state macro name");
00203 tmp = state_lookup(hmm, rdhmmdef_token);
00204 if (tmp == NULL) {
00205 jlog("Error: rdhmmdef_state: ~s \"%s\" not defined\n", rdhmmdef_token);
00206 rderr(NULL);
00207 }
00208 read_token(fp);
00209 return tmp;
00210 } else {
00211 rderr("no state data");
00212 return NULL;
00213 }
00214 }
00215
00216
00217
00225 void
00226 def_state_macro(char *name, FILE *fp, HTK_HMM_INFO *hmm)
00227 {
00228 HTK_HMM_State *new;
00229
00230
00231 new = state_read(fp, hmm);
00232
00233
00234 new->name = name;
00235 state_add(hmm, new);
00236 }