[aadk-commits] dbailey: uClinux/trunk r550 - in /uClinux/trunk/uClinux-dist: linux-2.6.x/dri...

SVN commits to the AADK repository aadk-commits at lists.digium.com
Tue Jul 31 14:43:26 CDT 2007


Author: dbailey
Date: Tue Jul 31 14:43:25 2007
New Revision: 550

URL: http://svn.digium.com/view/aadk?view=rev&rev=550
Log:
Updated the appliance ztmonitor to allow for simultaneous but separate rx and tx record

Modified:
    uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/zaptel/zaptel.h
    uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/zaptel/ztmonitor.c
    uClinux/trunk/uClinux-dist/linux-2.6.x/include/zaptel/zaptel.h
    uClinux/trunk/uClinux-dist/uClibc/include/zaptel/zaptel.h
    uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c

Modified: uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/zaptel/zaptel.h
URL: http://svn.digium.com/view/aadk/uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/zaptel/zaptel.h?view=diff&rev=550&r1=549&r2=550
==============================================================================
--- uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/zaptel/zaptel.h (original)
+++ uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/zaptel/zaptel.h Tue Jul 31 14:43:25 2007
@@ -975,6 +975,9 @@
 #define	ZT_CONF_CONFANNMON 7		/* conference announce/monitor mode */
 #define	ZT_CONF_REALANDPSEUDO 8	/* real and pseudo port both on conf */
 #define ZT_CONF_DIGITALMON 9	/* Do not decode or interpret */
+#define	ZT_CONF_MONITOR_RX_PREECHO 10	/* monitor mode (rx of other chan) - before echo can is done */
+#define	ZT_CONF_MONITOR_TX_PREECHO 11	/* monitor mode (tx of other chan) - before echo can is done */
+#define	ZT_CONF_MONITORBOTH_PREECHO 12	/* monitor mode (rx & tx of other chan) - before echo can is done */
 #define	ZT_CONF_FLAG_MASK 0xff00	/* mask for flags */
 #define	ZT_CONF_LISTENER 0x100		/* is a listener on the conference */
 #define	ZT_CONF_TALKER 0x200		/* is a talker on the conference */

Modified: uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/zaptel/ztmonitor.c
URL: http://svn.digium.com/view/aadk/uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/zaptel/ztmonitor.c?view=diff&rev=550&r1=549&r2=550
==============================================================================
--- uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/zaptel/ztmonitor.c (original)
+++ uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/zaptel/ztmonitor.c Tue Jul 31 14:43:25 2007
@@ -1,7 +1,7 @@
 /*
  * Monitor a Zaptel Channel
  *
- * Written by Mark Spencer <markster at linux-support.net>
+ * Written by Mark Spencer <markster at digium.com>
  * Based on previous works, designs, and architectures conceived and
  * written by Jim Dixon <jim at lambdatel.com>.
  *
@@ -24,7 +24,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
- * Primary Author: Mark Spencer <markster at linux-support.net>
+ * Primary Author: Mark Spencer <markster at digium.com>
  *
  */
 
@@ -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,146 @@
 
 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, "Save a combined normal rx/tx stream and a combined 'preecho' rx/tx stream to files\n");
+		fprintf(stderr, "        ztmonitor 1 -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;
-		        visual = 1;
+			if (visual)
+				verbose = 1;
+			visual = 1;
+			multichannel = 1;
 		} else if (!strcmp(argv[i], "-vv")) {
-		        visual = 1;
+			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]);
 			}
-		}
-	}
-	if (!visual) {
-		/* Open audio */
-		if ((afd = audio_open()) < 0) {
-			printf("Cannot open audio ...\n");
-			if (!ofh) exit(0);
-		}
-	}
+		} 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 (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,15 +402,47 @@
 		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) {
@@ -338,31 +454,63 @@
 	}
 	/* 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) fclose(ofh); /*Never Reached */
+			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[0]) fclose(ofh[0]);
+	if (ofh[1]) fclose(ofh[1]);
+	if (ofh[2]) fclose(ofh[2]);
+	if (ofh[3]) fclose(ofh[3]);
 	exit(0);
 }

Modified: uClinux/trunk/uClinux-dist/linux-2.6.x/include/zaptel/zaptel.h
URL: http://svn.digium.com/view/aadk/uClinux/trunk/uClinux-dist/linux-2.6.x/include/zaptel/zaptel.h?view=diff&rev=550&r1=549&r2=550
==============================================================================
--- uClinux/trunk/uClinux-dist/linux-2.6.x/include/zaptel/zaptel.h (original)
+++ uClinux/trunk/uClinux-dist/linux-2.6.x/include/zaptel/zaptel.h Tue Jul 31 14:43:25 2007
@@ -975,6 +975,9 @@
 #define	ZT_CONF_CONFANNMON 7		/* conference announce/monitor mode */
 #define	ZT_CONF_REALANDPSEUDO 8	/* real and pseudo port both on conf */
 #define ZT_CONF_DIGITALMON 9	/* Do not decode or interpret */
+#define	ZT_CONF_MONITOR_RX_PREECHO 10	/* monitor mode (rx of other chan) - before echo can is done */
+#define	ZT_CONF_MONITOR_TX_PREECHO 11	/* monitor mode (tx of other chan) - before echo can is done */
+#define	ZT_CONF_MONITORBOTH_PREECHO 12	/* monitor mode (rx & tx of other chan) - before echo can is done */
 #define	ZT_CONF_FLAG_MASK 0xff00	/* mask for flags */
 #define	ZT_CONF_LISTENER 0x100		/* is a listener on the conference */
 #define	ZT_CONF_TALKER 0x200		/* is a talker on the conference */

Modified: uClinux/trunk/uClinux-dist/uClibc/include/zaptel/zaptel.h
URL: http://svn.digium.com/view/aadk/uClinux/trunk/uClinux-dist/uClibc/include/zaptel/zaptel.h?view=diff&rev=550&r1=549&r2=550
==============================================================================
--- uClinux/trunk/uClinux-dist/uClibc/include/zaptel/zaptel.h (original)
+++ uClinux/trunk/uClinux-dist/uClibc/include/zaptel/zaptel.h Tue Jul 31 14:43:25 2007
@@ -975,6 +975,9 @@
 #define	ZT_CONF_CONFANNMON 7		/* conference announce/monitor mode */
 #define	ZT_CONF_REALANDPSEUDO 8	/* real and pseudo port both on conf */
 #define ZT_CONF_DIGITALMON 9	/* Do not decode or interpret */
+#define	ZT_CONF_MONITOR_RX_PREECHO 10	/* monitor mode (rx of other chan) - before echo can is done */
+#define	ZT_CONF_MONITOR_TX_PREECHO 11	/* monitor mode (tx of other chan) - before echo can is done */
+#define	ZT_CONF_MONITORBOTH_PREECHO 12	/* monitor mode (rx & tx of other chan) - before echo can is done */
 #define	ZT_CONF_FLAG_MASK 0xff00	/* mask for flags */
 #define	ZT_CONF_LISTENER 0x100		/* is a listener on the conference */
 #define	ZT_CONF_TALKER 0x200		/* is a talker on the conference */

Modified: uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c
URL: http://svn.digium.com/view/aadk/uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c?view=diff&rev=550&r1=549&r2=550
==============================================================================
--- uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c (original)
+++ uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c Tue Jul 31 14:43:25 2007
@@ -1,7 +1,7 @@
 /*
  * Monitor a Zaptel Channel
  *
- * Written by Mark Spencer <markster at linux-support.net>
+ * Written by Mark Spencer <markster at digium.com>
  * Based on previous works, designs, and architectures conceived and
  * written by Jim Dixon <jim at lambdatel.com>.
  *
@@ -24,7 +24,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
- * Primary Author: Mark Spencer <markster at linux-support.net>
+ * Primary Author: Mark Spencer <markster at digium.com>
  *
  */
 
@@ -53,11 +53,13 @@
 
 #define FRAG_SIZE 8
 
-/* Put the ofh (output file handle) outside
+#define PROG "ztmonitor"
+
+/* 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;
@@ -148,7 +150,7 @@
 #define barlevel ((baroptimal/barlen)*2)
 #define maxlevel (barlen*barlevel)
 
-void draw_barheader()
+void draw_barheader(void)
 {
 	char bar[barlen+5];
 
@@ -255,64 +257,167 @@
 	}
 }
 
+/** Print usage message */
+static void usage(void)
+{
+	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"
+		"Save a combined normal rx/tx stream and a combined 'preecho' rx/tx stream to files\n"
+		"        " PROG " 1 -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 ztmonitor_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");
+		usage();
 		exit(1);
 	}
 	for (i = 2; i < argc; ++i) {
 		if (!strcmp(argv[i], "-v")) {
-				if (visual)
-					verbose = 1;
-		        visual = 1;
+			if (visual)
+				verbose = 1;
+			visual = 1;
+			multichannel = 1;
 		} else if (!strcmp(argv[i], "-vv")) {
-		        visual = 1;
+			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]);
 			}
-		}
-	}
-	if (!visual) {
-		/* Open audio */
-		if ((afd = audio_open()) < 0) {
-			printf("Cannot open audio ...\n");
-			if (!ofh) exit(0);
-		}
-	}
+		} 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 (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);
 		}
@@ -320,15 +425,47 @@
 		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) {
@@ -340,31 +477,63 @@
 	}
 	/* 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) fclose(ofh); /*Never Reached */
+			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[0]) fclose(ofh[0]);
+	if (ofh[1]) fclose(ofh[1]);
+	if (ofh[2]) fclose(ofh[2]);
+	if (ofh[3]) fclose(ofh[3]);
 	exit(0);
 }




More information about the aadk-commits mailing list