[zaptel-commits] kpfleming: branch kpfleming/dtmf-twister r3485 - /team/kpfleming/dtmf-twister/

SVN commits to the Zaptel project zaptel-commits at lists.digium.com
Fri Dec 14 14:44:34 CST 2007


Author: kpfleming
Date: Fri Dec 14 14:44:34 2007
New Revision: 3485

URL: http://svn.digium.com/view/zaptel?view=rev&rev=3485
Log:
generate DTMF and MF tones here and send them in to Zaptel

Modified:
    team/kpfleming/dtmf-twister/tonezone.c

Modified: team/kpfleming/dtmf-twister/tonezone.c
URL: http://svn.digium.com/view/zaptel/team/kpfleming/dtmf-twister/tonezone.c?view=diff&rev=3485&r1=3484&r2=3485
==============================================================================
--- team/kpfleming/dtmf-twister/tonezone.c (original)
+++ team/kpfleming/dtmf-twister/tonezone.c Fri Dec 14 14:44:34 2007
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
+
 #include "tonezone.h"
 
 #define DEFAULT_ZT_DEV "/dev/zap/ctl"
@@ -63,15 +64,15 @@
 
 #define LEVEL -10
 
-static int build_tone(char *data, int size, struct tone_zone_sound *t, int *count)
+static int build_tone(void *data, int size, struct tone_zone_sound *t, int *count)
 {
 	char *dup, *s;
 	struct zt_tone_def *td=NULL;
 	int firstnobang = -1;
 	int freq1, freq2, time;
-	int used = 0;
 	int modulate = 0;
 	float gain;
+	int used = 0;
 	dup = strdup(t->data);
 	s = strtok(dup, ",");
 	while(s && strlen(s)) {
@@ -125,11 +126,11 @@
 #if 0
 		printf("Using %d samples for %d and %d\n", time * 8, freq1, freq2);
 #endif
-		if (size < sizeof(struct zt_tone_def)) {
-			fprintf(stderr, "Not enough space for samples\n");
+		if (size < sizeof(*td)) {
+			fprintf(stderr, "Not enough space for tones\n");
 			return -1;
 		}
-		td = (struct zt_tone_def *)data;
+		td = data;
 
 		/* Bring it down -8 dbm */
 		gain = pow(10.0, (LEVEL - 3.14) / 20.0) * 65536.0 / 2.0;
@@ -144,9 +145,9 @@
 
 		td->modulate = modulate;
 
-		data += (sizeof(struct zt_tone_def));
-		used += (sizeof(struct zt_tone_def));
-		size -= (sizeof(struct zt_tone_def));
+		data += sizeof(*td);
+		used += sizeof(*td);
+		size -= sizeof(*td);
 		td->tone = t->toneid;
 		if (time) {
 			/* We should move to the next tone */
@@ -157,7 +158,7 @@
 			td->next = *count;
 			td->samples = 8000;
 		}
-		(*count)++;
+		*count += 1;
 		s = strtok(NULL, ",");
 	}
 	if (td && time) {
@@ -225,63 +226,161 @@
 }
 #endif
 
+/* Tone frequency tables */
+struct mf_tone {
+	int	tone;
+	float   f1;     /* first freq */
+	float   f2;     /* second freq */
+};
+ 
+static struct mf_tone dtmf_dial[] = {
+	{ ZT_TONE_DTMF_0, 941.0, 1336.0 },
+	{ ZT_TONE_DTMF_1, 697.0, 1209.0 },
+	{ ZT_TONE_DTMF_2, 697.0, 1336.0 },
+	{ ZT_TONE_DTMF_3, 697.0, 1477.0 },
+	{ ZT_TONE_DTMF_4, 770.0, 1209.0 },
+	{ ZT_TONE_DTMF_5, 770.0, 1336.0 },
+	{ ZT_TONE_DTMF_6, 770.0, 1477.0 },
+	{ ZT_TONE_DTMF_7, 852.0, 1209.0 },
+	{ ZT_TONE_DTMF_8, 852.0, 1336.0 },
+	{ ZT_TONE_DTMF_9, 852.0, 1477.0 },
+	{ ZT_TONE_DTMF_s, 941.0, 1209.0 },
+	{ ZT_TONE_DTMF_p, 941.0, 1477.0 },
+	{ ZT_TONE_DTMF_A, 697.0, 1633.0 },
+	{ ZT_TONE_DTMF_B, 770.0, 1633.0 },
+	{ ZT_TONE_DTMF_C, 852.0, 1633.0 },
+	{ ZT_TONE_DTMF_D, 941.0, 1633.0 },
+	{ 0, 0, 0 }
+};
+ 
+static struct mf_tone mf_dial[] = {
+	{ ZT_TONE_MF_0, 1300.0, 1500.0 },
+	{ ZT_TONE_MF_1, 700.0, 900.0 },
+	{ ZT_TONE_MF_2, 700.0, 1100.0 },
+	{ ZT_TONE_MF_3, 900.0, 1100.0 },
+	{ ZT_TONE_MF_4, 700.0, 1300.0 },
+	{ ZT_TONE_MF_5, 900.0, 1300.0 },
+	{ ZT_TONE_MF_6, 1100.0, 1300.0 },
+	{ ZT_TONE_MF_7, 700.0, 1500.0 },
+	{ ZT_TONE_MF_8, 900.0, 1500.0 },
+	{ ZT_TONE_MF_9, 1100.0, 1500.0 },
+	{ ZT_TONE_MF_s, 1100.0, 1700.0 },	/* KP */
+	{ ZT_TONE_MF_p, 1500.0, 1700.0 },	/* ST */
+	{ ZT_TONE_MF_A, 900.0, 1700.0 },	/* ST' */
+	{ ZT_TONE_MF_B, 1300.0, 1700.0 },	/* ST'' */
+	{ ZT_TONE_MF_C, 700.0, 1700.0 },	/* ST''' */
+	{ 0, 0, 0 }
+};
+
+static int build_mf_tones(void *data, int size, int *count, struct mf_tone *tone, int low_tone_level, int high_tone_level)
+{
+	struct zt_tone_def *td;
+	float gain;
+	int used = 0;
+
+	while (tone->tone) {
+		if (size < sizeof(*td)) {
+			fprintf(stderr, "Not enough space for samples\n");
+			return -1;
+		}
+		td = data;
+		data += sizeof(td);
+		used += sizeof(td);
+		size -= sizeof(td);
+		td->tone = tone->tone;
+		*count += 1;
+
+		/* Bring it down 6 dBm */
+		gain = pow(10.0, (low_tone_level - 3.14) / 20.0) * 65536.0 / 2.0;
+		td->fac1 = 2.0 * cos(2.0 * M_PI * (tone->f1 / 8000.0)) * 32768.0;
+		td->init_v2_1 = sin(-4.0 * M_PI * (tone->f1 / 8000.0)) * gain;
+		td->init_v3_1 = sin(-2.0 * M_PI * (tone->f1 / 8000.0)) * gain;
+		
+		gain = pow(10.0, (high_tone_level - 3.14) / 20.0) * 65536.0 / 2.0;
+		td->fac2 = 2.0 * cos(2.0 * M_PI * (tone->f2 / 8000.0)) * 32768.0;
+		td->init_v2_2 = sin(-4.0 * M_PI * (tone->f2 / 8000.0)) * gain;
+		td->init_v3_2 = sin(-2.0 * M_PI * (tone->f2 / 8000.0)) * gain;
+
+		tone++;
+	}
+
+	return used;
+}
+
 int tone_zone_register_zone(int fd, struct tone_zone *z)
 {
 	char buf[MAX_SIZE];
 	int res;
-	int count=0;
+	int count = 0;
 	int x;
-	int used = 0;
-	int iopenedit = 0;
 	int space = MAX_SIZE;
-	char *ptr = buf;
+	void *ptr = buf;
+	int iopenedit = 1;
 	struct zt_tone_def_header *h;
+
+	h = ptr;
+	ptr += sizeof(*h);
+	space -= sizeof(*h);
+	h->zone = z->zone;
+
+	strncpy(h->name, z->description, sizeof(h->name) - 1);
+
+	for (x = 0; x < ZT_MAX_CADENCE; x++) 
+		h->ringcadence[x] = z->ringcadence[x];
+
+	for (x = 0; x < ZT_TONE_MAX; x++) {
+		if (!strlen(z->tones[x].data))
+			continue;
+
+#if 0
+		printf("Tone: %d, string: %s\n", z->tones[x].toneid, z->tones[x].data);
+#endif			
+		if ((res = build_tone(ptr, space, &z->tones[x], &count)) < 0) {
+			fprintf(stderr, "Tone %d not built.\n", x);
+			return -1;
+		}
+		ptr += res;
+		space -= res;
+	}
+
+	h->count = count;
+
+	if ((res = build_mf_tones(ptr, space, &count, dtmf_dial, z->dtmf_low_level, z->dtmf_high_level)) < 0) {
+		fprintf(stderr, "Could not build DTMF tones.\n");
+		return -1;
+	}
+	ptr += res;
+	space -= res;
+
+	if ((res = build_mf_tones(ptr, space, &count, mf_dial, z->mf_level, z->mf_level)) < 0) {
+		fprintf(stderr, "Could not build MF tones.\n");
+		return -1;
+	}
+	ptr += res;
+	space -= res;
+
 	if (fd < 0) {
-		fd = open(DEFAULT_ZT_DEV, O_RDWR);
-		iopenedit=1;
-		if (fd < 0) {
+		if ((fd = open(DEFAULT_ZT_DEV, O_RDWR)) < 0) {
 			fprintf(stderr, "Unable to open %s and fd not provided\n", DEFAULT_ZT_DEV);
 			return -1;
 		}
-	}
-	h = (struct zt_tone_def_header *)ptr;
-	ptr += sizeof(struct zt_tone_def_header);
-	space -= sizeof(struct zt_tone_def_header);
-	used += sizeof(struct zt_tone_def_header);
-	/*
-	 * Fill in ring cadence 
-	 */
-	for (x=0;x<ZT_MAX_CADENCE;x++) 
-		h->ringcadence[x] = z->ringcadence[x];
-	/* Put in an appropriate method for a kernel ioctl */
-	for (x=0;x<ZT_TONE_MAX;x++) {
-		if (strlen(z->tones[x].data)) {
-			/* It's a real tone */
-#if 0
-			printf("Tone: %d, string: %s\n", z->tones[x].toneid, z->tones[x].data);
-#endif			
-			res = build_tone(ptr, space, &z->tones[x], &count);
-			if (res < 0) {
-				fprintf(stderr, "Tone not built.\n");
-				if (iopenedit)
-					close(fd);
-				return -1;
-			}
-			ptr += res;
-			used += res;
-			space -= res;
-		}
-	}
-	h->count = count;
-	h->zone = z->zone;
-	strncpy(h->name, z->description, sizeof(h->name));
+		iopenedit = 1;
+	}
+
 	x = z->zone;
-	ioctl(fd, ZT_FREEZONE, &x);
-	res = ioctl(fd, ZT_LOADZONE, h);
-	if (res) 
+	if ((res = ioctl(fd, ZT_FREEZONE, &x))) {
+		fprintf(stderr, "ioctl(ZT_FREEZONE) failed: %s\n", strerror(errno));
+		return res;
+	}
+
+	if ((res = ioctl(fd, ZT_LOADZONE, h))) {
 		fprintf(stderr, "ioctl(ZT_LOADZONE) failed: %s\n", strerror(errno));
+		return res;
+	}
+
 	if (iopenedit)
 		close(fd);
+
 	return res;
 }
 




More information about the zaptel-commits mailing list