julius/hmm_check.c

説明を見る。
00001 
00017 /*
00018  * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University
00019  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00020  * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology
00021  * All rights reserved
00022  */
00023 
00024 #include <julius.h>
00025 
00026 #define PHSTEP 10               
00027 
00028 
00079 static HMM_Logical **
00080 new_str2phseq(char *str, HTK_HMM_INFO *hmminfo, int *len_ret)
00081 {
00082   char **tokens;
00083   boolean *word_end;
00084   int phnum;
00085   boolean word_mode = FALSE;
00086   HMM_Logical **new;
00087   static char buf[MAX_HMMNAME_LEN];
00088   
00089   /* read in string and divide into token unit */
00090   {
00091     char *p;
00092     int tokenmax;
00093     tokenmax = PHSTEP;
00094     tokens = (char **)mymalloc(sizeof(char *) * tokenmax);
00095     word_end = (boolean *)mymalloc(sizeof(boolean) * tokenmax);
00096     phnum = 0;
00097     for(p = first_token(str); p; p = next_token_if_any()) {
00098       if (strmatch(p, "|")) {
00099         word_mode = TRUE;
00100         if (phnum > 0) word_end[phnum-1] = TRUE;
00101         continue;
00102       }
00103       if (phnum >= tokenmax) {
00104         tokenmax += PHSTEP;
00105         tokens = (char **)myrealloc(tokens, sizeof(char *) * tokenmax);
00106         word_end = (boolean *)myrealloc(word_end, sizeof(boolean) * tokenmax);
00107       }
00108       tokens[phnum] = strcpy((char *)mymalloc(strlen(p)+1), p);
00109       word_end[phnum] = FALSE;
00110       phnum++;
00111     }
00112     if (phnum == 0) {
00113       j_printf("failed: no phone specified\n");
00114       new = NULL;
00115       goto spend;
00116     }
00117     word_end[phnum-1] = TRUE;
00118   }
00119   /* check if the phonemes exist in basephone list */
00120   {
00121     BASEPHONE *ph;
00122     int i;
00123     boolean ok_flag = TRUE;
00124     for (i=0;i<phnum;i++) {
00125       ph = aptree_search_data(tokens[i], hmminfo->basephone.root);
00126       if (! strmatch(ph->name, tokens[i])) {
00127         j_printf("         %2d: unknown phone \"%s\"\n", i+1, tokens[i]);
00128         ok_flag = FALSE;
00129         continue;
00130       }
00131     }
00132     if (! ok_flag) {
00133       j_printf("failed\n");
00134       new = NULL;
00135       goto spend;
00136     }
00137   }
00138   /* token -> original logical name -> logical HMM -> physical/pseudo phone */
00139   /* cross-word conversion and fallback to bi/mono-phone is also considered */
00140   {
00141     int i;
00142     char *hmmstr;
00143     HMM_Logical *lg;
00144     boolean ok_flag = TRUE;
00145 
00146     new = (HMM_Logical **)mymalloc(sizeof(HMM_Logical *) * phnum);
00147 
00148     /* original logical name, applied logical HMM name (defined by HMMList),
00149        and the actual physical/pseudo HMM name (defined in hmmdefs) */
00150     j_printf("\n  id     original   logical    physical/pseudo\n");
00151     j_printf(" -------------------------------------------------\n");
00152 
00153 
00154     if (hmminfo->is_triphone) {
00155       cycle_triphone(NULL);
00156       cycle_triphone(tokens[0]);
00157       for (i = 0; i < phnum; i++) {
00158         if (i < phnum - 1) {
00159           hmmstr = cycle_triphone(tokens[i+1]);
00160         } else {
00161           hmmstr = cycle_triphone_flush();
00162         }
00163         lg = htk_hmmdata_lookup_logical(hmminfo, hmmstr);
00164         if (lg == NULL) {
00165           if (word_mode) {
00166             if (i > 0 && word_end[i-1]) {
00167               if (word_end[i]) {
00168                 center_name(hmmstr, buf);
00169               } else {
00170                 rightcenter_name(hmmstr, buf);
00171               }
00172             } else if (word_end[i]) {
00173               leftcenter_name(hmmstr, buf);
00174             }
00175             lg = htk_hmmdata_lookup_logical(hmminfo, buf);
00176             if (lg == NULL) {
00177               j_printf("InternalError: no defined/pseudo HMM for \"%s\"??\n", buf);
00178               ok_flag = FALSE;
00179               continue;
00180             }
00181             if (lg->is_pseudo) {
00182               j_printf("  %2d: %11s -> (pseudo) -> {%s}\n", i+1, hmmstr, lg->body.pseudo->name);
00183             } else {
00184               j_printf("  %2d: %11s -> %8s -> [%s]\n", i+1, hmmstr, lg->name, lg->body.defined->name);
00185             }
00186           } else {
00187             j_printf(" UNKNOWN %2d: (%s)\n", i+1, hmmstr);
00188             ok_flag = FALSE;
00189             continue;
00190           }
00191         } else {
00192           if (lg->is_pseudo) {
00193             j_printf("  %2d: %11s -> (pseudo) -> {%s}\n", i+1, hmmstr, lg->body.pseudo->name);
00194           } else {
00195             j_printf("  %2d: %11s -> %8s -> [%s]\n", i+1, hmmstr, " ", lg->body.defined->name);
00196           }
00197         }
00198         new[i] = lg;
00199       }
00200     } else {
00201       for (i = 0; i < phnum; i++) {
00202         lg = htk_hmmdata_lookup_logical(hmminfo, tokens[i]);
00203         if (lg == NULL) {
00204           j_printf("%2d: unknown logical HMM \"%s\"\n", i+1, tokens[i]);
00205           ok_flag = FALSE;
00206           continue;
00207         }
00208         new[i] = lg;
00209       }
00210     }
00211     if (ok_flag) {
00212       j_printf("succeeded\n");
00213     } else {
00214       j_printf("failed\n");
00215       free(new);
00216       new = NULL;
00217       goto spend;
00218     }
00219       
00220   }
00221 
00222  spend:
00223   {
00224     int i;
00225     for(i=0;i<phnum;i++) {
00226       free(tokens[i]);
00227     }
00228     free(tokens);
00229     free(word_end);
00230   }
00231 
00232   *len_ret = phnum;
00233 
00234   return new;
00235 }
00236 
00251 static boolean
00252 test_expand_triphone(HTK_HMM_INFO *hmminfo)
00253 {
00254   char *buf;
00255   int newline;
00256   HMM_Logical **phseq;
00257   int phlen;
00258   boolean flag = FALSE;
00259 
00260   buf = (char *)mymalloc(4096);
00261   for(;;) {
00262     /* read in phoneme sequence from stdin */
00263     j_printf(">>> input phone sequence (word delimiter is `|', blank to return)\n");
00264     if (fgets(buf, 4096, stdin) == NULL) {
00265       flag = TRUE;
00266       break;
00267     }
00268     newline = strlen(buf)-1;    /* chop newline */
00269     if (buf[newline] == '\n') buf[newline] = '\0';
00270     if (buf[0] == '\0') break;
00271     /* convert string to phseq and output */
00272     phseq = new_str2phseq(buf, hmminfo, &phlen);
00273     free(phseq);
00274   }
00275   free(buf);
00276   return flag;
00277 }
00278 
00293 void
00294 hmm_check(HTK_HMM_INFO *hmminfo, WORD_INFO *winfo)
00295 {
00296   boolean endflag;
00297   static char cmd[MAX_HMMNAME_LEN];
00298   int newline;
00299   
00300   j_printf("\n\n");
00301   j_printf("*************************************************\n");
00302   j_printf("********  TRIPHONE COHERENCE CHECK MODE  ********\n");
00303   j_printf("*************************************************\n");
00304   j_printf("\n");
00305 
00306   j_printf("hmmdefs=%s\n", hmmfilename);
00307   if (mapfilename != NULL) {
00308     j_printf("hmmlist=%s\n", mapfilename);
00309   }
00310   j_printf("dict=%s\n", dictfilename);
00311   j_printf("headsil = "); put_voca(winfo, winfo->head_silwid);
00312   j_printf("tailsil = "); put_voca(winfo, winfo->tail_silwid);
00313 
00314   make_base_phone(hmminfo, winfo);
00315   print_phone_info(hmminfo);
00316 
00317   for(endflag = FALSE; endflag == FALSE;) {
00318     j_printf("===== command (\"H\" for help) > ");
00319     if (fgets(cmd, MAX_HMMNAME_LEN, stdin) == NULL) break;
00320     newline = strlen(cmd)-1;    /* chop newline */
00321     if (cmd[newline] == '\n') cmd[newline] = '\0';
00322     if (cmd[0] == '\0') continue; /* if blank line, read next */
00323 
00324     switch(cmd[0]) {
00325     case 'a':                   /* all */
00326       /* check if logical HMMs cover all possible variants */
00327       test_interword_triphone(hmminfo, winfo);
00328       break;
00329     case 'c':                   /* conv */
00330       /* try to expand triphone for given phoneme sequence */
00331       endflag = test_expand_triphone(hmminfo);
00332       break;
00333     case 'i':                   /* info */
00334       /* output data source */
00335       j_printf("hmmdefs=%s\n", hmmfilename);
00336       if (mapfilename != NULL) {
00337         j_printf("hmmlist=%s\n", mapfilename);
00338       }
00339       j_printf("dict=%s\n", dictfilename);
00340       j_printf("headsil = "); put_voca(winfo, winfo->head_silwid);
00341       j_printf("tailsil = "); put_voca(winfo, winfo->tail_silwid);
00342       print_phone_info(hmminfo);
00343       break;
00344     case 'p':                   /* phonelist */
00345       /* output basephone */
00346       print_all_basephone_name(&(hmminfo->basephone));
00347       break;
00348     case 'd':                   /* phonelist in detail */
00349       /* output basephone */
00350       print_all_basephone_detail(&(hmminfo->basephone));
00351       break;
00352     case 'q':                   /* quit */
00353       /* quit this check mode */
00354       endflag = TRUE;
00355       break;
00356     default:
00357       j_printf("COMMANDS:\n");
00358       j_printf("info      --- output HMM information\n");
00359       j_printf("conv      --- try HMM conversion for given phone sequence\n");
00360       j_printf("phonelist --- print base phone list\n");
00361       j_printf("all       --- check if all possible IW-triphone is covered\n");
00362       j_printf("quit      --- quit\n");
00363       break;
00364     }
00365   }
00366   j_printf("\n");
00367   j_printf("*************************************************\n");
00368   j_printf("*****  END OF TRIPHONE COHERENCE CHECK MODE  ****\n");
00369   j_printf("*************************************************\n");
00370   j_printf("\n");
00371 }

Julianに対してTue Dec 26 12:56:18 2006に生成されました。  doxygen 1.5.0