[zaptel-commits] tzafrir: trunk r2454 - /trunk/ztmonitor.c
zaptel-commits at lists.digium.com
zaptel-commits at lists.digium.com
Wed Apr 25 10:23:53 MST 2007
Author: tzafrir
Date: Wed Apr 25 12:23:53 2007
New Revision: 2454
URL: http://svn.digium.com/view/zaptel?view=rev&rev=2454
Log:
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.
Modified:
trunk/ztmonitor.c
Modified: trunk/ztmonitor.c
URL: http://svn.digium.com/view/zaptel/trunk/ztmonitor.c?view=diff&rev=2454&r1=2453&r2=2454
==============================================================================
--- trunk/ztmonitor.c (original)
+++ trunk/ztmonitor.c Wed Apr 25 12:23:53 2007
@@ -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 @@
}
}
+/** Print usage message */
+static void usage()
+{
+ fprintf(stderr,
+ "" PROG ": monitor a zaptel channel.\n"
+ "Usage:\n"
+ " " PROG " [options] <channel num>\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;
-
- if ((argc < 2) || (atoi(argv[1]) < 1)) {
- fprintf(stderr, "Usage: ztmonitor <channel num> [-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");
+ int opt;
+ int opt_visual = 0;
+ enum ofh_type ofh_type = ofh_def;
+ int chan_num = -1;
+
+ 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] <CHAN_NUM>
+ */
+
+ 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 @@
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 @@
}
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 @@
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 @@
}
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 @@
} 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 @@
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 @@
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 @@
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 @@
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);
}
More information about the zaptel-commits
mailing list