00001
00035
00036
00037
00038
00039
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
00195
00196 if (recordlen == 0) {
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
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
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 }