From 578112cb0dd965656e0a32ae6087493d1a64ee0d Mon Sep 17 00:00:00 2001 From: tzafrir Date: Wed, 25 Apr 2007 17:23:53 +0000 Subject: fix style in ztmonitor's code: * Use getopts for parsing the options. * Fix incorrect test for "no output stream". * Give names to some numbered file descriptors. * A separate usage message function. That is being used. * The sox message is back, and gives a working command. * clean-ups. git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2454 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- ztmonitor.c | 246 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 133 insertions(+), 113 deletions(-) diff --git a/ztmonitor.c b/ztmonitor.c index 26b6ccb..a9278ad 100644 --- a/ztmonitor.c +++ b/ztmonitor.c @@ -51,10 +51,20 @@ #define FRAG_SIZE 8 +#define PROG "ztmonitor" + /* Put the ofh (output file handles) outside * the main loop in case we ever add a signal * handler. */ + +enum ofh_type { + ofh_def = 0, + ofh_tx, + ofh_pre, + ofh_pretx, + ofh_last +}; static FILE* ofh[4] = {0, 0, 0, 0}; static int stereo = 0; @@ -253,128 +263,138 @@ void visualize(short *tx, short *rx, int cnt) } } +/** Print usage message */ +static void usage() +{ + fprintf(stderr, + "" PROG ": monitor a zaptel channel.\n" + "Usage:\n" + " " PROG " [options] \n" + "Options:\n" + " -v: Visual mode. Implies -m.\n" + " -vv: Visual/Verbose mode. Implies -m.\n" + " -m: Separate rx/tx streams.\n" + " -o: Output audio via OSS. Note: Only 'normal'\n" + " combined rx/tx streams are output via OSS.\n" + " -p: Get a pre-echocanceled stream.\n" + " -f FILE: Save combined rx/tx stream to FILE. \n" + " Cannot be used with -m.\n" + " -r FILE: Save rx stream to FILE. Implies -m.\n" + " -t FILE: Save tx stream to FILE. Implies -m.\n" + " -F FILE: Save combined pre-echocanceled rx/tx\n" + " stream to FILE. Cannot be used with -m.\n" + " Implies -p.\n" + " -R FILE: Save pre-echocanceled rx stream to FILE. \n" + " Implies -m and -p.\n" + " -T FILE: Save pre-echocanceled tx stream to FILE. \n" + " Implies -m and -p.\n" + "" + "At least one of -v, -o, -f -F, -r, -R, -t, -T must be\n" + "used to set the output.\n" + "Examples:\n" + "Save a stream to a file:\n" + " " PROG " 1 -f stream.raw\n" + "Visualize an rx/tx stream and save them to separate files:\n" + " " PROG " 1 -v -r streamrx.raw -t streamtx.raw\n" + "Play a combined rx/tx stream via OSS and save it to a file\n" + " " PROG " 1 -o -f stream.raw\n" + "Play a combined rx/tx stream via OSS and save them to separate files\n" + " " PROG " 1 -m -o -r streamrx.raw -t streamtx.raw\n" + "Save a combined normal rx/tx stream and a combined 'preecho' rx/tx stream to files\n" + " " PROG " 1 -m -p -f stream.raw -F streampreecho.raw\n" + "Save a normal rx/tx stream and a 'preecho' rx/tx stream to separate files\n" + " " PROG " 1 -m -p -r streamrx.raw -t streamtx.raw -R streampreechorx.raw -T streampreechotx.raw\n" + ""); +} + + + int main(int argc, char *argv[]) { int afd = -1; int pfd[4] = {-1, -1, -1, -1}; short buf[8192]; short buf2[16384]; - char output_file[255]; + char *output_file = NULL; int res, res2; int visual = 0; int multichannel = 0; int ossoutput = 0; int preecho = 0; - int savefile = 0; - int x, i; + //int savefile = 0; replaced with: (output_file == NULL) + int x; struct zt_confinfo zc; + int opt; + int opt_visual = 0; + enum ofh_type ofh_type = ofh_def; + int chan_num = -1; - if ((argc < 2) || (atoi(argv[1]) < 1)) { - fprintf(stderr, "Usage: ztmonitor [-v[v]] [-m] [-o] [-p] [-f FILE | -r FILE1 -t FILE2] [-F FILE | -R FILE1 -T FILE2]\n"); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -v: Visual mode. Implies -m.\n"); - fprintf(stderr, " -vv: Visual/Verbose mode. Implies -m.\n"); - fprintf(stderr, " -m: Separate rx/tx streams.\n"); - fprintf(stderr, " -o: Output audio via OSS. Note: Only 'normal' combined rx/tx streams are output via OSS.\n"); - fprintf(stderr, " -p: Get a pre-echocanceled stream.\n"); - fprintf(stderr, " -f FILE: Save combined rx/tx stream to FILE. Cannot be used with -m.\n"); - fprintf(stderr, " -r FILE: Save rx stream to FILE. Implies -m.\n"); - fprintf(stderr, " -t FILE: Save tx stream to FILE. Implies -m.\n"); - fprintf(stderr, " -F FILE: Save combined pre-echocanceled rx/tx stream to FILE. Cannot be used with -m. Implies -p.\n"); - fprintf(stderr, " -R FILE: Save pre-echocanceled rx stream to FILE. Implies -m and -p.\n"); - fprintf(stderr, " -T FILE: Save pre-echocanceled tx stream to FILE. Implies -m and -p.\n"); - fprintf(stderr, "Examples:\n"); - fprintf(stderr, "Save a stream to a file\n"); - fprintf(stderr, " ztmonitor 1 -f stream.raw\n"); - fprintf(stderr, "Visualize an rx/tx stream and save them to separate files.\n"); - fprintf(stderr, " ztmonitor 1 -v -r streamrx.raw -t streamtx.raw\n"); - fprintf(stderr, "Play a combined rx/tx stream via OSS and save it to a file\n"); - fprintf(stderr, " ztmonitor 1 -o -f stream.raw\n"); - fprintf(stderr, "Play a combined rx/tx stream via OSS and save them to separate files\n"); - fprintf(stderr, " ztmonitor 1 -m -o -r streamrx.raw -t streamtx.raw\n"); - fprintf(stderr, "Save a combined normal rx/tx stream and a combined 'preecho' rx/tx stream to files\n"); - fprintf(stderr, " ztmonitor 1 -m -p -f stream.raw -F streampreecho.raw\n"); - fprintf(stderr, "Save a normal rx/tx stream and a 'preecho' rx/tx stream to separate files\n"); - fprintf(stderr, " ztmonitor 1 -m -p -r streamrx.raw -t streamtx.raw -R streampreechorx.raw -T streampreechotx.raw\n"); + while((opt = getopt(argc, argv, "hvmopf:r:t:F:R:T:")) != -1) { + switch(opt) { + case 'h': usage(); exit(0); break; + case '?': usage(); exit(1); break; + case 'v': opt_visual++; break; + case 'm': multichannel=1; break; + case 'o': ossoutput=1; break; + case 'p': preecho=1; break; + case 'f': output_file = optarg; break; + case 'r': output_file = optarg; multichannel = 1; break; + case 't': output_file = optarg; multichannel = 1; ofh_type = ofh_tx; break; + case 'F': output_file = optarg; ofh_type = ofh_pre; preecho = 1; break; + case 'R': output_file = optarg; multichannel = 1; ofh_type = ofh_pre; preecho = 1; break; + case 'T': output_file = optarg; multichannel = 1; ofh_type = ofh_pretx; preecho = 1; break; + } + } + /* XXX: have a single "verbose" variable? or separate those + * two options? */ + if (opt_visual >= 1) + visual = 1; + + if (opt_visual >= 2) + verbose = 1; + + if (output_file && ((ofh[ofh_type] = fopen(output_file, "w"))<0)) { + fprintf(stderr, PROG ": Could not open %s for writing: %s\n", + output_file, strerror(errno)); exit(1); } - for (i = 2; i < argc; ++i) { - if (!strcmp(argv[i], "-v")) { - if (visual) - verbose = 1; - visual = 1; - multichannel = 1; - } else if (!strcmp(argv[i], "-vv")) { - visual = 1; - verbose = 1; - multichannel = 1; - } else if ((!strcmp(argv[i], "-f") || !strcmp(argv[i], "-r") || !strcmp(argv[i], "-t") - || !strcmp(argv[i], "-F") || !strcmp(argv[i], "-R") || !strcmp(argv[i], "-T")) - && (i+1) < argc) { - /* Set which file descriptor to use */ - if (!strcmp(argv[i], "-f")) { - savefile = 1; - x = 0; - } else if (!strcmp(argv[i], "-r")) { - savefile = 1; - multichannel = 1; - x = 0; - } else if (!strcmp(argv[i], "-t")) { - savefile = 1; - multichannel = 1; - x = 1; - } else if (!strcmp(argv[i], "-F")) { - savefile = 1; - preecho = 1; - x = 2; - } else if (!strcmp(argv[i], "-R")) { - savefile = 1; - multichannel = 1; - preecho = 1; - x = 2; - } else if (!strcmp(argv[i], "-T")) { - savefile = 1; - multichannel = 1; - preecho = 1; - x = 3; - } else - x = 0; - - ++i; /* we care about the file name */ - if (strlen(argv[i]) < 255 ) { - strcpy(output_file, argv[i]); - fprintf(stderr, "Output to %s\n", output_file); - if ((ofh[x] = fopen(output_file, "w"))<0) { - fprintf(stderr, "Could not open %s for writing: %s\n", output_file, strerror(errno)); - exit(1); - } - fprintf(stderr, "Run e.g., 'sox -r 8000 -s -w -c 1 %s file.wav' to convert.\n", output_file); - } else { - fprintf(stderr, "File Name %s too long\n",argv[i+1]); - } - } else if (!strcmp(argv[i], "-m")) { - multichannel = 1; - } else if (!strcmp(argv[i], "-o")) { - ossoutput = 1; - } else if (!strcmp(argv[i], "-p")) { - preecho = 1; - } + if (output_file) + printf("Started recording. To stop: cress ctrl-C. " + "Recording a raw slinear file, to get a wav file:\n" + " sox -r 8000 -s -w -c %d %s %s.wav\n", + (multichannel)? 2:1, output_file, output_file); + + /* XXX: if POSIXLY_CORRECT is set, getopt will stop parsing at the + * first non-option argument. In the case of ztmonitor, the + * first argument used to be a non-option (the channel), hence + * we rely on a posix-incompatibility. + * Workaround: in the presence of POSIXLY_CORRECT, use: + * ztmonitor [options] + */ + + if (argv[optind]) + chan_num =atoi(argv[optind]); + if (! chan_num < 1) { + fprintf(stderr,"Error: missing channel number\n"); + usage(); + exit(1); } if (ossoutput) { if (multichannel) { - printf("Multi-channel audio is enabled. OSS output will be disabled.\n"); + fprintf(stderr, "Multi-channel audio is enabled. OSS output will be disabled.\n"); ossoutput = 0; } else { /* Open audio */ if ((afd = audio_open()) < 0) { - printf("Cannot open audio ...\n"); + fprintf(stderr, "Cannot open audio ...\n"); ossoutput = 0; } } } - if (!ossoutput && !multichannel && !savefile) { - fprintf(stderr, "Nothing to do with the stream(s) ...\n"); + if (!ossoutput || !multichannel || (output_file != NULL)) { + fprintf(stderr, "No output defined. Aborting.\n"); + usage(); exit(1); } @@ -393,7 +413,7 @@ int main(int argc, char *argv[]) if (multichannel) { memset(&zc, 0, sizeof(zc)); zc.chan = 0; - zc.confno = atoi(argv[1]); + zc.confno = chan_num; /* Two pseudo's, one for tx, one for rx */ zc.confmode = ZT_CONF_MONITORTX; if (ioctl(pfd[0], ZT_SETCONF, &zc) < 0) { @@ -402,7 +422,7 @@ int main(int argc, char *argv[]) } memset(&zc, 0, sizeof(zc)); zc.chan = 0; - zc.confno = atoi(argv[1]); + zc.confno = chan_num; zc.confmode = ZT_CONF_MONITOR; if (ioctl(pfd[1], ZT_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); @@ -411,7 +431,7 @@ int main(int argc, char *argv[]) if (preecho) { memset(&zc, 0, sizeof(zc)); zc.chan = 0; - zc.confno = atoi(argv[1]); + zc.confno = chan_num; /* Two pseudo's, one for tx, one for rx */ zc.confmode = ZT_CONF_MONITOR_TX_PREECHO; if (ioctl(pfd[2], ZT_SETCONF, &zc) < 0) { @@ -420,7 +440,7 @@ int main(int argc, char *argv[]) } memset(&zc, 0, sizeof(zc)); zc.chan = 0; - zc.confno = atoi(argv[1]); + zc.confno = chan_num; zc.confmode = ZT_CONF_MONITOR_RX_PREECHO; if (ioctl(pfd[3], ZT_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); @@ -430,7 +450,7 @@ int main(int argc, char *argv[]) } else { memset(&zc, 0, sizeof(zc)); zc.chan = 0; - zc.confno = atoi(argv[1]); + zc.confno = chan_num; zc.confmode = ZT_CONF_MONITORBOTH; if (ioctl(pfd[0], ZT_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); @@ -439,7 +459,7 @@ int main(int argc, char *argv[]) if (preecho) { memset(&zc, 0, sizeof(zc)); zc.chan = 0; - zc.confno = atoi(argv[1]); + zc.confno = chan_num; zc.confmode = ZT_CONF_MONITORBOTH_PREECHO; if (ioctl(pfd[2], ZT_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); @@ -459,15 +479,15 @@ int main(int argc, char *argv[]) res = read(pfd[0], buf, sizeof(buf)); if (res < 1) break; - if (ofh[0]) - fwrite(buf, 1, res, ofh[0]); + if (ofh[ofh_def]) + fwrite(buf, 1, res, ofh[ofh_def]); if (multichannel) { res2 = read(pfd[1], buf2, res); if (res2 < 1) break; - if (ofh[1]) - fwrite(buf2, 1, res2, ofh[1]); + if (ofh[ofh_tx]) + fwrite(buf2, 1, res2, ofh[ofh_tx]); if (visual) { if (res == res2) @@ -481,15 +501,15 @@ int main(int argc, char *argv[]) res = read(pfd[2], buf, sizeof(buf)); if (res < 1) break; - if (ofh[2]) - fwrite(buf, 1, res, ofh[2]); + if (ofh[ofh_pre]) + fwrite(buf, 1, res, ofh[ofh_pre]); if (multichannel) { res2 = read(pfd[3], buf2, res); if (res2 < 1) break; - if (ofh[3]) - fwrite(buf2, 1, res, ofh[3]); + if (ofh[ofh_pretx]) + fwrite(buf2, 1, res, ofh[ofh_pretx]); /* XXX How are we going to visualize the preecho set of streams? if (visual) { @@ -510,9 +530,9 @@ int main(int argc, char *argv[]) write(afd, buf, res); } } - if (ofh[0]) fclose(ofh[0]); - if (ofh[1]) fclose(ofh[1]); - if (ofh[2]) fclose(ofh[2]); - if (ofh[3]) fclose(ofh[3]); + + for (x=ofh_def; x < ofh_last; x++) + if (ofh[x]) + fclose(ofh[x]); exit(0); } -- cgit v1.2.3