[aadk-commits] dbailey: uClinux/trunk r361 - /uClinux/trunk/uClinux-dist/user/busybox/miscut...

aadk-commits at lists.digium.com aadk-commits at lists.digium.com
Fri Apr 20 12:04:19 MST 2007


Author: dbailey
Date: Fri Apr 20 14:04:18 2007
New Revision: 361

URL: http://svn.digium.com/view/aadk?view=rev&rev=361
Log:
Actually add the ztmonitor code to the svn archive

Added:
    uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c   (with props)

Added: 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=auto&rev=361
==============================================================================
--- uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c (added)
+++ uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c Fri Apr 20 14:04:18 2007
@@ -1,0 +1,368 @@
+/*
+ * Monitor a Zaptel Channel
+ *
+ * Written by Mark Spencer <markster at linux-support.net>
+ * Based on previous works, designs, and architectures conceived and
+ * written by Jim Dixon <jim at lambdatel.com>.
+ *
+ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
+ * Copyright (C) 2001 Linux Support Services, Inc.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under thet erms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * 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>
+ *
+ */
+
+#include <stdio.h> 
+#include <getopt.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <errno.h>
+#ifdef STANDALONE_ZAPATA
+#include "zaptel.h"
+#include "tonezone.h"
+#else
+#include <zaptel/zaptel.h>
+#include <zaptel/tonezone.h>
+#endif
+#include <linux/soundcard.h>
+
+#define BUFFERS 4
+
+#define FRAG_SIZE 8
+
+/* Put the ofh (output file handle) outside
+ * the main loop in case we ever add a signal
+ * hanlder.
+ */
+static FILE*  ofh = 0;
+
+static int stereo = 0;
+static int verbose = 0;
+
+int audio_open(void)
+{
+	int fd;
+	int speed = 8000;
+	int fmt = AFMT_S16_LE;
+	int fragsize = (BUFFERS << 16) | (FRAG_SIZE);
+	struct audio_buf_info ispace, ospace;
+	fd = open("/dev/dsp", O_WRONLY);
+	if (fd < 0) {
+		fprintf(stderr, "Unable to open /dev/dsp: %s\n", strerror(errno));
+		return -1;
+	}
+	/* Step 1: Signed linear */
+	if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) < 0) {
+		fprintf(stderr, "ioctl(SETFMT) failed: %s\n", strerror(errno));
+		close(fd);
+		return -1;
+	}
+	/* Step 2: Make non-stereo */
+	if (ioctl(fd, SNDCTL_DSP_STEREO, &stereo) < 0) {
+		fprintf(stderr, "ioctl(STEREO) failed: %s\n", strerror(errno));
+		close(fd);
+		return -1;
+	}
+	if (stereo != 0) {
+		fprintf(stderr, "Can't turn stereo off :(\n");
+	}
+	/* Step 3: Make 8000 Hz */
+	if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) < 0) {
+		fprintf(stderr, "ioctl(SPEED) failed: %s\n", strerror(errno));
+		close(fd);
+		return -1;
+	}
+	if (speed != 8000) 
+		fprintf(stderr, "Warning: Requested 8000 Hz, got %d\n", speed);
+	if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragsize)) {
+		fprintf(stderr, "Sound card won't let me set fragment size to 10 64-byte buffers (%x)\n"
+						"so sound may be choppy: %s.\n", fragsize, strerror(errno));
+	}	
+	bzero(&ispace, sizeof(ispace));
+	bzero(&ospace, sizeof(ospace));
+
+	if (ioctl(fd, SNDCTL_DSP_GETISPACE, &ispace)) {
+		/* They don't support block size stuff, so just return but notify the user */
+		fprintf(stderr, "Sound card won't let me know the input buffering...\n");
+	}
+	if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &ospace)) {
+		/* They don't support block size stuff, so just return but notify the user */
+		fprintf(stderr, "Sound card won't let me know the output buffering...\n");
+	}
+	fprintf(stderr, "New input space:  %d of %d %d byte fragments (%d bytes left)\n", 
+		ispace.fragments, ispace.fragstotal, ispace.fragsize, ispace.bytes);
+	fprintf(stderr, "New output space:  %d of %d %d byte fragments (%d bytes left)\n", 
+		ospace.fragments, ospace.fragstotal, ospace.fragsize, ospace.bytes);
+	return fd;
+}
+
+int pseudo_open(void)
+{
+	int fd;
+	int x = 1;
+	fd = open("/dev/zap/pseudo", O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "Unable to open pseudo channel: %s\n", strerror(errno));
+		return -1;
+	}
+	if (ioctl(fd, ZT_SETLINEAR, &x)) {
+		fprintf(stderr, "Unable to set linear mode: %s\n", strerror(errno));
+		close(fd);
+		return -1;
+	}
+	x = 240;
+	if (ioctl(fd, ZT_SET_BLOCKSIZE, &x)) {
+		fprintf(stderr, "unable to set sane block size: %s\n", strerror(errno));
+		close(fd);
+		return -1;
+	}
+	return fd;
+}
+
+#define barlen 35
+#define baroptimal 3250
+//define barlevel 200
+#define barlevel ((baroptimal/barlen)*2)
+#define maxlevel (barlen*barlevel)
+
+void draw_barheader()
+{
+	char bar[barlen+5];
+
+	memset(bar, '-', sizeof(bar));
+	memset(bar, '<', 1);
+	memset(bar+barlen+2, '>', 1);
+	memset(bar+barlen+3, '\0', 1);
+
+	strncpy(bar+(barlen/2), "(RX)", 4);
+	printf("%s", bar);
+
+	strncpy(bar+(barlen/2), "(TX)", 4);
+	printf(" %s\n", bar);
+}
+
+void draw_bar(int avg, int max)
+{
+	char bar[barlen+5];
+
+	memset(bar, ' ', sizeof(bar));
+
+	max /= barlevel;
+	avg /= barlevel;
+	if (avg > barlen)
+		avg = barlen;
+	if (max > barlen)
+		max = barlen;
+	
+	if (avg > 0) 
+		memset(bar, '#', avg);
+	if (max > 0) 
+		memset(bar + max, '*', 1);
+
+	bar[barlen+1] = '\0';
+	printf("%s", bar);
+	fflush(stdout);
+}
+
+void visualize(short *tx, short *rx, int cnt)
+{
+	int x;
+	float txavg = 0;
+	float rxavg = 0;
+	static int txmax = 0;
+	static int rxmax = 0;
+	static int sametxmax = 0;
+	static int samerxmax = 0;
+	static int txbest = 0;
+	static int rxbest = 0;
+	float ms;
+	static struct timeval last;
+	struct timeval tv;
+	
+	gettimeofday(&tv, NULL);
+	ms = (tv.tv_sec - last.tv_sec) * 1000.0 + (tv.tv_usec - last.tv_usec) / 1000.0;
+	for (x=0;x<cnt;x++) {
+		txavg += abs(tx[x]);
+		rxavg += abs(rx[x]);
+	}
+	txavg = abs(txavg / cnt);
+	rxavg = abs(rxavg / cnt);
+	
+	if (txavg > txbest)
+		txbest = txavg;
+	if (rxavg > rxbest)
+		rxbest = rxavg;
+	
+	/* Update no more than 10 times a second */
+	if (ms < 100)
+		return;
+	
+	/* Save as max levels, if greater */
+	if (txbest > txmax) {
+		txmax = txbest;
+		sametxmax = 0;
+	}
+	if (rxbest > rxmax) {
+		rxmax = rxbest;
+		samerxmax = 0;
+	}
+
+	memcpy(&last, &tv, sizeof(last));
+
+	/* Clear screen */
+	printf("\r ");
+	draw_bar(rxbest, rxmax);
+	printf("   ");
+	draw_bar(txbest, txmax);
+	if (verbose)
+		printf("   Rx: %5d (%5d) Tx: %5d (%5d)", rxbest, rxmax, txbest, txmax);
+	txbest = 0;
+	rxbest = 0;
+	
+	/* If we have had the same max hits for x times, clear the values */
+	sametxmax++;
+	samerxmax++;
+	if (sametxmax > 6) {
+		txmax = 0;
+		sametxmax = 0;
+	}
+	if (samerxmax > 6) {
+		rxmax = 0;
+		samerxmax = 0;
+	}
+}
+
+int ztmonitor_main(int argc, char *argv[])
+{
+	int afd = -1, pfd, pfd2 = -1;
+	short buf[8192];
+	short buf2[16384];
+	char  output_file[255];
+	int res, res2;
+	int visual = 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");
+		exit(1);
+	}
+	for (i = 2; i < argc; ++i) {
+		if (!strcmp(argv[i], "-v")) {
+				if (visual)
+					verbose = 1;
+		        visual = 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 */
+			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) {
+					fprintf(stderr, "Could not open %s for writing: %s\n", output_file, strerror(errno));
+					exit(0);
+				}
+				fprintf(stderr, "Run e.g., 'sox -r 8000 -s -w -c 1 file.raw file.wav' to convert.\n");
+			} 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);
+		}
+	}
+	/* Open Pseudo device */
+	if ((pfd = pseudo_open()) < 0)
+		exit(1);
+	if (visual && ((pfd2 = pseudo_open()) < 0))
+		exit(1);
+	/* Conference them */
+	memset(&zc, 0, sizeof(zc));
+	zc.chan = 0;
+	zc.confno = atoi(argv[1]);
+	if (visual) {
+		/* Two pseudo's, one for tx, one for rx */
+		zc.confmode = ZT_CONF_MONITORTX;
+		if (ioctl(pfd, 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;
+		if (ioctl(pfd2, ZT_SETCONF, &zc) < 0) {
+			fprintf(stderr, "Unable to monitor: %s\n", strerror(errno));
+			exit(1);
+		}
+	} else {
+		zc.confmode = ZT_CONF_MONITORBOTH;
+		if (ioctl(pfd, ZT_SETCONF, &zc) < 0) {
+			fprintf(stderr, "Unable to monitor: %s\n", strerror(errno));
+			exit(1);
+		}
+	}
+	if (visual) {
+		printf("\nVisual Audio Levels.\n");
+		printf("--------------------\n");
+		printf(" Use zapata.conf file to adjust the gains if needed.\n\n");
+		printf("( # = Audio Level  * = Max Audio Hit )\n");
+		draw_barheader();
+	}
+	/* Now, copy from pseudo to audio */
+	for (;;) {
+		res = read(pfd, buf, sizeof(buf));
+		if (res < 1) 
+			break;
+		if (visual) {
+			res2 = read(pfd2, 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 */
+	exit(0);
+}

Propchange: uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: uClinux/trunk/uClinux-dist/user/busybox/miscutils/ztmonitor.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain



More information about the aadk-commits mailing list