Julius 4.2
|
00001 00067 /* 00068 * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University 00069 * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology 00070 * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology 00071 * All rights reserved 00072 */ 00073 00074 #include <sent/stddefs.h> 00075 #include <sent/speech.h> 00076 #include <sent/adin.h> 00077 00078 #ifdef HAVE_LIBSNDFILE 00079 00080 /* sound header */ 00081 #include <sndfile.h> 00082 00083 static int sfreq; 00084 static SF_INFO sinfo; 00085 static SNDFILE *sp; 00086 static boolean from_file; 00087 static FILE *fp_list; 00088 static char speechfilename[MAXPATHLEN]; 00089 00091 static boolean 00092 check_format(SF_INFO *s) 00093 { 00094 if ((s->format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) { 00095 if (s->samplerate != sfreq) { 00096 jlog("Error: adin_sndfile: sample rate != %d, it's %d Hz data\n", sfreq, s->samplerate); 00097 return FALSE; 00098 } 00099 } 00100 if (s->channels != 1) { 00101 jlog("Error: adin_sndfile: channel num != 1, it has %d channels\n", s->channels); 00102 return FALSE; 00103 } 00104 #ifdef HAVE_LIBSNDFILE_VER1 00105 if ((s->format & SF_FORMAT_SUBMASK) != SF_FORMAT_PCM_16) { 00106 jlog("Error: adin_sndfile: not 16-bit data\n"); 00107 return FALSE; 00108 } 00109 #else 00110 if (s->pcmbitwidth != 16) { 00111 jlog("Error: adin_sndfile: not 16-bit data, it's %d bit\n", s->pcmbitwidth); 00112 return FALSE; 00113 } 00114 #endif 00115 return TRUE; 00116 } 00117 00119 static void 00120 print_format(SF_INFO *s) 00121 { 00122 switch(s->format & SF_FORMAT_TYPEMASK) { 00123 case SF_FORMAT_WAV: jlog("Stat: adin_sndfile: input format = Microsoft WAV\n"); break; 00124 case SF_FORMAT_AIFF: jlog("Stat: adin_sndfile: input format = Apple/SGI AIFF\n"); break; 00125 case SF_FORMAT_AU: jlog("Stat: adin_sndfile: input format = Sun/NeXT AU\n"); break; 00126 #ifndef HAVE_LIBSNDFILE_VER1 00127 case SF_FORMAT_AULE: jlog("Stat: adin_sndfile: input format = DEC AU\n"); break; 00128 #endif 00129 case SF_FORMAT_RAW: jlog("Stat: adin_sndfile: input format = RAW\n"); break; 00130 case SF_FORMAT_PAF: jlog("Stat: adin_sndfile: input format = Ensoniq PARIS\n"); break; 00131 case SF_FORMAT_SVX: jlog("Stat: adin_sndfile: input format = Amiga IFF / SVX8 / SV16\n"); break; 00132 case SF_FORMAT_NIST: jlog("Stat: adin_sndfile: input format = Sphere NIST\n"); break; 00133 #ifdef HAVE_LIBSNDFILE_VER1 00134 case SF_FORMAT_VOC: jlog("Stat: adin_sndfile: input format = VOC file\n"); break; 00135 case SF_FORMAT_IRCAM: jlog("Stat: adin_sndfile: input format = Berkeley/IRCAM/CARL\n"); break; 00136 case SF_FORMAT_W64: jlog("Stat: adin_sndfile: input format = Sonic Foundry's 64bit RIFF/WAV\n"); break; 00137 case SF_FORMAT_MAT4: jlog("Stat: adin_sndfile: input format = Matlab (tm) V4.2 / GNU Octave 2.0\n"); break; 00138 case SF_FORMAT_MAT5: jlog("Stat: adin_sndfile: input format = Matlab (tm) V5.0 / GNU Octave 2.1\n"); break; 00139 #endif 00140 default: jlog("Stat: adin_sndfile: input format = UNKNOWN TYPE\n"); break; 00141 } 00142 switch(s->format & SF_FORMAT_SUBMASK) { 00143 #ifdef HAVE_LIBSNDFILE_VER1 00144 case SF_FORMAT_PCM_U8: jlog("Stat: adin_sndfile: input type = Unsigned 8 bit PCM\n"); break; 00145 case SF_FORMAT_PCM_S8: jlog("Stat: adin_sndfile: input type = Signed 8 bit PCM\n"); break; 00146 case SF_FORMAT_PCM_16: jlog("Stat: adin_sndfile: input type = Signed 16 bit PCM\n"); break; 00147 case SF_FORMAT_PCM_24: jlog("Stat: adin_sndfile: input type = Signed 24 bit PCM\n"); break; 00148 case SF_FORMAT_PCM_32: jlog("Stat: adin_sndfile: input type = Signed 32 bit PCM\n"); break; 00149 case SF_FORMAT_FLOAT: jlog("Stat: adin_sndfile: input type = 32bit float\n"); break; 00150 case SF_FORMAT_DOUBLE: jlog("Stat: adin_sndfile: input type = 64bit float\n"); break; 00151 case SF_FORMAT_ULAW: jlog("Stat: adin_sndfile: input type = U-Law\n"); break; 00152 case SF_FORMAT_ALAW: jlog("Stat: adin_sndfile: input type = A-Law\n"); break; 00153 case SF_FORMAT_IMA_ADPCM: jlog("Stat: adin_sndfile: input type = IMA ADPCM\n"); break; 00154 case SF_FORMAT_MS_ADPCM: jlog("Stat: adin_sndfile: input type = Microsoft ADPCM\n"); break; 00155 case SF_FORMAT_GSM610: jlog("Stat: adin_sndfile: input type = GSM 6.10, \n"); break; 00156 case SF_FORMAT_G721_32: jlog("Stat: adin_sndfile: input type = 32kbs G721 ADPCM\n"); break; 00157 case SF_FORMAT_G723_24: jlog("Stat: adin_sndfile: input type = 24kbs G723 ADPCM\n"); break; 00158 case SF_FORMAT_G723_40: jlog("Stat: adin_sndfile: input type = 40kbs G723 ADPCM\n"); break; 00159 #else 00160 case SF_FORMAT_PCM: jlog("Stat: adin_sndfile: input type = PCM\n"); break; 00161 case SF_FORMAT_FLOAT: jlog("Stat: adin_sndfile: input type = floats\n"); break; 00162 case SF_FORMAT_ULAW: jlog("Stat: adin_sndfile: input type = U-Law\n"); break; 00163 case SF_FORMAT_ALAW: jlog("Stat: adin_sndfile: input type = A-Law\n"); break; 00164 case SF_FORMAT_IMA_ADPCM: jlog("Stat: adin_sndfile: input type = IMA ADPCM\n"); break; 00165 case SF_FORMAT_MS_ADPCM: jlog("Stat: adin_sndfile: input type = Microsoft ADPCM\n"); break; 00166 case SF_FORMAT_PCM_BE: jlog("Stat: adin_sndfile: input type = Big endian PCM\n"); break; 00167 case SF_FORMAT_PCM_LE: jlog("Stat: adin_sndfile: input type = Little endian PCM\n"); break; 00168 case SF_FORMAT_PCM_S8: jlog("Stat: adin_sndfile: input type = Signed 8 bit PCM\n"); break; 00169 case SF_FORMAT_PCM_U8: jlog("Stat: adin_sndfile: input type = Unsigned 8 bit PCM\n"); break; 00170 case SF_FORMAT_SVX_FIB: jlog("Stat: adin_sndfile: input type = SVX Fibonacci Delta\n"); break; 00171 case SF_FORMAT_SVX_EXP: jlog("Stat: adin_sndfile: input type = SVX Exponential Delta\n"); break; 00172 case SF_FORMAT_GSM610: jlog("Stat: adin_sndfile: input type = GSM 6.10, \n"); break; 00173 case SF_FORMAT_G721_32: jlog("Stat: adin_sndfile: input type = 32kbs G721 ADPCM\n"); break; 00174 case SF_FORMAT_G723_24: jlog("Stat: adin_sndfile: input type = 24kbs G723 ADPCM\n"); break; 00175 #endif 00176 default: jlog("Stat: adin_sndfile: input type = UNKNOWN SUBTYPE\n"); break; 00177 } 00178 00179 #ifdef HAVE_LIBSNDFILE_VER1 00180 switch(s->format & SF_FORMAT_ENDMASK) { 00181 case SF_ENDIAN_FILE: jlog("Stat: adin_sndfile: endian = file native endian\n"); break; 00182 case SF_ENDIAN_LITTLE: jlog("Stat: adin_sndfile: endian = forced little endian\n"); break; 00183 case SF_ENDIAN_BIG: jlog("Stat: adin_sndfile: endian = forced big endian\n"); break; 00184 case SF_ENDIAN_CPU: jlog("Stat: adin_sndfile: endian = forced CPU native endian\n"); break; 00185 } 00186 jlog("Stat: adin_sndfile: %d Hz, %d channels\n", s->samplerate, s->channels); 00187 #else 00188 jlog("Stat: adin_sndfile: %d bit, %d Hz, %d channels\n", s->pcmbitwidth, s->samplerate, s->channels); 00189 #endif 00190 } 00191 00201 boolean 00202 adin_sndfile_standby(int freq, void *arg) 00203 { 00204 char *fname = arg; 00205 if (fname != NULL) { 00206 /* read input filename from file */ 00207 if ((fp_list = fopen(fname, "r")) == NULL) { 00208 jlog("Error: adin_sndfile: failed to open %s\n", fname); 00209 return(FALSE); 00210 } 00211 from_file = TRUE; 00212 } else { 00213 /* read filename from stdin */ 00214 from_file = FALSE; 00215 } 00216 /* store sampling frequency */ 00217 sfreq = freq; 00218 00219 return(TRUE); 00220 } 00221 00229 static boolean 00230 adin_sndfile_open(char *filename) 00231 { 00232 #ifndef HAVE_LIBSNDFILE_VER1 00233 sinfo.samplerate = sfreq; 00234 sinfo.pcmbitwidth = 16; 00235 sinfo.channels = 1; 00236 #endif 00237 sinfo.format = 0x0; 00238 if ((sp = 00239 #ifdef HAVE_LIBSNDFILE_VER1 00240 sf_open(filename, SFM_READ, &sinfo) 00241 #else 00242 sf_open_read(filename, &sinfo) 00243 #endif 00244 ) == NULL) { 00245 /* retry assuming raw format */ 00246 sinfo.samplerate = sfreq; 00247 sinfo.channels = 1; 00248 #ifdef HAVE_LIBSNDFILE_VER1 00249 sinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16 | SF_ENDIAN_BIG; 00250 #else 00251 sinfo.pcmbitwidth = 16; 00252 sinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_BE; 00253 #endif 00254 if ((sp = 00255 #ifdef HAVE_LIBSNDFILE_VER1 00256 sf_open(filename, SFM_READ, &sinfo) 00257 #else 00258 sf_open_read(filename, &sinfo) 00259 #endif 00260 ) == NULL) { 00261 sf_perror(sp); 00262 jlog("Error: adin_sndfile: failed to open speech data: \"%s\"\n",filename); 00263 } 00264 } 00265 if (sp == NULL) { /* open failure */ 00266 return FALSE; 00267 } 00268 /* check its format */ 00269 if (! check_format(&sinfo)) { 00270 return FALSE; 00271 } 00272 return TRUE; 00273 } 00274 00286 boolean 00287 adin_sndfile_begin(char *filename) 00288 { 00289 boolean readp; 00290 00291 if (filename != NULL) { 00292 if (adin_sndfile_open(filename) == FALSE) { 00293 jlog("Error: adin_sndfile: invalid format: \"%s\"\n", filename); 00294 print_format(&sinfo); 00295 return FALSE; 00296 } 00297 jlog("Stat: adin_sndfile: input speechfile: %s\n", filename); 00298 print_format(&sinfo); 00299 strcpy(speechfilename, filename); 00300 return TRUE; 00301 } 00302 00303 /* ready to read next input */ 00304 readp = FALSE; 00305 while(readp == FALSE) { 00306 if (from_file) { 00307 /* read file name from listfile */ 00308 do { 00309 if (getl_fp(speechfilename, MAXPATHLEN, fp_list) == NULL) { /* end of input */ 00310 fclose(fp_list); 00311 return(FALSE); /* end of input */ 00312 } 00313 } while (speechfilename[0] == '#'); /* skip comment */ 00314 } else { 00315 /* read file name from stdin */ 00316 if (get_line_from_stdin(speechfilename, MAXPATHLEN, "enter filename->") == NULL) { 00317 return (FALSE); /* end of input */ 00318 } 00319 } 00320 if (adin_sndfile_open(speechfilename) == FALSE) { 00321 jlog("Error: adin_sndfile: invalid format: \"%s\"\n",speechfilename); 00322 print_format(&sinfo); 00323 } else { 00324 jlog("Stat: adin_sndfile: input speechfile: %s\n",speechfilename); 00325 print_format(&sinfo); 00326 readp = TRUE; 00327 } 00328 } 00329 return TRUE; 00330 } 00331 00340 int 00341 adin_sndfile_read(SP16 *buf, int sampnum) 00342 { 00343 int cnt; 00344 00345 cnt = sf_read_short(sp, buf, sampnum); 00346 if (cnt == 0) { /* EOF */ 00347 return -1; 00348 } else if (cnt < 0) { /* error */ 00349 sf_perror(sp); 00350 sf_close(sp); 00351 return -2; /* error */ 00352 } 00353 return cnt; 00354 } 00355 00361 boolean 00362 adin_sndfile_end() 00363 { 00364 /* close files */ 00365 if (sf_close(sp) != 0) { 00366 sf_perror(sp); 00367 jlog("Error: adin_sndfile: failed to close\n"); 00368 return FALSE; 00369 } 00370 return TRUE; 00371 } 00372 00380 char * 00381 adin_sndfile_get_current_filename() 00382 { 00383 return(speechfilename); 00384 } 00385 00386 #endif /* ~HAVE_LIBSNDFILE */