📄 main.cpp
字号:
//// Test program for the endpointer//// Main reads the command line and processes each argument assuming it is a file name.// Main calls dofile for each filename. See dofile for specific example of how to// use the endpointer.//// Bruce Lowerre, 1995, 1997////#include "general.h"#include "endpoint.h"#include "cbuf.h"#include "playbuf.h"#include "sigcvt.h"#define SAMPRATE 8000#define STEP 80 // step size is 10 msec#define WINDOW 128 // window size is 16 msecLOCAL cbuf_short* readfile( char* filename){ cbuf_short *buffer; char *cbuffer, // raw bytes *c, chr1, chr2; short *buf16; FILE *fd; long i, n, srate = SAMPRATE, n16; sigconvert sigcvt; // mulaw and alaw conversions fd = fopen (filename, "r"); if (fd == NULL) { cout << "readfile: Can't open file \"" << filename << "\"" << endl; return (NULL); } for (n = 0; ; n++) { // count length of file if (!fread (&chr1, 1, 1, fd)) break; } rewind (fd); // rewind to read again cbuffer = new char[n]; // read as bytes fread (cbuffer, 1, n, fd); fclose (fd); // determine file type for (c = filename + strlen (filename) - 1; c >= filename && *c != '.'; c--) ; // find extension, if any if (*c == '.') { // found extension, determine file type if (!strcmp (c, ".raw") || !strcmp (c, ".RAW")) { // looks like 16 bit linear for (c = cbuffer, i = 0; i < n; i +=2, c += 2) { // byte swap the shorts chr1 = *c; chr2 = *(c + 1); *c = chr2; *(c + 1) = chr1; } buf16 = (short*) cbuffer; // coerce buffer type n16 = n / sizeof (short); // number of samples } else if (!strcmp (c, ".16l") || !strcmp (c, "16L")) { // 16 bit linear, no byte swap buf16 = (short*) cbuffer; // coerce buffer type n16 = n / sizeof (short); // number of samples } else if (!strcmp (c, ".8U") || !strcmp (c, ".8u")) { // looks like 8KHz mulaw file srate = 8000; n16 = n; buf16 = new short[n16]; for (i = 0; i < n; i++) buf16[i] = sigcvt.mulaw_to_short(cbuffer[i]); delete []cbuffer; } else if (!strcmp (c, ".8A") || !strcmp (c, ".8a")) { // looks like 8KHz a-law file srate = 8000; n16 = n; buf16 = new short[n16]; for (i = 0; i < n; i++) buf16[i] = sigcvt.alaw_to_short(cbuffer[i]); delete []cbuffer; } else { cout << "readfile: unknown file type \"" << filename << "\"" << endl; return (NULL); } } else { // no extension cout << "readfile: unknown file type \"" << filename << "\"" << endl; return (NULL); } buffer = new cbuf_short (n16); buffer -> write (buf16, n16); delete []buf16; // delete temporary buffer return (buffer);} // end readfileLOCAL void nextframe( short *frame, cbuf_short *buffer){ // STEP frame and fill to WINDOW long i, n = WINDOW - STEP; // number of old samples to keep for (i = 0; i < n; i++) frame[i] = frame[i + STEP]; // shift down samples to keep buffer -> read (frame + n, STEP); // fill rest of frame with new samples} // end nextframeLOCAL void dofile( char *filename, // file to process BOOLEAN printvalues // print endpoint values){ cbuf_short *buffer; endpointer *ep; // use default parameters short frame[WINDOW]; // one frame of data long n, // number of samples needed i, // count frames startframe = -1, // start of utt frame number endframe = -1; // end of utt frame number BOOLEAN gogo; // keep processing EPTAG eptag; if ((buffer = readfile (filename)) == NULL) { cout << "dofile: Can't read file \"" << filename << "\"" << endl; return; } cout << endl << filename << endl << flush; playbuf (buffer); // play file before endpointing, may be stub ep = new endpointer (SAMPRATE, WINDOW, STEP, 1000); if (printvalues) ep -> printvars (); cout << "frame\tlabel" << endl; for (i = 0, gogo = True; gogo; i++) { // Get number of samples needed for this frame if (i == 0) n = WINDOW; // first frame, fill completely else n = STEP; // step frame while (gogo && buffer -> available_read () < n) { // Assuming this is a live input system, we would wait at this point // for more data to become available. Since this is actually running // from pre-recorded data, there is no more data available and the // the endpointer has not yet confirmed the end of utterance. So, // force end of utt. gogo = False; cout << "no more data" << endl; } if (!gogo) continue; // actually, could break if (i == 0) buffer -> read (frame, n); // fill first frame else nextframe (frame, buffer); // step next frame eptag = ep -> getendpoint (frame);// get endpoint tag cout << i << "\t" << ep -> gettagname (eptag) << endl; switch (eptag) { // determine what to do with this frame case EP_RESET: // false start // At this point, one would reset the recognizer to start over. // After reset, fall through, same as next. case EP_SILENCE: // not yet start of utt // Essentially, this frame can be ignored. startframe = i + 1; // set to next frame for demo buffer -> setkeeper (0);// advance the keeper pointer break; case EP_MAYBEEND: // possible end of utterance // remember recognition result at this point in case it is // actual end of utterance. endframe = i; // set end frame number for demo buffer -> seteod (0); // mark end of data // Now, fall through to next and keep processing as if this // were not the end of utterance case EP_INUTT: // confirmed signal start // all data frames before this marked as EP_SIGNAL were part // of the actual utterance. A reset after this point will be // due to a rejected signal rather than a false start. // Fall through, treat as EP_SIGNAL case EP_SIGNAL: // signal frame // process the frame through the recognition system break; case EP_NOTEND: // the last MAYBEEND was NOT the end of the utt endframe = -1; // indicate end not found buffer -> unseteod (); // unset the end of data pointer // Now, process this frame same as SIGNAL frame. break; case EP_ENDOFUTT: // confirmed end of utterance gogo = False; // stop processing // This is a silence frame after the end of signal. The previous // MAYBEEND frame was the actual end of utterance break; case EP_NOSTARTSILENCE: // error condition cout << "Spoke too soon" << endl; // This error may be handled as you wish. For this demo, keep going. break; } } if (endframe < 0) cout << "Utterance not found" << endl; else { cout << "Utterance is between frames " << startframe << " and " << endframe << endl << flush; playbuf (buffer); // play file after endpointing, may be stub } delete buffer; delete ep;} // end dofileLOCAL void printusage( char* progn){ cout << "Usage: " << progn << "[-v] <data.file> ..." << endl; cout << " -v print endpoint values " << endl;} // end printusageint main( long argc, char **argv){ BOOLEAN printvalues = False; char* progn = argv[0]; for (; argc > 1 && argv[1][0] == '-'; argc--, argv++) { switch (argv[1][1]) { case 'v': // print endpoint values printvalues = True; break; default: cout << "Unknown switch \"" << argv[1] << "\"" << endl; printusage (progn); return (-1); } } if (argc < 2 || argv[1][0] == '?') { printusage (progn); return (-1); } for (; argc > 1; argc--, argv++) dofile (argv[1], printvalues); return (0);} // end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -