[svn-commits] kpfleming: branch kpfleming/dtmf-twister r3485 - /team/kpfleming/dtmf-twister/
SVN commits to the Digium repositories
svn-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 svn-commits
mailing list