Julius 4.2
julius/record.c
説明を見る。
00001 
00035 /*
00036  * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University
00037  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00038  * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology
00039  * All rights reserved
00040  */
00041 
00042 #include "app.h"
00043 #include <time.h>
00044 
00045 static char *record_dirname = NULL;
00046 
00047 static char rectmpfilename[MAXLINELEN];
00048 static char recordfilename[MAXLINELEN];
00049 static int recordlen;
00050 static FILE *recfile_fp = NULL;
00051 static boolean open_error = FALSE;
00052 
00067 static void
00068 timestring(char *t, int maxlen)
00069 {
00070   time_t timep;
00071   struct tm *lmtm;
00072 
00073   time(&timep);
00074   lmtm = localtime(&timep);
00075 
00076   snprintf ( t, maxlen,"%04d.%02d%02d.%02d%02d%02d", 1900+lmtm->tm_year, 1+lmtm->tm_mon, lmtm->tm_mday, lmtm->tm_hour, lmtm->tm_min, lmtm->tm_sec);
00077 }
00078 
00097 static void
00098 make_record_filename(char *buf, int buflen, char *basename, char *dirname)
00099 {
00100   if (dirname == NULL) {
00101     fprintf(stderr, "no record directory specified??\n");
00102     return;
00103   }
00104   snprintf(buf, buflen,
00105 #if defined(_WIN32) && !defined(__CYGWIN32__)
00106            "%s\\%s.wav"
00107 #else
00108            "%s/%s.wav"
00109 #endif
00110            , dirname, basename);
00111 }
00112 
00127 static void
00128 make_tmp_filename(char *buf, int buflen, char *dirname)
00129 {
00130 #if defined(_WIN32) && !defined(__CYGWIN32__)
00131   snprintf(buf, buflen, "%s\\tmprecord.000", dirname);
00132 #else
00133   snprintf(buf, buflen, "%s/tmprecord.%d", dirname, getpid());
00134 #endif
00135 }  
00136 
00147 static void
00148 record_sample_open(Recog *recog, void *dummy)
00149 {
00150   if (recfile_fp != NULL) {
00151     fprintf(stderr, "Error: record_sample_open: re-opened before closed!\n"); 
00152     return;
00153   }
00154 
00155   make_tmp_filename(rectmpfilename, MAXLINELEN, record_dirname);
00156   if ((recfile_fp = wrwav_open(rectmpfilename, recog->jconf->input.sfreq)) == NULL) {
00157     perror("Error: record_sample_open");
00158     fprintf(stderr, "failed to open \"%s\" (temporary record file)\n", rectmpfilename);
00159     open_error = TRUE;
00160     return;
00161   }
00162 
00163   recordlen = 0;
00164 }
00165 
00180 static void
00181 record_sample_write(Recog *recog, SP16 *speech, int samplenum, void *dummy)
00182 {
00183   static char tstr[20];
00184 
00185   if (recfile_fp == NULL) {
00186     if (! open_error) record_sample_open(recog, dummy);
00187   }
00188 
00189   if (wrwav_data(recfile_fp, speech, samplenum) == FALSE) {
00190     perror("Error: record_sample_write");
00191     fprintf(stderr, "failed to write samples to \"%s\"\n", rectmpfilename);
00192     return;
00193   }
00194 
00195   /* make timestamp of system time when an input begins */
00196   /* the current temporal recording file will be renamed to this time-stamp filename */
00197   if (recordlen == 0) {         /* beginning of recording */
00198     timestring(tstr, 18);
00199   }
00200   make_record_filename(recordfilename, MAXLINELEN, tstr, record_dirname);
00201   
00202   recordlen += samplenum;
00203 }
00204 
00216 static void
00217 record_sample_close(Recog *recog, void *dummy)
00218 {
00219   open_error = FALSE;
00220   if (recfile_fp == NULL) {
00221     fprintf(stderr, "Warning: record_sample_close; file not opened yet!?\n");
00222     return;
00223   }
00224 
00225   if (wrwav_close(recfile_fp) == FALSE) {
00226     perror("Error: record_sample_close");
00227   }
00228   recfile_fp = NULL;
00229 
00230   if (recordlen == 0) {
00231     unlink(rectmpfilename);
00232     if (verbose_flag) {
00233       fprintf(stderr, "No input, not recorded\n");
00234     }
00235     return;
00236   }
00237 
00238   /* now rename the temporary file to time-stamp filename */
00239   if (rename(rectmpfilename, recordfilename) < 0) {
00240     perror("Error: record_sample_close");
00241     fprintf(stderr, "failed to move %s to %s\n", rectmpfilename, recordfilename);
00242     return;
00243   }
00244   if (verbose_flag) {
00245     fprintf(stderr, "recorded to \"%s\" (%d bytes, %.2f sec.)\n", recordfilename, recordlen * sizeof(SP16), (float)recordlen / (float) recog->jconf->input.sfreq);
00246   }
00247 }
00248 
00249 /************************************************************************/
00250 static boolean
00251 opt_record(Jconf *jconf, char *arg[], int argnum)
00252 {
00253   record_dirname = strdup(arg[0]);
00254 #if !defined(_WIN32) || defined(__CYGWIN32__)
00255   if (access(record_dirname, R_OK | W_OK | X_OK) == -1) {
00256     perror("checkdir");
00257     fprintf(stderr, "Error: cannot write to dir %s\n", record_dirname);
00258     return FALSE;
00259   }
00260 #endif
00261   return TRUE;
00262 }
00263 void
00264 record_add_option()
00265 {
00266   j_add_option("-record", 1, 1, "record input waveform to file in dir", opt_record);
00267 }
00268 
00269 /************************************************************************/
00270 void
00271 record_setup(Recog *recog, void *data)
00272 {
00273   if (record_dirname) {
00274     /* regist callbacks */
00275     callback_add_adin(recog, CALLBACK_ADIN_TRIGGERED, record_sample_write, data);
00276     callback_add(recog, CALLBACK_EVENT_SPEECH_STOP, record_sample_close, data);
00277     printf("Input speech data will be stored to = %s/\n", record_dirname);
00278   }
00279 }