Julius 4.2
libsent/src/adin/adin_sndfile.c
説明を見る。
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 */