Julius 4.2
libsent/src/adin/adin_file.c
説明を見る。
00001 
00062 /*
00063  * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University
00064  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00065  * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology
00066  * All rights reserved
00067  */
00068 
00069 
00070 #include <sent/stddefs.h>
00071 #include <sent/speech.h>
00072 #include <sent/adin.h>
00073 
00074 static FILE *gfp;               
00075 static boolean wav_p;           
00076 static int maxlen;              
00077 static int nowlen;              
00078 
00083 static SP16 pre_data[2];
00084 static boolean has_pre;         
00085 
00086 static unsigned int sfreq;      
00087 
00088 static char speechfilename[MAXPATHLEN]; 
00089 static char *stdin_buf = NULL;
00090 
00091 /* read .wav data with endian conversion */
00092 /* (all .wav datas are in little endian) */
00093 
00105 static boolean
00106 myread(void *buf, size_t unitbyte, int unitnum, FILE *fp)
00107 {
00108   int tmp;
00109   if ((tmp = fread(buf, unitbyte, unitnum, fp)) < unitnum) {
00110     return(FALSE);
00111   }
00112 #ifdef WORDS_BIGENDIAN
00113   swap_bytes(buf, unitbyte, unitnum);
00114 #endif
00115   return(TRUE);
00116 }
00118 #define MYREAD(A,B,C,D)  if (!myread(A, B, C, D)) {jlog("Error: adin_file: file is corrupted\n"); return -1;}
00119 
00133 static boolean
00134 setup_wav(FILE *fp)
00135 {
00136   char dummy[9];
00137   unsigned int i, len;
00138   unsigned short s;
00139 
00140   /* 4 byte: byte num of rest ( = filesize - 8) */
00141   /* --- just skip them */
00142   MYREAD(dummy, 1, 4, fp);
00143   /* first part: WAVE format specifications */
00144   /* 4 byte: "WAVE" */
00145   MYREAD(dummy, 1, 4, fp);
00146   if (dummy[0] != 'W' ||
00147       dummy[1] != 'A' ||
00148       dummy[2] != 'V' ||
00149       dummy[3] != 'E') {
00150     jlog("Error: adin_file: WAVE header not found, file corrupted?\n");
00151     return FALSE;
00152   }
00153   /* format chunk: "fmt " */
00154   MYREAD(dummy, 1, 4, fp);
00155   if (dummy[0] != 'f' ||
00156       dummy[1] != 'm' ||
00157       dummy[2] != 't' ||
00158       dummy[3] != ' ') {
00159     jlog("Error: adin_file: fmt chunk not found, file corrupted?\n");
00160     return FALSE;
00161   }
00162   /* 4byte: byte size of this part */
00163   MYREAD(&len, 4, 1, fp);
00164 
00165   /* 2byte: data format */
00166   MYREAD(&s, 2, 1, fp);
00167   if (s != 1) {
00168     jlog("Error: adin_file: data format != PCM (id=%d)\n", s);
00169     return FALSE;
00170   }
00171   /* 2byte: channel num */
00172   MYREAD(&s, 2, 1, fp);
00173   if (s >= 2) {
00174     jlog("Error: adin_file: channel num != 1 (%d)\n", s);
00175     return FALSE;
00176   }
00177   /* 4byte: sampling rate */
00178   MYREAD(&i, 4, 1, fp);
00179   if (i != sfreq) {
00180     jlog("Error: adin_file: sampling rate != %d (%d)\n", sfreq, i);
00181     return FALSE;
00182   }
00183   /* 4byte: bytes per second */
00184   MYREAD(&i, 4, 1, fp);
00185   if (i != sfreq * sizeof(SP16)) {
00186     jlog("Error: adin_file: bytes per second != %d (%d)\n", sfreq * sizeof(SP16), i);
00187     return FALSE;
00188   }
00189   /* 2bytes: bytes per frame ( = (bytes per sample) x channel ) */
00190   MYREAD(&s, 2, 1, fp);
00191   if (s != 2) {
00192     jlog("Error: adin_file: (bytes per sample) x channel != 2 (%d)\n", s);
00193     return FALSE;
00194   }
00195   /* 2bytes: bits per sample */
00196   MYREAD(&s, 2, 1, fp);
00197   if (s != 16) {
00198     jlog("Error: adin_file: bits per sample != 16 (%d)\n", s);
00199     return FALSE;
00200   }
00201   /* skip rest */
00202   if (len > 16) {
00203     len -= 16;
00204     while (len > 0) {
00205       if (len > 8) {
00206         MYREAD(dummy, 1, 8, fp);
00207         len -= 8;
00208       } else {
00209         MYREAD(dummy, 1, len, fp);
00210         len = 0;
00211       }
00212     }
00213   }
00214   /* end of fmt part */
00215 
00216   /* seek for 'data' part */
00217   while (myread(dummy, 1, 4, fp)) {
00218     MYREAD(&len, 4, 1, fp);
00219     if (dummy[0] == 'd' &&
00220         dummy[1] == 'a' &&
00221         dummy[2] == 't' &&
00222         dummy[3] == 'a') {
00223       break;
00224     }
00225     for (i=0;i<len;i++) myread(dummy, 1, 1, fp);
00226   }
00227   /* ready to read in "data" part --- this is speech data */
00228   maxlen = len / sizeof(SP16);
00229   nowlen = 0;
00230   return TRUE;
00231 }
00232 
00242 static boolean
00243 adin_file_open(char *filename)  /* NULL for standard input */
00244 {
00245   FILE *fp;
00246   char dummy[4];
00247 
00248   if (filename != NULL) {
00249     if ((fp = fopen(filename, "rb")) == NULL) {
00250       jlog("Error: adin_file: failed to open %s\n",filename);
00251       return(FALSE);
00252     }
00253   } else {
00254     fp = stdin;
00255 #if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__MINGW32__)
00256     if (_setmode( _fileno( stdin ), _O_BINARY ) == -1) {
00257       jlog("Error: adin_file: _setmode() failed\n");
00258     }
00259 #endif
00260     if (stdin_buf == NULL) {
00261       stdin_buf = (char *)mymalloc(BUFSIZ);
00262       setvbuf(stdin, stdin_buf, _IOFBF, BUFSIZ);
00263     }
00264   }
00265     
00266   /* check first 4 byte to detect Microsoft WAVE format */
00267   if (fread(dummy, 1, 4, fp) < 4) {
00268     jlog("Error: adin_file: size less than 4 bytes?\n",filename);
00269     fclose(fp);
00270     return(FALSE);
00271   }
00272   if (dummy[0] == 'R' &&
00273       dummy[1] == 'I' &&
00274       dummy[2] == 'F' &&
00275       dummy[3] == 'F') {
00276     /* it's a WAVE file */
00277     wav_p = TRUE;
00278     has_pre = FALSE;
00279     if (setup_wav(fp) == FALSE) {
00280       jlog("Error: adin_file: error in parsing wav header at %s\n",filename);
00281       fclose(fp);
00282       return(FALSE);
00283     }
00284   } else {
00285     /* read as raw format file */
00286     wav_p = FALSE;
00287     memcpy(pre_data, dummy, 4);    /* already read (4/sizeof(SP)) samples */
00288     has_pre = TRUE;
00289   }
00290 
00291   gfp = fp;
00292 
00293   return(TRUE);
00294 }
00295 
00301 static boolean
00302 adin_file_close()
00303 {
00304   FILE *fp;
00305 
00306   fp = gfp;
00307   if (fclose(fp) != 0) {
00308     jlog("Error: adin_file: failed to close file\n");
00309     return FALSE;
00310   }
00311  return TRUE; 
00312 }
00313 
00314 static boolean from_file;       
00315 static FILE *fp_list;           
00316 
00325 boolean
00326 adin_file_standby(int freq, void *arg)
00327 {
00328   char *fname = arg;
00329   if (fname != NULL) {
00330     /* read input filename from file */
00331     if ((fp_list = fopen(fname, "r")) == NULL) {
00332       jlog("Error: adin_file: failed to open %s\n", fname);
00333       return(FALSE);
00334     }
00335     from_file = TRUE;
00336   } else {
00337     /* read filename from stdin */
00338     from_file = FALSE;
00339   }
00340   /* store sampling frequency */
00341   sfreq = freq;
00342   
00343   return(TRUE);
00344 }
00345 
00357 boolean
00358 adin_file_begin(char *filename)
00359 {
00360   boolean readp;
00361 
00362   if (filename != NULL) {
00363     /* open the file and exit with its status */
00364     if (adin_file_open(filename) == FALSE) {
00365       jlog("Error: adin_file: failed to read speech data: \"%s\"\n", filename);
00366       return FALSE;
00367     }
00368     jlog("Stat: adin_file: input speechfile: %s\n", filename);
00369     strcpy(speechfilename, filename);
00370     return TRUE;
00371   }
00372 
00373   /* ready to read next input */
00374   readp = FALSE;
00375   while(readp == FALSE) {
00376     if (from_file) {
00377       /* read file name from listfile */
00378       do {
00379         if (getl_fp(speechfilename, MAXPATHLEN, fp_list) == NULL) { /* end of input */
00380           fclose(fp_list);
00381           return(FALSE); /* end of input */
00382         }
00383       } while (speechfilename[0] == '#'); /* skip comment */
00384     } else {
00385       /* read file name from stdin */
00386       if (get_line_from_stdin(speechfilename, MAXPATHLEN, "enter filename->") == NULL) {
00387         return (FALSE); /* end of input */
00388       }
00389     }
00390     /* open input file */
00391     if (adin_file_open(speechfilename) == FALSE) {
00392       jlog("Error: adin_file: failed to read speech data: \"%s\"\n", speechfilename);
00393     } else {
00394       jlog("Stat: adin_file: input speechfile: %s\n", speechfilename);
00395       readp = TRUE;
00396     }
00397   }
00398   return TRUE;
00399 }
00400 
00409 int
00410 adin_file_read(SP16 *buf, int sampnum)
00411 {
00412   FILE *fp;
00413   int cnt;
00414 
00415   fp = gfp;
00416   
00417   if (wav_p) {
00418     cnt = fread(buf, sizeof(SP16), sampnum, fp);
00419     if (cnt == 0) {
00420       if (feof(fp)) return -1; /* EOF */
00421       if (ferror(fp)) {
00422         jlog("Error: adin_file: an error occured while reading file\n");
00423         adin_file_close();
00424         return -2; /* error */
00425       }
00426     }
00427     if (nowlen + cnt > maxlen) {
00428       cnt = maxlen - nowlen;
00429     }
00430     nowlen += cnt;
00431   } else {
00432     if (has_pre) {
00433       buf[0] = pre_data[0]; buf[1] = pre_data[1];
00434       has_pre = FALSE;
00435       cnt = fread(&(buf[2]), sizeof(SP16), sampnum - 2, fp);
00436       if (cnt == 0) {
00437         if (feof(fp)) return -1; /* EOF */
00438         if (ferror(fp)) {
00439           jlog("Error: adin_file: an error occured file reading file\n");
00440           adin_file_close();
00441           return -2; /* error */
00442         }
00443       }
00444       cnt += 2;
00445     } else {
00446       cnt = fread(buf, sizeof(SP16), sampnum, fp);
00447       if (cnt == 0) {
00448         if (feof(fp)) return -1; /* EOF */
00449         if (ferror(fp)) {
00450           jlog("Error: adin_file: an error occured file reading file\n");
00451           adin_file_close();
00452           return -2; /* error */
00453         }
00454       }
00455     }
00456   }
00457   /* all .wav data are in little endian */
00458   /* assume .raw data are in big endian */
00459 #ifdef WORDS_BIGENDIAN
00460   if (wav_p) swap_sample_bytes(buf, cnt);
00461 #else
00462   if (!wav_p) swap_sample_bytes(buf, cnt);
00463 #endif
00464   return cnt;
00465 }
00466 
00472 boolean
00473 adin_file_end()
00474 {
00475   /* nothing needed */
00476   adin_file_close();
00477   return TRUE;
00478 }
00479 
00488 boolean
00489 adin_stdin_standby(int freq, void *arg)
00490 {
00491   /* store sampling frequency */
00492   sfreq = freq;
00493   return(TRUE);
00494 }
00495 
00503 boolean
00504 adin_stdin_begin(char *pathname)
00505 {
00506   if (feof(stdin)) {            /* already reached the end of input stream */
00507     jlog("Error: adin_stdin: stdin reached EOF\n");
00508     return FALSE;               /* terminate search here */
00509   } else {
00510     /* open input stream */
00511     if (adin_file_open(NULL) == FALSE) {
00512       jlog("Error: adin_stdin: failed to read speech data from stdin\n");
00513       return FALSE;
00514     }
00515     jlog("Stat: adin_stdin: reading wavedata from stdin...\n");
00516   }
00517   return TRUE;
00518 }
00519 
00528 int
00529 adin_stdin_read(SP16 *buf, int sampnum)
00530 {
00531   int cnt;
00532 
00533   if (wav_p) {
00534     cnt = fread(buf, sizeof(SP16), sampnum, stdin);
00535     if (cnt == 0) {
00536       if (feof(stdin)) return -1; /* EOF */
00537       if (ferror(stdin)) {
00538         jlog("Error: adin_stdin: an error occured while reading stdin\n");
00539         return -2; /* error */
00540       }
00541     }
00542   } else {
00543     if (has_pre) {
00544       buf[0] = pre_data[0]; buf[1] = pre_data[1];
00545       has_pre = FALSE;
00546       cnt = fread(&(buf[2]), sizeof(SP16), sampnum - 2, stdin);
00547       if (cnt == 0) {
00548         if (feof(stdin)) return -1; /* EOF */
00549         if (ferror(stdin)) {
00550           jlog("Error: adin_stdin: an error occured while reading stdin\n");
00551           return -2; /* error */
00552         }
00553       }
00554       cnt += 2;
00555     } else {
00556       cnt = fread(buf, sizeof(SP16), sampnum, stdin);
00557       if (cnt == 0) {
00558         if (feof(stdin)) return -1; /* EOF */
00559         if (ferror(stdin)) {
00560           jlog("Error: adin_stdin: an error occured while reading stdin\n");
00561           return -2; /* error */
00562         }
00563       }
00564     }
00565   }
00566 
00567   /* all .wav data are in little endian */
00568   /* assume .raw data are in big endian */
00569 #ifdef WORDS_BIGENDIAN
00570   if (wav_p) swap_sample_bytes(buf, cnt);
00571 #else
00572   if (!wav_p) swap_sample_bytes(buf, cnt);
00573 #endif
00574   return cnt;
00575 }
00576 
00584 char *
00585 adin_file_get_current_filename()
00586 {
00587   return(speechfilename);
00588 }
00596 char *
00597 adin_stdin_input_name()
00598 {
00599   return("stdin");
00600 }