summaryrefslogtreecommitdiff
path: root/ztmonitor.c
diff options
context:
space:
mode:
authorqwell <qwell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-04-24 18:32:49 +0000
committerqwell <qwell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-04-24 18:32:49 +0000
commit5cf0e7757b6970a2860871e174c3a0066df50ce3 (patch)
tree4dff955f38767ea098329fcf738a4bfb13e043f6 /ztmonitor.c
parentf9dd2abfd14a990eed67f8ac1f6baf034e2c9719 (diff)
Merge in pre-echocan debugging for ztmonitor.
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@2433 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'ztmonitor.c')
-rw-r--r--ztmonitor.c246
1 files changed, 198 insertions, 48 deletions
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 <channel num> [-v[v]] [-f FILE]\n");
+ 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");
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<res;x++)
- buf2[x<<1] = buf2[(x<<1) + 1] = buf[x];
- write(afd, buf2, res << 1);
- } else
- write(afd, buf, res);
+ if (ofh[1])
+ fwrite(buf2, 1, res2, ofh[1]);
+
+ if (visual) {
+ if (res == res2)
+ visualize((short *)buf, (short *)buf2, res/2);
+ else
+ printf("Huh? res = %d, res2 = %d?\n", res, res2);
}
}
+
+ if (preecho) {
+ res = read(pfd[2], buf, sizeof(buf));
+ if (res < 1)
+ break;
+ if (ofh[2])
+ fwrite(buf, 1, res, ofh[2]);
+
+ if (multichannel) {
+ res2 = read(pfd[3], buf2, res);
+ if (res2 < 1)
+ break;
+ if (ofh[3])
+ fwrite(buf2, 1, res, ofh[3]);
+
+ /* XXX How are we going to visualize the preecho set of streams?
+ if (visual) {
+ if (res == res2)
+ visualize((short *)buf, (short *)buf2, res/2);
+ else
+ printf("Huh? res = %d, res2 = %d?\n", res, res2);
+ } */
+ }
+ }
+
+ if (ossoutput && afd) {
+ if (stereo) {
+ for (x=0;x<res;x++)
+ buf2[x<<1] = buf2[(x<<1) + 1] = buf[x];
+ write(afd, buf2, res << 1);
+ } else
+ write(afd, buf, res);
+ }
}
- if (ofh) fclose(ofh); /*Never Reached */
+ if (ofh[0]) fclose(ofh[0]);
+ if (ofh[1]) fclose(ofh[1]);
+ if (ofh[2]) fclose(ofh[2]);
+ if (ofh[3]) fclose(ofh[3]);
exit(0);
}