julius/record.c

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

Generated on Tue Dec 18 15:59:50 2007 for Julius by  doxygen 1.5.4