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 = 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
00196
00197 if (recordlen == 0) {
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
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
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 }