00001
00018
00019
00020
00021
00022
00023
00024
00025 #include <julius/julius.h>
00026
00027 #define PHSTEP 10
00028
00029
00080 static HMM_Logical **
00081 new_str2phseq(char *str, HTK_HMM_INFO *hmminfo, int *len_ret)
00082 {
00083 char **tokens;
00084 boolean *word_end;
00085 int phnum;
00086 boolean word_mode = FALSE;
00087 HMM_Logical **new;
00088 static char buf[MAX_HMMNAME_LEN];
00089
00090
00091 {
00092 char *p;
00093 int tokenmax;
00094 tokenmax = PHSTEP;
00095 tokens = (char **)mymalloc(sizeof(char *) * tokenmax);
00096 word_end = (boolean *)mymalloc(sizeof(boolean) * tokenmax);
00097 phnum = 0;
00098 for(p = strtok(str, DELM); p; p = strtok(NULL, DELM)) {
00099 if (strmatch(p, "|")) {
00100 word_mode = TRUE;
00101 if (phnum > 0) word_end[phnum-1] = TRUE;
00102 continue;
00103 }
00104 if (phnum >= tokenmax) {
00105 tokenmax += PHSTEP;
00106 tokens = (char **)myrealloc(tokens, sizeof(char *) * tokenmax);
00107 word_end = (boolean *)myrealloc(word_end, sizeof(boolean) * tokenmax);
00108 }
00109 tokens[phnum] = strcpy((char *)mymalloc(strlen(p)+1), p);
00110 word_end[phnum] = FALSE;
00111 phnum++;
00112 }
00113 if (phnum == 0) {
00114 jlog("ERROR: hmm_check: no phone specified\n");
00115 printf("ERROR: hmm_check: no phone specified\n");
00116 new = NULL;
00117 goto spend;
00118 }
00119 word_end[phnum-1] = TRUE;
00120 }
00121
00122 {
00123 BASEPHONE *ph;
00124 int i;
00125 boolean ok_flag = TRUE;
00126 for (i=0;i<phnum;i++) {
00127 ph = aptree_search_data(tokens[i], hmminfo->basephone.root);
00128 if (ph == NULL || ! strmatch(ph->name, tokens[i])) {
00129 jlog("ERROR: hmm_check: %2d - unknown phone \"%s\"\n", i+1, tokens[i]);
00130 printf("ERROR: hmm_check: %2d - unknown phone \"%s\"\n", i+1, tokens[i]);
00131 ok_flag = FALSE;
00132 continue;
00133 }
00134 }
00135 if (! ok_flag) {
00136 jlog("ERROR: hmm_check: unknown phone(s)\n");
00137 printf("ERROR: hmm_check: unknown phone(s)\n");
00138 new = NULL;
00139 goto spend;
00140 }
00141 }
00142
00143
00144 {
00145 int i;
00146 char *hmmstr;
00147 HMM_Logical *lg;
00148 boolean ok_flag = TRUE;
00149
00150 new = (HMM_Logical **)mymalloc(sizeof(HMM_Logical *) * phnum);
00151
00152
00153
00154 printf("\n id original logical physical/pseudo\n");
00155 printf(" -------------------------------------------------\n");
00156
00157
00158 if (hmminfo->is_triphone) {
00159 cycle_triphone(NULL);
00160 cycle_triphone(tokens[0]);
00161 for (i = 0; i < phnum; i++) {
00162 if (i < phnum - 1) {
00163 hmmstr = cycle_triphone(tokens[i+1]);
00164 } else {
00165 hmmstr = cycle_triphone_flush();
00166 }
00167 lg = htk_hmmdata_lookup_logical(hmminfo, hmmstr);
00168 if (lg == NULL) {
00169 if (word_mode) {
00170 if (i > 0 && word_end[i-1]) {
00171 if (word_end[i]) {
00172 center_name(hmmstr, buf);
00173 } else {
00174 rightcenter_name(hmmstr, buf);
00175 }
00176 } else if (word_end[i]) {
00177 leftcenter_name(hmmstr, buf);
00178 }
00179 lg = htk_hmmdata_lookup_logical(hmminfo, buf);
00180 if (lg == NULL) {
00181 jlog("ERROR: hmm_check: no defined/pseudo HMM for \"%s\"??\n", buf);
00182 printf("ERROR: hmm_check: no defined/pseudo HMM for \"%s\"??\n", buf);
00183 ok_flag = FALSE;
00184 continue;
00185 }
00186 if (lg->is_pseudo) {
00187 printf(" %2d: %11s -> (pseudo) -> {%s}\n", i+1, hmmstr, lg->body.pseudo->name);
00188 } else {
00189 printf(" %2d: %11s -> %8s -> [%s]\n", i+1, hmmstr, lg->name, lg->body.defined->name);
00190 }
00191 } else {
00192 jlog("ERROR: hmm_check: UNKNOWN %2d: (%s)\n", i+1, hmmstr);
00193 printf("ERROR: hmm_check: UNKNOWN %2d: (%s)\n", i+1, hmmstr);
00194 ok_flag = FALSE;
00195 continue;
00196 }
00197 } else {
00198 if (lg->is_pseudo) {
00199 printf(" %2d: %11s -> (pseudo) -> {%s}\n", i+1, hmmstr, lg->body.pseudo->name);
00200 } else {
00201 printf(" %2d: %11s -> %8s -> [%s]\n", i+1, hmmstr, " ", lg->body.defined->name);
00202 }
00203 }
00204 new[i] = lg;
00205 }
00206 } else {
00207 for (i = 0; i < phnum; i++) {
00208 lg = htk_hmmdata_lookup_logical(hmminfo, tokens[i]);
00209 if (lg == NULL) {
00210 jlog("ERROR: hmm_check: %2d - unknown logical HMM \"%s\"\n", i+1, tokens[i]);
00211 printf("ERROR: hmm_check: %2d - unknown logical HMM \"%s\"\n", i+1, tokens[i]);
00212 ok_flag = FALSE;
00213 continue;
00214 }
00215 new[i] = lg;
00216 }
00217 }
00218 if (ok_flag) {
00219 printf("succeeded\n");
00220 } else {
00221 jlog("ERROR: hmm_check: failed\n");
00222 printf("failed\n");
00223 free(new);
00224 new = NULL;
00225 goto spend;
00226 }
00227
00228 }
00229
00230 spend:
00231 {
00232 int i;
00233 for(i=0;i<phnum;i++) {
00234 free(tokens[i]);
00235 }
00236 free(tokens);
00237 free(word_end);
00238 }
00239
00240 *len_ret = phnum;
00241
00242 return new;
00243 }
00244
00259 static boolean
00260 test_expand_triphone(HTK_HMM_INFO *hmminfo)
00261 {
00262 char *buf;
00263 int newline;
00264 HMM_Logical **phseq;
00265 int phlen;
00266 boolean flag = FALSE;
00267
00268 buf = (char *)mymalloc(4096);
00269 for(;;) {
00270
00271 printf(">>> input phone sequence (word delimiter is `|', blank to return)\n");
00272 if (fgets(buf, 4096, stdin) == NULL) {
00273 flag = TRUE;
00274 break;
00275 }
00276 newline = strlen(buf)-1;
00277 if (buf[newline] == '\n') buf[newline] = '\0';
00278 if (buf[0] == '\0') break;
00279
00280 phseq = new_str2phseq(buf, hmminfo, &phlen);
00281 free(phseq);
00282 }
00283 free(buf);
00284 return flag;
00285 }
00286
00302 void
00303 hmm_check(RecogProcess *r)
00304 {
00305 boolean endflag;
00306 static char cmd[MAX_HMMNAME_LEN];
00307 int newline;
00308
00309 printf("*************************************************\n");
00310 printf("******** TRIPHONE COHERENCE CHECK MODE ********\n");
00311 printf("*************************************************\n");
00312
00313 printf("hmmdefs=%s\n", r->am->config->hmmfilename);
00314 if (r->am->config->mapfilename != NULL) {
00315 printf("hmmlist=%s\n", r->am->config->mapfilename);
00316 }
00317 printf("dict=%s\n", r->lm->config->dictfilename);
00318 printf("headsil = "); put_voca(stdout, r->lm->winfo, r->lm->winfo->head_silwid);
00319 printf("tailsil = "); put_voca(stdout, r->lm->winfo, r->lm->winfo->tail_silwid);
00320
00321 if (make_base_phone(r->am->hmminfo, r->lm->winfo) == FALSE) {
00322 jlog("ERROR: hmm_check: error in making base phone list\n");
00323 printf("ERROR: hmm_check: error in making base phone list\n");
00324 return;
00325 }
00326
00327 print_phone_info(stdout, r->am->hmminfo);
00328
00329 for(endflag = FALSE; endflag == FALSE;) {
00330 printf("===== command (\"H\" for help) > ");
00331 if (fgets(cmd, MAX_HMMNAME_LEN, stdin) == NULL) break;
00332 newline = strlen(cmd)-1;
00333 if (cmd[newline] == '\n') cmd[newline] = '\0';
00334 if (cmd[0] == '\0') continue;
00335
00336 switch(cmd[0]) {
00337 case 'a':
00338
00339 test_interword_triphone(r->am->hmminfo, r->lm->winfo);
00340 break;
00341 case 'c':
00342
00343 endflag = test_expand_triphone(r->am->hmminfo);
00344 break;
00345 case 'i':
00346
00347 printf("hmmdefs=%s\n", r->am->config->hmmfilename);
00348 if (r->am->config->mapfilename != NULL) {
00349 printf("hmmlist=%s\n", r->am->config->mapfilename);
00350 }
00351 printf("dict=%s\n", r->lm->config->dictfilename);
00352 printf("headsil = "); put_voca(stdout, r->lm->winfo, r->lm->winfo->head_silwid);
00353 printf("tailsil = "); put_voca(stdout, r->lm->winfo, r->lm->winfo->tail_silwid);
00354 print_phone_info(stdout, r->am->hmminfo);
00355 break;
00356 case 'p':
00357
00358 print_all_basephone_name(&(r->am->hmminfo->basephone));
00359 break;
00360 case 'd':
00361
00362 print_all_basephone_detail(&(r->am->hmminfo->basephone));
00363 break;
00364 case 'q':
00365
00366 endflag = TRUE;
00367 break;
00368 default:
00369 printf("COMMANDS:\n");
00370 printf(" info --- output HMM information\n");
00371 printf(" conv --- try HMM conversion for given phone sequence\n");
00372 printf(" phonelist --- print base phone list\n");
00373 printf(" all --- check if all possible IW-triphone is covered\n");
00374 printf(" quit --- quit\n");
00375 break;
00376 }
00377 }
00378 printf("*************************************************\n");
00379 printf("***** END OF TRIPHONE COHERENCE CHECK MODE ****\n");
00380 printf("*************************************************\n");
00381 }
00382