From a461c286fb7d9aae69594f2d89b4f0a853ef57e2 Mon Sep 17 00:00:00 2001 From: qwell Date: Tue, 24 Apr 2007 18:54:06 +0000 Subject: merge (manually) ztmonitor pre-echocan debugging git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2436 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- ztmonitor.c | 246 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 198 insertions(+), 48 deletions(-) (limited to 'ztmonitor.c') diff --git a/ztmonitor.c b/ztmonitor.c index 43333e3..26b6ccb 100644 --- a/ztmonitor.c +++ b/ztmonitor.c @@ -51,11 +51,11 @@ #define FRAG_SIZE 8 -/* Put the ofh (output file handle) outside +/* Put the ofh (output file handles) outside * the main loop in case we ever add a signal - * hanlder. + * handler. */ -static FILE* ofh = 0; +static FILE* ofh[4] = {0, 0, 0, 0}; static int stereo = 0; static int verbose = 0; @@ -255,62 +255,148 @@ void visualize(short *tx, short *rx, int cnt) int main(int argc, char *argv[]) { - int afd = -1, pfd, pfd2 = -1; + int afd = -1; + int pfd[4] = {-1, -1, -1, -1}; short buf[8192]; short buf2[16384]; char output_file[255]; int res, res2; int visual = 0; - int x,i; + int multichannel = 0; + int ossoutput = 0; + int preecho = 0; + int savefile = 0; + int x, i; struct zt_confinfo zc; if ((argc < 2) || (atoi(argv[1]) < 1)) { - fprintf(stderr, "Usage: ztmonitor [-v[v]] [-f FILE]\n"); + 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"); exit(1); } for (i = 2; i < argc; ++i) { if (!strcmp(argv[i], "-v")) { - if (visual) - verbose = 1; + if (visual) + verbose = 1; visual = 1; + multichannel = 1; } else if (!strcmp(argv[i], "-vv")) { visual = 1; verbose = 1; - } else if (!strcmp(argv[i], "-f") && (i+1) < argc) { - ++i; /*we care about hte file name */ + 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 = fopen(output_file, "w"))<0) { + if ((ofh[x] = fopen(output_file, "w"))<0) { fprintf(stderr, "Could not open %s for writing: %s\n", output_file, strerror(errno)); - exit(0); + exit(1); } - fprintf(stderr, "Run e.g., 'sox -r 8000 -s -w -c 1 file.raw file.wav' to convert.\n"); + 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 (!visual) { - /* Open audio */ - if ((afd = audio_open()) < 0) { - printf("Cannot open audio ...\n"); - if (!ofh) exit(0); + + if (ossoutput) { + if (multichannel) { + printf("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"); + ossoutput = 0; + } } } + if (!ossoutput && !multichannel && !savefile) { + fprintf(stderr, "Nothing to do with the stream(s) ...\n"); + exit(1); + } + /* Open Pseudo device */ - if ((pfd = pseudo_open()) < 0) + if ((pfd[0] = pseudo_open()) < 0) exit(1); - if (visual && ((pfd2 = pseudo_open()) < 0)) + if (multichannel && ((pfd[1] = pseudo_open()) < 0)) exit(1); + if (preecho) { + if ((pfd[2] = pseudo_open()) < 0) + exit(1); + if (multichannel && ((pfd[3] = pseudo_open()) < 0)) + exit(1); + } /* Conference them */ - memset(&zc, 0, sizeof(zc)); - zc.chan = 0; - zc.confno = atoi(argv[1]); - if (visual) { + if (multichannel) { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = atoi(argv[1]); /* Two pseudo's, one for tx, one for rx */ zc.confmode = ZT_CONF_MONITORTX; - if (ioctl(pfd, ZT_SETCONF, &zc) < 0) { + if (ioctl(pfd[0], ZT_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); exit(1); } @@ -318,16 +404,48 @@ int main(int argc, char *argv[]) zc.chan = 0; zc.confno = atoi(argv[1]); zc.confmode = ZT_CONF_MONITOR; - if (ioctl(pfd2, ZT_SETCONF, &zc) < 0) { + if (ioctl(pfd[1], ZT_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); exit(1); } + if (preecho) { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = atoi(argv[1]); + /* Two pseudo's, one for tx, one for rx */ + zc.confmode = ZT_CONF_MONITOR_TX_PREECHO; + if (ioctl(pfd[2], ZT_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = atoi(argv[1]); + zc.confmode = ZT_CONF_MONITOR_RX_PREECHO; + if (ioctl(pfd[3], ZT_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + } } else { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = atoi(argv[1]); zc.confmode = ZT_CONF_MONITORBOTH; - if (ioctl(pfd, ZT_SETCONF, &zc) < 0) { + if (ioctl(pfd[0], ZT_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); exit(1); } + if (preecho) { + memset(&zc, 0, sizeof(zc)); + zc.chan = 0; + zc.confno = atoi(argv[1]); + zc.confmode = ZT_CONF_MONITORBOTH_PREECHO; + if (ioctl(pfd[2], ZT_SETCONF, &zc) < 0) { + fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); + exit(1); + } + } } if (visual) { printf("\nVisual Audio Levels.\n"); @@ -338,31 +456,63 @@ int main(int argc, char *argv[]) } /* Now, copy from pseudo to audio */ for (;;) { - res = read(pfd, buf, sizeof(buf)); - if (res < 1) + res = read(pfd[0], buf, sizeof(buf)); + if (res < 1) break; - if (visual) { - res2 = read(pfd2, buf2, res); - if (res2 < 1) + if (ofh[0]) + fwrite(buf, 1, res, ofh[0]); + + if (multichannel) { + res2 = read(pfd[1], buf2, res); + if (res2 < 1) break; - if (res == res2) - visualize((short *)buf, (short *)buf2, res/2); - else - printf("Huh? res = %d, res2 = %d?\n", res, res2); - - } else { - if (ofh) - fwrite(buf, 1, res, ofh); - if (afd) { - if (stereo) { - for (x=0;x